mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-07-25 00:44:42 +00:00
Adapt automount to IPAAnsibleModule and add code review modifications.
This commit is contained in:
@@ -4,7 +4,7 @@ Automountmap module
|
|||||||
Description
|
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.
|
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
|
ipaserver.test.local
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Example playbook to ensure presence of an automount map:
|
Example playbook to ensure presence of an automount map:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
---
|
---
|
||||||
- name: Playbook to add an automount map
|
- name: Playbook to add an automount map
|
||||||
hosts: ipaserver
|
hosts: ipaserver
|
||||||
become: true
|
become: no
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: ensure map named auto.DMZ in location DMZ is created
|
- 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"
|
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
|
```yaml
|
||||||
---
|
---
|
||||||
- name: Playbook to remove an automount map
|
- name: Playbook to remove an automount map
|
||||||
hosts: ipaserver
|
hosts: ipaserver
|
||||||
become: true
|
become: no
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: ensure map auto.DMZ has been removed
|
- name: ensure map auto.DMZ has been removed
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: auto.DMZ
|
name: auto.DMZ
|
||||||
location: DMX
|
location: DMZ
|
||||||
state: absent
|
state: absent
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -76,9 +75,6 @@ Example playbook to ensure auto.DMZi does not exist
|
|||||||
Variables
|
Variables
|
||||||
=========
|
=========
|
||||||
|
|
||||||
ipaautomountmap
|
|
||||||
-------
|
|
||||||
|
|
||||||
Variable | Description | Required
|
Variable | Description | Required
|
||||||
-------- | ----------- | --------
|
-------- | ----------- | --------
|
||||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
`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
|
`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
|
Authors
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Automount map absent example
|
- name: Automount map absent example
|
||||||
hosts: ipaserver
|
hosts: ipaserver
|
||||||
become: true
|
become: no
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: ensure map TestMap is absent
|
- name: ensure map TestMap is absent
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
@@ -9,4 +10,3 @@
|
|||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Automount map present example
|
- name: Automount map present example
|
||||||
hosts: ipaserver
|
hosts: ipaserver
|
||||||
become: true
|
become: no
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: ensure map TestMap is present
|
- name: ensure map TestMap is present
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
@@ -9,4 +10,3 @@
|
|||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
desc: "this is a test map"
|
desc: "this is a test map"
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
ANSIBLE_METADATA = {
|
ANSIBLE_METADATA = {
|
||||||
"metadata_version": "1.0",
|
"metadata_version": "1.0",
|
||||||
"supported_by": "community",
|
"supported_by": "community",
|
||||||
@@ -29,27 +33,27 @@ ANSIBLE_METADATA = {
|
|||||||
DOCUMENTATION = '''
|
DOCUMENTATION = '''
|
||||||
---
|
---
|
||||||
module: ipaautomountmap
|
module: ipaautomountmap
|
||||||
author: chris procter
|
author: Chris Procter
|
||||||
short_description: Manage FreeIPA autommount map
|
short_description: Manage FreeIPA autommount map
|
||||||
description:
|
description:
|
||||||
- Add, delete, and modify an IPA automount map
|
- Add, delete, and modify an IPA automount map
|
||||||
options:
|
options:
|
||||||
ipaadmin_principal:
|
ipaadmin_principal:
|
||||||
description: The admin principal
|
description: The admin principal.
|
||||||
default: admin
|
default: admin
|
||||||
ipaadmin_password:
|
ipaadmin_password:
|
||||||
description: The admin password
|
description: The admin password.
|
||||||
required: false
|
required: false
|
||||||
automountlocation:
|
automountlocation:
|
||||||
description: automount location map is anchored to
|
description: automount location map is anchored to
|
||||||
choices: ["location", "automountlocationcn"]
|
choices: ["location", "automountlocationcn"]
|
||||||
required: True
|
required: True
|
||||||
name:
|
name:
|
||||||
description: automount map to be managed
|
description: automount map to be managed.
|
||||||
choices: ["mapname", "map", "automountmapname"]
|
choices: ["mapname", "map", "automountmapname"]
|
||||||
required: True
|
required: True
|
||||||
desc:
|
desc:
|
||||||
description: description of automount map
|
description: description of automount map.
|
||||||
choices: ["description"]
|
choices: ["description"]
|
||||||
required: false
|
required: false
|
||||||
state:
|
state:
|
||||||
@@ -78,84 +82,85 @@ EXAMPLES = '''
|
|||||||
RETURN = '''
|
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 = {
|
def __init__(self, *args, **kwargs):
|
||||||
"automountmapname": "name",
|
# pylint: disable=super-with-arguments
|
||||||
}
|
super(AutomountMap, self).__init__(*args, **kwargs)
|
||||||
|
self.commands = []
|
||||||
|
|
||||||
def get_map(self, location, name):
|
def get_automountmap(self, location, name):
|
||||||
response = dict()
|
|
||||||
try:
|
try:
|
||||||
response = self.api_command("automountmap_show",
|
response = self.ipa_command(
|
||||||
location,
|
"automountmap_show",
|
||||||
{"automountmapname": name})
|
location,
|
||||||
except Exception:
|
{"automountmapname": name, "all": True}
|
||||||
pass
|
)
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
return response.get("result", None)
|
return None
|
||||||
|
else:
|
||||||
|
return response["result"]
|
||||||
|
|
||||||
def check_ipa_params(self):
|
def check_ipa_params(self):
|
||||||
|
invalid = []
|
||||||
if self.ipa_params.state == "present":
|
name = self.params_get("name")
|
||||||
if len(self.ipa_params.name) != 1:
|
state = self.params_get("state")
|
||||||
|
if state == "present":
|
||||||
|
if len(name) != 1:
|
||||||
self.fail_json(msg="Exactly one name must be provided \
|
self.fail_json(msg="Exactly one name must be provided \
|
||||||
for state=present.")
|
for state=present.")
|
||||||
else:
|
if state == "absent":
|
||||||
if len(self.ipa_params.name) == 0 :
|
if len(name) == 0 :
|
||||||
self.fail_json(msg="At least one name must be provided \
|
self.fail_json(msg="Argument 'map_type' can not be used with "
|
||||||
when state=absent.")
|
"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):
|
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":
|
for mapname in name:
|
||||||
automountmap = self.get_map(self.ipa_params.location,
|
automountmap = self.get_automountmap(location, mapname)
|
||||||
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:
|
if state == "present":
|
||||||
self.add_ipa_command(
|
args = self.get_args(mapname, desc)
|
||||||
"automountmap_del",
|
if automountmap is None:
|
||||||
name=self.ipa_params.location,
|
self.commands.append([location, "automountmap_add", args])
|
||||||
args={"automountmapname": to_del}
|
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():
|
def main():
|
||||||
ipa_module = AutomountMap(
|
ipa_module = AutomountMap(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
ipaadmin_principal=dict(type="str",
|
|
||||||
default="admin"
|
|
||||||
),
|
|
||||||
ipaadmin_password=dict(type="str",
|
|
||||||
required=False,
|
|
||||||
no_log=True
|
|
||||||
),
|
|
||||||
state=dict(type='str',
|
state=dict(type='str',
|
||||||
default='present',
|
default='present',
|
||||||
choices=['present', 'absent']
|
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__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
---
|
---
|
||||||
- name: Test automountmap
|
- name: Test automountmap
|
||||||
hosts: ipaserver
|
hosts: ipaserver
|
||||||
become: true
|
become: no
|
||||||
gather_facts: false
|
gather_facts: no
|
||||||
|
|
||||||
tasks:
|
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
|
- name: ensure location TestLocation is absent
|
||||||
ipaautomountlocation:
|
ipaautomountlocation:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
@@ -24,112 +34,114 @@
|
|||||||
name: TestLocation
|
name: TestLocation
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: ensure map TestMap is present
|
# TESTS
|
||||||
ipaautomountmap:
|
- block:
|
||||||
ipaadmin_password: SomeADMINpassword
|
- name: ensure map TestMap is present
|
||||||
name: TestMap
|
ipaautomountmap:
|
||||||
location: TestLocation
|
ipaadmin_password: SomeADMINpassword
|
||||||
desc: "this is a test map that should be deleted by the test"
|
name: TestMap
|
||||||
register: result
|
location: TestLocation
|
||||||
failed_when: result.failed or not result.changed
|
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
|
- name: ensure map TestMap is present again
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or result.changed
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
- name: ensure map TestMap has a different description
|
- name: ensure map TestMap has a different description
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
desc: "this is a changed description that should be deleted by the test"
|
desc: "this is a changed description that should be deleted by the test"
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or not result.changed
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
- name: ensure map TestMap has a different description
|
- name: ensure map TestMap has a different description, again
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
desc: "this is a changed description that should be deleted by the test"
|
desc: "this is a changed description that should be deleted by the test"
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or result.changed
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
- name: ensure map TestMap is removed
|
- name: ensure map TestMap is removed
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or not result.changed
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
- name: ensure map TestMap has been removed
|
- name: ensure map TestMap has been removed
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap
|
name: TestMap
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or result.changed
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
- name: ensure map TestMap01 is present
|
- name: ensure map TestMap01 is present
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap01
|
name: TestMap01
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
desc: "this is a changed description that should be deleted by the test"
|
desc: "this is a changed description that should be deleted by the test"
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or not result.changed
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
- name: ensure map TestMap02 is present
|
- name: ensure map TestMap02 is present
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: TestMap02
|
name: TestMap02
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
desc: "this is a changed description that should be deleted by the test"
|
desc: "this is a changed description that should be deleted by the test"
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or not result.changed
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
- name: ensure TestMap01 and TestMap02 are both absent
|
- name: ensure TestMap01 and TestMap02 are both absent
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name:
|
name:
|
||||||
- TestMap01
|
- TestMap01
|
||||||
- TestMap02
|
- TestMap02
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or not result.changed
|
failed_when: result.failed or not result.changed
|
||||||
|
|
||||||
- name: ensure TestMap01 and TestMap02 are both absent again
|
- name: ensure TestMap01 and TestMap02 are both absent again
|
||||||
ipaautomountmap:
|
ipaautomountmap:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name:
|
name:
|
||||||
- TestMap01
|
- TestMap01
|
||||||
- TestMap02
|
- TestMap02
|
||||||
location: TestLocation
|
location: TestLocation
|
||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
failed_when: result.failed or result.changed
|
failed_when: result.failed or result.changed
|
||||||
|
|
||||||
- name: ensure location TestLocation is absent
|
# CLEAN UP
|
||||||
ipaautomountlocation:
|
always:
|
||||||
ipaadmin_password: SomeADMINpassword
|
- name: ensure test maps are absent
|
||||||
name: TestLocation
|
ipaautomountmap:
|
||||||
state: absent
|
ipaadmin_password: SomeADMINpassword
|
||||||
register: result
|
name:
|
||||||
failed_when: result.failed or not result.changed
|
- TestMap01
|
||||||
|
- TestMap02
|
||||||
- name: ensure location TestLocation is absent again
|
location: TestLocation
|
||||||
ipaautomountlocation:
|
state: absent
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: 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
|
||||||
|
|||||||
Reference in New Issue
Block a user