fix nxos_snmp_user issues (#39760)

* fix nxos_snmp_user issues

* shipppable fix
This commit is contained in:
saichint 2018-05-07 23:27:12 -07:00 committed by Trishna Guha
parent 58f9676d4b
commit e3bfbe5875
2 changed files with 138 additions and 54 deletions

View file

@ -42,7 +42,15 @@ options:
group: group:
description: description:
- Group to which the user will belong to. - Group to which the user will belong to.
required: true If state = present, and the user is existing,
the group is added to the user. If the user
is not existing, user entry is created with this
group argument.
If state = absent, only the group is removed from the
user entry. However, to maintain backward compatibility,
if the existing user belongs to only one group, and if
group argument is same as the existing user's group,
then the user entry also is deleted.
authentication: authentication:
description: description:
- Authentication parameters for the user. - Authentication parameters for the user.
@ -50,9 +58,11 @@ options:
pwd: pwd:
description: description:
- Authentication password when using md5 or sha. - Authentication password when using md5 or sha.
This is not idempotent
privacy: privacy:
description: description:
- Privacy password for the user. - Privacy password for the user.
This is not idempotent
encrypt: encrypt:
description: description:
- Enables AES-128 bit encryption when using privacy password. - Enables AES-128 bit encryption when using privacy password.
@ -148,8 +158,18 @@ def get_snmp_user(user, module):
privkey = 'priv' privkey = 'priv'
grpkey = 'group' grpkey = 'group'
resource_table = body[0][tablekey][rowkey] rt = body[0][tablekey][rowkey]
resource['user'] = str(resource_table['user']) # on some older platforms, all groups except the 1st one
# are in list elements by themselves and they are
# indexed by 'user'. This is due to a platform bug.
# Get first element if rt is a list due to the bug
# or if there is no bug, parse rt directly
if isinstance(rt, list):
resource_table = rt[0]
else:
resource_table = rt
resource['user'] = user
resource['authentication'] = str(resource_table[authkey]).strip() resource['authentication'] = str(resource_table[authkey]).strip()
encrypt = str(resource_table[privkey]).strip() encrypt = str(resource_table[privkey]).strip()
if encrypt.startswith('aes'): if encrypt.startswith('aes'):
@ -166,6 +186,15 @@ def get_snmp_user(user, module):
except TypeError: except TypeError:
groups.append(str(group_table[grpkey]).strip()) groups.append(str(group_table[grpkey]).strip())
# Now for the platform bug case, get the groups
if isinstance(rt, list):
# remove 1st element from the list as this is parsed already
rt.pop(0)
# iterate through other elements indexed by
# 'user' and add it to groups.
for each in rt:
groups.append(each['user'].strip())
resource['group'] = groups resource['group'] = groups
except (KeyError, AttributeError, IndexError, TypeError): except (KeyError, AttributeError, IndexError, TypeError):
@ -174,22 +203,23 @@ def get_snmp_user(user, module):
return resource return resource
def remove_snmp_user(user): def remove_snmp_user(user, group=None):
if group:
return ['no snmp-server user {0} {1}'.format(user, group)]
else:
return ['no snmp-server user {0}'.format(user)] return ['no snmp-server user {0}'.format(user)]
def config_snmp_user(proposed, user, reset, new): def config_snmp_user(proposed, user, reset):
if reset and not new: if reset:
commands = remove_snmp_user(user) commands = remove_snmp_user(user)
else: else:
commands = [] commands = []
group = proposed.get('group', None) if proposed.get('group'):
cmd = ''
if group:
cmd = 'snmp-server user {0} {group}'.format(user, **proposed) cmd = 'snmp-server user {0} {group}'.format(user, **proposed)
else:
cmd = 'snmp-server user {0}'.format(user)
auth = proposed.get('authentication', None) auth = proposed.get('authentication', None)
pwd = proposed.get('pwd', None) pwd = proposed.get('pwd', None)
@ -214,7 +244,7 @@ def config_snmp_user(proposed, user, reset, new):
def main(): def main():
argument_spec = dict( argument_spec = dict(
user=dict(required=True, type='str'), user=dict(required=True, type='str'),
group=dict(type='str', required=True), group=dict(type='str'),
pwd=dict(type='str'), pwd=dict(type='str'),
privacy=dict(type='str'), privacy=dict(type='str'),
authentication=dict(choices=['md5', 'sha']), authentication=dict(choices=['md5', 'sha']),
@ -251,19 +281,28 @@ def main():
existing = get_snmp_user(user, module) existing = get_snmp_user(user, module)
if existing: if state == 'present' and existing:
if group:
if group not in existing['group']: if group not in existing['group']:
existing['group'] = None existing['group'] = None
else: else:
existing['group'] = group existing['group'] = group
else:
existing['group'] = None
commands = [] commands = []
if state == 'absent' and existing: if state == 'absent' and existing:
if group:
if group in existing['group']:
if len(existing['group']) == 1:
commands.append(remove_snmp_user(user))
else:
commands.append(remove_snmp_user(user, group))
else:
commands.append(remove_snmp_user(user)) commands.append(remove_snmp_user(user))
elif state == 'present': elif state == 'present':
new = False
reset = False reset = False
args = dict(user=user, pwd=pwd, group=group, privacy=privacy, args = dict(user=user, pwd=pwd, group=group, privacy=privacy,
@ -273,7 +312,7 @@ def main():
if not existing: if not existing:
if encrypt: if encrypt:
proposed['encrypt'] = 'aes-128' proposed['encrypt'] = 'aes-128'
commands.append(config_snmp_user(proposed, user, reset, new)) commands.append(config_snmp_user(proposed, user, reset))
elif existing: elif existing:
if encrypt and not existing['encrypt'].startswith('aes'): if encrypt and not existing['encrypt'].startswith('aes'):
@ -285,13 +324,11 @@ def main():
if delta.get('pwd'): if delta.get('pwd'):
delta['authentication'] = authentication delta['authentication'] = authentication
if delta:
delta['group'] = group
if delta and encrypt: if delta and encrypt:
delta['encrypt'] = 'aes-128' delta['encrypt'] = 'aes-128'
command = config_snmp_user(delta, user, reset, new) if delta:
command = config_snmp_user(delta, user, reset)
commands.append(command) commands.append(command)
cmds = flatten_list(commands) cmds = flatten_list(commands)

View file

@ -3,7 +3,17 @@
- debug: msg="Using provider={{ connection.transport }}" - debug: msg="Using provider={{ connection.transport }}"
when: ansible_connection == "local" when: ansible_connection == "local"
- name: Create snmp user - name: Remove snmp user
nxos_snmp_user: &remove
user: ntc
state: absent
provider: "{{ connection }}"
- pause:
seconds: 5
- block:
- name: Create snmp user
nxos_snmp_user: &create nxos_snmp_user: &create
user: ntc user: ntc
group: network-operator group: network-operator
@ -14,30 +24,67 @@
provider: "{{ connection }}" provider: "{{ connection }}"
register: result register: result
- assert: &true - assert: &true
that: that:
- "result.changed == true" - "result.changed == true"
- name: delete snmp user - name: Add another group to user
nxos_snmp_user: &remove nxos_snmp_user: &chg
user: ntc user: ntc
group: network-operator group: network-admin
authentication: md5 provider: "{{ connection }}"
pwd: Testing1% register: result
privacy: HelloU$er1
encrypt: true - assert: *true
- name: "Check Idempotence"
nxos_snmp_user: *chg
register: result
- assert: &false
that:
- "result.changed == false"
- name: Remove group from user
nxos_snmp_user: &remg
user: ntc
group: network-admin
state: absent state: absent
provider: "{{ connection }}" provider: "{{ connection }}"
register: result register: result
- assert: *true - assert: *true
- name: "Remove Idempotence" - pause:
nxos_snmp_user: *remove seconds: 5
- name: "Check Idempotence"
nxos_snmp_user: *remg
register: result register: result
- assert: &false - assert: *false
that:
- "result.changed == false" - name: delete snmp user
nxos_snmp_user: &remove1
user: ntc
group: network-operator
state: absent
provider: "{{ connection }}"
register: result
- assert: *true
- pause:
seconds: 5
- name: "Remove Idempotence"
nxos_snmp_user: *remove1
register: result
- assert: *false
always:
- name: delete snmp user
nxos_snmp_user: *remove
- debug: msg="END connection={{ ansible_connection }} nxos_snmp_user sanity test" - debug: msg="END connection={{ ansible_connection }} nxos_snmp_user sanity test"