From 0d474290009ef10c5d0e41c7a36eac1ed2aaa55f Mon Sep 17 00:00:00 2001 From: chrisp Date: Tue, 12 Jan 2021 16:47:20 +0000 Subject: [PATCH 1/2] New automount map management module. There is a new server management module placed in the plugins folder: plugins/modules/ipaautomountmap.py The server module allows to ensure presence and absence of automount maps. The module requires an existing automount location to place the map within. It does not create any automount keys with in the map. Here is the documentation for the module: README-automountmap.md New example playbooks have been added: playbooks/automount/automount-map-absent.yaml playbooks/automount/automount-map-present.yaml New tests for the module: tests/automount/test_automountmap.yml --- README-automountmap.md | 95 +++++++++ playbooks/automount/automount-map-absent.yaml | 12 ++ .../automount/automount-map-present.yaml | 12 ++ plugins/modules/ipaautomountmap.py | 184 ++++++++++++++++++ tests/automount/test_automountmap.yml | 135 +++++++++++++ 5 files changed, 438 insertions(+) create mode 100644 README-automountmap.md create mode 100644 playbooks/automount/automount-map-absent.yaml create mode 100644 playbooks/automount/automount-map-present.yaml create mode 100644 plugins/modules/ipaautomountmap.py create mode 100644 tests/automount/test_automountmap.yml diff --git a/README-automountmap.md b/README-automountmap.md new file mode 100644 index 00000000..0fdcede6 --- /dev/null +++ b/README-automountmap.md @@ -0,0 +1,95 @@ +Automountmap module +===================== + +Description +----------- + +The automountmap module allows the addition and removal of maps within automount locations. + +It is desgined to follow the IPA api as closely as possible while ensuring ease of use. + + +Features +-------- +* Automount map management + +Supported FreeIPA Versions +-------------------------- + +FreeIPA versions 4.4.0 and up are supported by the ipaautomountmap module. + +Requirements +------------ +**Controller** +* Ansible version: 2.8+ + +**Node** +* Supported FreeIPA version (see above) + + +Usage +===== + +Example inventory file + +```ini +[ipaserver] +ipaserver.test.local +``` + + +Example playbook to ensure presence of an automount map: + +```yaml +--- +- name: Playbook to add an automount map + hosts: ipaserver + become: true + + tasks: + - name: ensure map named auto.DMZ in location DMZ is created + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: auto.DMZ + location: DMZ + desc: "this is a map for servers in the DMZ" +``` + + +Example playbook to ensure auto.DMZi does not exist +```yaml +--- +- name: Playbook to remove an automount map + hosts: ipaserver + become: true + + tasks: + - name: ensure map auto.DMZ has been removed + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: auto.DMZ + location: DMX + state: absent +``` + + +Variables +========= + +ipaautomountmap +------- + +Variable | Description | Required +-------- | ----------- | -------- +`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no +`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no +`name` \| `mapname` \| `map` \| `automountmapname` | Name of the map to manage | yes +`location` \| `automountlocation` \| `automountlocationcn` | Location name. | yes +`desc` \| `description` | Description of the map | yes +`state` | The state to ensure. It can be one of `present`, or `absent`, default: `present`. | no + + +Authors +======= + +Chris Procter diff --git a/playbooks/automount/automount-map-absent.yaml b/playbooks/automount/automount-map-absent.yaml new file mode 100644 index 00000000..91c4b67e --- /dev/null +++ b/playbooks/automount/automount-map-absent.yaml @@ -0,0 +1,12 @@ +--- +- name: Automount map absent example + hosts: ipaserver + become: true + tasks: + - name: ensure map TestMap is absent + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + state: absent + diff --git a/playbooks/automount/automount-map-present.yaml b/playbooks/automount/automount-map-present.yaml new file mode 100644 index 00000000..3cc92ba3 --- /dev/null +++ b/playbooks/automount/automount-map-present.yaml @@ -0,0 +1,12 @@ +--- +- name: Automount map present example + hosts: ipaserver + become: true + tasks: + - name: ensure map TestMap is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a test map" + diff --git a/plugins/modules/ipaautomountmap.py b/plugins/modules/ipaautomountmap.py new file mode 100644 index 00000000..654986cc --- /dev/null +++ b/plugins/modules/ipaautomountmap.py @@ -0,0 +1,184 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Authors: +# Chris Procter +# +# Copyright (C) 2021 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +ANSIBLE_METADATA = { + "metadata_version": "1.0", + "supported_by": "community", + "status": ["preview"], +} + + +DOCUMENTATION = ''' +--- +module: ipaautomountmap +author: chris procter +short_description: Manage FreeIPA autommount map +description: +- Add, delete, and modify an IPA automount map +options: + ipaadmin_principal: + description: The admin principal + default: admin + ipaadmin_password: + description: The admin password + required: false + automountlocation: + description: automount location map is anchored to + choices: ["location", "automountlocationcn"] + required: True + name: + description: automount map to be managed + choices: ["mapname", "map", "automountmapname"] + required: True + desc: + description: description of automount map + choices: ["description"] + required: false + state: + description: State to ensure + required: false + default: present + choices: ["present", "absent"] +''' + +EXAMPLES = ''' + - name: ensure map named auto.DMZ in location DMZ is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: auto.DMZ + location: DMZ + desc: "this is a map for servers in the DMZ" + + - name: remove a map named auto.DMZ in location DMZ if it exists + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: auto.DMZ + location: DMZ + state: absent +''' + +RETURN = ''' +''' + +from ansible.module_utils.ansible_freeipa_module import FreeIPABaseModule + + +class AutomountMap(FreeIPABaseModule): + + ipa_param_mapping = { + "automountmapname": "name", + } + + def get_map(self, location, name): + response = dict() + try: + response = self.api_command("automountmap_show", + location, + {"automountmapname": name}) + except Exception: + pass + + return response.get("result", None) + + def check_ipa_params(self): + + if self.ipa_params.state == "present": + if len(self.ipa_params.name) != 1: + self.fail_json(msg="Exactly one name must be provided \ + for state=present.") + else: + if len(self.ipa_params.name) == 0 : + self.fail_json(msg="At least one name must be provided \ + when state=absent.") + + def define_ipa_commands(self): + args = self.get_ipa_command_args() + + if self.ipa_params.state == "present": + automountmap = self.get_map(self.ipa_params.location, + self.ipa_params.name[0]) + args['automountmapname'] = self.ipa_params.name[0] + if automountmap is None: + # does not exist and is wanted + self.add_ipa_command( + "automountmap_add", + name=self.ipa_params.location, + args=args + ) + else: + # exists and is wanted, check for changes + if self.ipa_params.desc != \ + automountmap.get('description', [None])[0]: + args['description'] = self.ipa_params.desc + self.add_ipa_command( + "automountmap_mod", + name=self.ipa_params.location, + args=args + ) + else: + # exists and is not wanted (i.e. self.ipa_params.state == "absent") + to_del = [x for x in self.ipa_params.name + if self.get_map(self.ipa_params.location, x) is not None] + + if len(to_del) > 0: + self.add_ipa_command( + "automountmap_del", + name=self.ipa_params.location, + args={"automountmapname": to_del} + ) + + +def main(): + ipa_module = AutomountMap( + argument_spec=dict( + ipaadmin_principal=dict(type="str", + default="admin" + ), + ipaadmin_password=dict(type="str", + required=False, + no_log=True + ), + state=dict(type='str', + default='present', + choices=['present', 'absent'] + ), + location=dict(type="str", + aliases=["automountlocation", "automountlocationcn"], + default=None, + required=True + ), + name=dict(type="list", + aliases=["mapname", "map", "automountmapname"], + default=None, + required=True + ), + desc=dict(type="str", + aliases=["description"], + required=False, + default=None + ), + ), + ) + ipa_module.ipa_run() + + +if __name__ == "__main__": + main() diff --git a/tests/automount/test_automountmap.yml b/tests/automount/test_automountmap.yml new file mode 100644 index 00000000..5c0b379c --- /dev/null +++ b/tests/automount/test_automountmap.yml @@ -0,0 +1,135 @@ +--- +- name: Test automountmap + hosts: ipaserver + become: true + gather_facts: false + + tasks: + - name: ensure location TestLocation is absent + ipaautomountlocation: + ipaadmin_password: SomeADMINpassword + name: TestLocation + state: absent + + - name: ensure map TestMap is absent + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + state: absent + + - name: ensure location TestLocation is present + ipaautomountlocation: + ipaadmin_password: SomeADMINpassword + name: TestLocation + state: present + + - name: ensure map TestMap is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a test map that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed + + - name: ensure map TestMap is present again + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + register: result + failed_when: result.failed or result.changed + + - name: ensure map TestMap has a different description + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed + + - name: ensure map TestMap has a different description + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or result.changed + + - name: ensure map TestMap is removed + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + state: absent + register: result + failed_when: result.failed or not result.changed + + - name: ensure map TestMap has been removed + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + state: absent + register: result + failed_when: result.failed or result.changed + + - name: ensure map TestMap01 is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap01 + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed + + - name: ensure map TestMap02 is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap02 + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed + + - name: ensure TestMap01 and TestMap02 are both absent + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: + - TestMap01 + - TestMap02 + location: TestLocation + state: absent + register: result + failed_when: result.failed or not result.changed + + - name: ensure TestMap01 and TestMap02 are both absent again + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: + - TestMap01 + - TestMap02 + location: TestLocation + state: absent + register: result + failed_when: result.failed or result.changed + + - name: ensure location TestLocation is absent + ipaautomountlocation: + ipaadmin_password: SomeADMINpassword + name: TestLocation + state: absent + register: result + failed_when: result.failed or not result.changed + + - name: ensure location TestLocation is absent again + ipaautomountlocation: + ipaadmin_password: SomeADMINpassword + name: TestLocation + state: absent + register: result + failed_when: result.failed or result.changed + From e1e8ff5916302fdfd14c8c801b380668960cba96 Mon Sep 17 00:00:00 2001 From: Rafael Guterres Jeffman Date: Wed, 5 Jan 2022 15:23:38 -0300 Subject: [PATCH 2/2] Adapt automount to IPAAnsibleModule and add code review modifications. --- README-automountmap.md | 19 +- playbooks/automount/automount-map-absent.yaml | 4 +- .../automount/automount-map-present.yaml | 4 +- plugins/modules/ipaautomountmap.py | 143 ++++++------ tests/automount/test_automountmap.yml | 212 +++++++++--------- 5 files changed, 203 insertions(+), 179 deletions(-) diff --git a/README-automountmap.md b/README-automountmap.md index 0fdcede6..208dd53d 100644 --- a/README-automountmap.md +++ b/README-automountmap.md @@ -4,7 +4,7 @@ Automountmap module Description ----------- -The automountmap module allows the addition and removal of maps within automount locations. +The automountmap module allows the addition and removal of maps within automount locations. It is desgined to follow the IPA api as closely as possible while ensuring ease of use. @@ -37,14 +37,13 @@ Example inventory file ipaserver.test.local ``` - Example playbook to ensure presence of an automount map: ```yaml --- - name: Playbook to add an automount map hosts: ipaserver - become: true + become: no tasks: - name: ensure map named auto.DMZ in location DMZ is created @@ -55,20 +54,20 @@ Example playbook to ensure presence of an automount map: desc: "this is a map for servers in the DMZ" ``` +Example playbook to ensure auto.DMZi is absent: -Example playbook to ensure auto.DMZi does not exist ```yaml --- - name: Playbook to remove an automount map hosts: ipaserver - become: true + become: no tasks: - name: ensure map auto.DMZ has been removed ipaautomountmap: ipaadmin_password: SomeADMINpassword name: auto.DMZ - location: DMX + location: DMZ state: absent ``` @@ -76,9 +75,6 @@ Example playbook to ensure auto.DMZi does not exist Variables ========= -ipaautomountmap -------- - Variable | Description | Required -------- | ----------- | -------- `ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no @@ -89,6 +85,11 @@ Variable | Description | Required `state` | The state to ensure. It can be one of `present`, or `absent`, default: `present`. | no +Notes +===== + +Creation of indirect mount points are not supported. + Authors ======= diff --git a/playbooks/automount/automount-map-absent.yaml b/playbooks/automount/automount-map-absent.yaml index 91c4b67e..344fb205 100644 --- a/playbooks/automount/automount-map-absent.yaml +++ b/playbooks/automount/automount-map-absent.yaml @@ -1,7 +1,8 @@ --- - name: Automount map absent example hosts: ipaserver - become: true + become: no + tasks: - name: ensure map TestMap is absent ipaautomountmap: @@ -9,4 +10,3 @@ name: TestMap location: TestLocation state: absent - diff --git a/playbooks/automount/automount-map-present.yaml b/playbooks/automount/automount-map-present.yaml index 3cc92ba3..88f4bb7b 100644 --- a/playbooks/automount/automount-map-present.yaml +++ b/playbooks/automount/automount-map-present.yaml @@ -1,7 +1,8 @@ --- - name: Automount map present example hosts: ipaserver - become: true + become: no + tasks: - name: ensure map TestMap is present ipaautomountmap: @@ -9,4 +10,3 @@ name: TestMap location: TestLocation desc: "this is a test map" - diff --git a/plugins/modules/ipaautomountmap.py b/plugins/modules/ipaautomountmap.py index 654986cc..72084396 100644 --- a/plugins/modules/ipaautomountmap.py +++ b/plugins/modules/ipaautomountmap.py @@ -19,6 +19,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +from __future__ import (absolute_import, division, print_function) + +__metaclass__ = type + ANSIBLE_METADATA = { "metadata_version": "1.0", "supported_by": "community", @@ -29,27 +33,27 @@ ANSIBLE_METADATA = { DOCUMENTATION = ''' --- module: ipaautomountmap -author: chris procter +author: Chris Procter short_description: Manage FreeIPA autommount map description: - Add, delete, and modify an IPA automount map options: ipaadmin_principal: - description: The admin principal + description: The admin principal. default: admin ipaadmin_password: - description: The admin password + description: The admin password. required: false automountlocation: description: automount location map is anchored to choices: ["location", "automountlocationcn"] required: True name: - description: automount map to be managed + description: automount map to be managed. choices: ["mapname", "map", "automountmapname"] required: True desc: - description: description of automount map + description: description of automount map. choices: ["description"] required: false state: @@ -78,84 +82,85 @@ EXAMPLES = ''' RETURN = ''' ''' -from ansible.module_utils.ansible_freeipa_module import FreeIPABaseModule +from ansible.module_utils.ansible_freeipa_module import ( + IPAAnsibleModule, compare_args_ipa +) -class AutomountMap(FreeIPABaseModule): +class AutomountMap(IPAAnsibleModule): - ipa_param_mapping = { - "automountmapname": "name", - } + def __init__(self, *args, **kwargs): + # pylint: disable=super-with-arguments + super(AutomountMap, self).__init__(*args, **kwargs) + self.commands = [] - def get_map(self, location, name): - response = dict() + def get_automountmap(self, location, name): try: - response = self.api_command("automountmap_show", - location, - {"automountmapname": name}) - except Exception: - pass - - return response.get("result", None) + response = self.ipa_command( + "automountmap_show", + location, + {"automountmapname": name, "all": True} + ) + except Exception: # pylint: disable=broad-except + return None + else: + return response["result"] def check_ipa_params(self): - - if self.ipa_params.state == "present": - if len(self.ipa_params.name) != 1: + invalid = [] + name = self.params_get("name") + state = self.params_get("state") + if state == "present": + if len(name) != 1: self.fail_json(msg="Exactly one name must be provided \ for state=present.") - else: - if len(self.ipa_params.name) == 0 : - self.fail_json(msg="At least one name must be provided \ - when state=absent.") + if state == "absent": + if len(name) == 0 : + self.fail_json(msg="Argument 'map_type' can not be used with " + "state 'absent'") + invalid = ["desc"] + + self.params_fail_used_invalid(invalid, state) + + def get_args(self, mapname, desc): # pylint: disable=no-self-use + _args = {} + if mapname: + _args["automountmapname"] = mapname + if desc: + _args["description"] = desc + return _args def define_ipa_commands(self): - args = self.get_ipa_command_args() + name = self.params_get("name") + state = self.params_get("state") + location = self.params_get("location") + desc = self.params_get("desc") - if self.ipa_params.state == "present": - automountmap = self.get_map(self.ipa_params.location, - self.ipa_params.name[0]) - args['automountmapname'] = self.ipa_params.name[0] - if automountmap is None: - # does not exist and is wanted - self.add_ipa_command( - "automountmap_add", - name=self.ipa_params.location, - args=args - ) - else: - # exists and is wanted, check for changes - if self.ipa_params.desc != \ - automountmap.get('description', [None])[0]: - args['description'] = self.ipa_params.desc - self.add_ipa_command( - "automountmap_mod", - name=self.ipa_params.location, - args=args - ) - else: - # exists and is not wanted (i.e. self.ipa_params.state == "absent") - to_del = [x for x in self.ipa_params.name - if self.get_map(self.ipa_params.location, x) is not None] + for mapname in name: + automountmap = self.get_automountmap(location, mapname) - if len(to_del) > 0: - self.add_ipa_command( - "automountmap_del", - name=self.ipa_params.location, - args={"automountmapname": to_del} - ) + if state == "present": + args = self.get_args(mapname, desc) + if automountmap is None: + self.commands.append([location, "automountmap_add", args]) + else: + if not compare_args_ipa(self, args, automountmap): + self.commands.append( + [location, "automountmap_mod", args] + ) + + if state == "absent": + if automountmap is not None: + self.commands.append([ + location, + "automountmap_del", + {"automountmapname": [mapname]} + ]) def main(): ipa_module = AutomountMap( argument_spec=dict( - ipaadmin_principal=dict(type="str", - default="admin" - ), - ipaadmin_password=dict(type="str", - required=False, - no_log=True - ), state=dict(type='str', default='present', choices=['present', 'absent'] @@ -177,7 +182,13 @@ def main(): ), ), ) - ipa_module.ipa_run() + changed = False + ipaapi_context = ipa_module.params_get("ipaapi_context") + with ipa_module.ipa_connect(context=ipaapi_context): + ipa_module.check_ipa_params() + ipa_module.define_ipa_commands() + changed = ipa_module.execute_ipa_commands(ipa_module.commands) + ipa_module.exit_json(changed=changed) if __name__ == "__main__": diff --git a/tests/automount/test_automountmap.yml b/tests/automount/test_automountmap.yml index 5c0b379c..cbf5db40 100644 --- a/tests/automount/test_automountmap.yml +++ b/tests/automount/test_automountmap.yml @@ -1,10 +1,20 @@ --- - name: Test automountmap hosts: ipaserver - become: true - gather_facts: false + become: no + gather_facts: no tasks: + # setup environment + - name: ensure test maps are absent + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: + - TestMap01 + - TestMap02 + location: TestLocation + state: absent + - name: ensure location TestLocation is absent ipaautomountlocation: ipaadmin_password: SomeADMINpassword @@ -24,112 +34,114 @@ name: TestLocation state: present - - name: ensure map TestMap is present - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap - location: TestLocation - desc: "this is a test map that should be deleted by the test" - register: result - failed_when: result.failed or not result.changed + # TESTS + - block: + - name: ensure map TestMap is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a test map that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed - - name: ensure map TestMap is present again - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap - location: TestLocation - register: result - failed_when: result.failed or result.changed + - name: ensure map TestMap is present again + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + register: result + failed_when: result.failed or result.changed - - name: ensure map TestMap has a different description - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap - location: TestLocation - desc: "this is a changed description that should be deleted by the test" - register: result - failed_when: result.failed or not result.changed + - name: ensure map TestMap has a different description + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed - - name: ensure map TestMap has a different description - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap - location: TestLocation - desc: "this is a changed description that should be deleted by the test" - register: result - failed_when: result.failed or result.changed + - name: ensure map TestMap has a different description, again + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or result.changed - - name: ensure map TestMap is removed - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap - location: TestLocation - state: absent - register: result - failed_when: result.failed or not result.changed + - name: ensure map TestMap is removed + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + state: absent + register: result + failed_when: result.failed or not result.changed - - name: ensure map TestMap has been removed - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap - location: TestLocation - state: absent - register: result - failed_when: result.failed or result.changed + - name: ensure map TestMap has been removed + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap + location: TestLocation + state: absent + register: result + failed_when: result.failed or result.changed - - name: ensure map TestMap01 is present - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap01 - location: TestLocation - desc: "this is a changed description that should be deleted by the test" - register: result - failed_when: result.failed or not result.changed + - name: ensure map TestMap01 is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap01 + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed - - name: ensure map TestMap02 is present - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: TestMap02 - location: TestLocation - desc: "this is a changed description that should be deleted by the test" - register: result - failed_when: result.failed or not result.changed + - name: ensure map TestMap02 is present + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: TestMap02 + location: TestLocation + desc: "this is a changed description that should be deleted by the test" + register: result + failed_when: result.failed or not result.changed - - name: ensure TestMap01 and TestMap02 are both absent - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: - - TestMap01 - - TestMap02 - location: TestLocation - state: absent - register: result - failed_when: result.failed or not result.changed + - name: ensure TestMap01 and TestMap02 are both absent + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: + - TestMap01 + - TestMap02 + location: TestLocation + state: absent + register: result + failed_when: result.failed or not result.changed - - name: ensure TestMap01 and TestMap02 are both absent again - ipaautomountmap: - ipaadmin_password: SomeADMINpassword - name: - - TestMap01 - - TestMap02 - location: TestLocation - state: absent - register: result - failed_when: result.failed or result.changed + - name: ensure TestMap01 and TestMap02 are both absent again + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: + - TestMap01 + - TestMap02 + location: TestLocation + state: absent + register: result + failed_when: result.failed or result.changed - - name: ensure location TestLocation is absent - ipaautomountlocation: - ipaadmin_password: SomeADMINpassword - name: TestLocation - state: absent - register: result - failed_when: result.failed or not result.changed - - - name: ensure location TestLocation is absent again - ipaautomountlocation: - ipaadmin_password: SomeADMINpassword - name: TestLocation - state: absent - register: result - failed_when: result.failed or result.changed + # CLEAN UP + always: + - name: ensure test maps are absent + ipaautomountmap: + ipaadmin_password: SomeADMINpassword + name: + - TestMap01 + - TestMap02 + location: TestLocation + state: absent + - name: ensure location TestLocation is absent + ipaautomountlocation: + ipaadmin_password: SomeADMINpassword + name: TestLocation + state: absent