Fix junos_user purge option failures (#28867)
* Fix junos_user pruge option failures Fixes #25989 Add seperate handling for purge option which fetches configured users on remote device and delete the one not present in aggregate list. * Minor changes
This commit is contained in:
parent
effa5085ca
commit
a6af204cee
3 changed files with 66 additions and 16 deletions
|
@ -211,7 +211,13 @@ def load_config(module, candidate, warnings, action='merge', format='xml'):
|
||||||
|
|
||||||
|
|
||||||
def get_param(module, key):
|
def get_param(module, key):
|
||||||
return module.params[key] or module.params['provider'].get(key)
|
if module.params.get(key):
|
||||||
|
value = module.params[key]
|
||||||
|
elif module.params.get('provider'):
|
||||||
|
value = module.params['provider'].get(key)
|
||||||
|
else:
|
||||||
|
value = None
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
def map_params_to_obj(module, param_to_xpath_map, param=None):
|
def map_params_to_obj(module, param_to_xpath_map, param=None):
|
||||||
|
|
|
@ -57,7 +57,6 @@ options:
|
||||||
remote system. User accounts can have more than one role
|
remote system. User accounts can have more than one role
|
||||||
configured.
|
configured.
|
||||||
required: false
|
required: false
|
||||||
default: read-only
|
|
||||||
choices: ['operator', 'read-only', 'super-user', 'unauthorized']
|
choices: ['operator', 'read-only', 'super-user', 'unauthorized']
|
||||||
sshkey:
|
sshkey:
|
||||||
description:
|
description:
|
||||||
|
@ -71,7 +70,7 @@ options:
|
||||||
- The C(purge) argument instructs the module to consider the
|
- The C(purge) argument instructs the module to consider the
|
||||||
users definition absolute. It will remove any previously configured
|
users definition absolute. It will remove any previously configured
|
||||||
users on the device with the exception of the current defined
|
users on the device with the exception of the current defined
|
||||||
set of users.
|
set of aggregate.
|
||||||
required: false
|
required: false
|
||||||
default: false
|
default: false
|
||||||
state:
|
state:
|
||||||
|
@ -113,7 +112,8 @@ EXAMPLES = """
|
||||||
|
|
||||||
- name: remove all user accounts except ansible
|
- name: remove all user accounts except ansible
|
||||||
junos_user:
|
junos_user:
|
||||||
name: ansible
|
aggregate:
|
||||||
|
- name: ansible
|
||||||
purge: yes
|
purge: yes
|
||||||
|
|
||||||
- name: Create list of users
|
- name: Create list of users
|
||||||
|
@ -147,6 +147,7 @@ from copy import deepcopy
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.network_common import remove_default_spec
|
from ansible.module_utils.network_common import remove_default_spec
|
||||||
|
from ansible.module_utils.netconf import send_request
|
||||||
from ansible.module_utils.junos import junos_argument_spec, check_args
|
from ansible.module_utils.junos import junos_argument_spec, check_args
|
||||||
from ansible.module_utils.junos import commit_configuration, discard_changes
|
from ansible.module_utils.junos import commit_configuration, discard_changes
|
||||||
from ansible.module_utils.junos import load_config, locked_config
|
from ansible.module_utils.junos import load_config, locked_config
|
||||||
|
@ -161,27 +162,47 @@ ROLES = ['operator', 'read-only', 'super-user', 'unauthorized']
|
||||||
USE_PERSISTENT_CONNECTION = True
|
USE_PERSISTENT_CONNECTION = True
|
||||||
|
|
||||||
|
|
||||||
def map_obj_to_ele(want):
|
def handle_purge(module, want):
|
||||||
|
want_users = [item['name'] for item in want]
|
||||||
element = Element('system')
|
element = Element('system')
|
||||||
login = SubElement(element, 'login', {'replace': 'replace'})
|
login = SubElement(element, 'login')
|
||||||
|
|
||||||
|
reply = send_request(module, Element('get-configuration'), ignore_warning=False)
|
||||||
|
users = reply.xpath('configuration/system/login/user/name')
|
||||||
|
if users:
|
||||||
|
for item in users:
|
||||||
|
name = item.text
|
||||||
|
if name not in want_users and name != 'root':
|
||||||
|
user = SubElement(login, 'user', {'operation': 'delete'})
|
||||||
|
SubElement(user, 'name').text = name
|
||||||
|
if element.xpath('/system/login/user/name'):
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def map_obj_to_ele(module, want):
|
||||||
|
element = Element('system')
|
||||||
|
login = SubElement(element, 'login')
|
||||||
|
|
||||||
for item in want:
|
for item in want:
|
||||||
if item['state'] != 'present':
|
if item['state'] != 'present':
|
||||||
|
if item['name'] == 'root':
|
||||||
|
module.fail_json(msg="cannot delete the 'root' account.")
|
||||||
operation = 'delete'
|
operation = 'delete'
|
||||||
else:
|
else:
|
||||||
operation = 'replace'
|
operation = 'merge'
|
||||||
|
|
||||||
user = SubElement(login, 'user', {'operation': operation})
|
user = SubElement(login, 'user', {'operation': operation})
|
||||||
|
|
||||||
SubElement(user, 'name').text = item['name']
|
SubElement(user, 'name').text = item['name']
|
||||||
|
|
||||||
if operation == 'replace':
|
if operation == 'merge':
|
||||||
if item['active']:
|
if item['active']:
|
||||||
user.set('active', 'active')
|
user.set('active', 'active')
|
||||||
else:
|
else:
|
||||||
user.set('inactive', 'inactive')
|
user.set('inactive', 'inactive')
|
||||||
|
|
||||||
SubElement(user, 'class').text = item['role']
|
if item['role']:
|
||||||
|
SubElement(user, 'class').text = item['role']
|
||||||
|
|
||||||
if item.get('full_name'):
|
if item.get('full_name'):
|
||||||
SubElement(user, 'full-name').text = item['full_name']
|
SubElement(user, 'full-name').text = item['full_name']
|
||||||
|
@ -262,7 +283,7 @@ def main():
|
||||||
element_spec = dict(
|
element_spec = dict(
|
||||||
name=dict(),
|
name=dict(),
|
||||||
full_name=dict(),
|
full_name=dict(),
|
||||||
role=dict(choices=ROLES, default='unauthorized'),
|
role=dict(choices=ROLES),
|
||||||
sshkey=dict(),
|
sshkey=dict(),
|
||||||
state=dict(choices=['present', 'absent'], default='present'),
|
state=dict(choices=['present', 'absent'], default='present'),
|
||||||
active=dict(type='bool', default=True)
|
active=dict(type='bool', default=True)
|
||||||
|
@ -294,16 +315,16 @@ def main():
|
||||||
result = {'changed': False, 'warnings': warnings}
|
result = {'changed': False, 'warnings': warnings}
|
||||||
|
|
||||||
want = map_params_to_obj(module)
|
want = map_params_to_obj(module)
|
||||||
ele = map_obj_to_ele(want)
|
ele = map_obj_to_ele(module, want)
|
||||||
|
|
||||||
kwargs = {}
|
purge_request = None
|
||||||
if module.params['purge']:
|
if module.params['purge']:
|
||||||
kwargs['action'] = 'replace'
|
purge_request = handle_purge(module, want)
|
||||||
else:
|
|
||||||
kwargs['action'] = 'merge'
|
|
||||||
|
|
||||||
with locked_config(module):
|
with locked_config(module):
|
||||||
diff = load_config(module, tostring(ele), warnings, **kwargs)
|
if purge_request:
|
||||||
|
load_config(module, tostring(purge_request), warnings, action='replace')
|
||||||
|
diff = load_config(module, tostring(ele), warnings, action='merge')
|
||||||
|
|
||||||
commit = not module.check_mode
|
commit = not module.check_mode
|
||||||
if diff:
|
if diff:
|
||||||
|
|
|
@ -168,3 +168,26 @@
|
||||||
- "result.changed == true"
|
- "result.changed == true"
|
||||||
- "'<name>test_user1</name>' not in config.xml"
|
- "'<name>test_user1</name>' not in config.xml"
|
||||||
- "'<name>test_user2</name>' not in config.xml"
|
- "'<name>test_user2</name>' not in config.xml"
|
||||||
|
|
||||||
|
- name: Create list of users
|
||||||
|
junos_user:
|
||||||
|
aggregate:
|
||||||
|
- name: ansible
|
||||||
|
- {name: test_user1, full_name: test_user2, role: operator}
|
||||||
|
- {name: test_user2, full_name: test_user2, role: read-only}
|
||||||
|
provider: "{{ netconf }}"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- name: Purge users except the users in aggregate
|
||||||
|
junos_user:
|
||||||
|
aggregate:
|
||||||
|
- name: ansible
|
||||||
|
purge: True
|
||||||
|
provider: "{{ netconf }}"
|
||||||
|
register: result
|
||||||
|
|
||||||
|
- assert:
|
||||||
|
that:
|
||||||
|
- "result.changed == true"
|
||||||
|
- result.diff.prepared | search("\- *user test_user1")
|
||||||
|
- result.diff.prepared | search("\- *user test_user2")
|
||||||
|
|
Loading…
Add table
Reference in a new issue