eos_user fix username param (#28114)
* eos_user fix username param Signed-off-by: Trishna Guha <trishnaguha17@gmail.com> * Add setup eos_user test and rename username for consistency Signed-off-by: Trishna Guha <trishnaguha17@gmail.com> * update unit test and pep8 fix Signed-off-by: Trishna Guha <trishnaguha17@gmail.com> * pep8 fix
This commit is contained in:
parent
d8b1cb9a63
commit
ce3d1c6ba0
4 changed files with 61 additions and 54 deletions
|
@ -42,7 +42,7 @@ _DEVICE_CONNECTION = None
|
|||
eos_argument_spec = {
|
||||
'host': dict(),
|
||||
'port': dict(type='int'),
|
||||
'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME']), aliases=['name']),
|
||||
'username': dict(fallback=(env_fallback, ['ANSIBLE_NET_USERNAME'])),
|
||||
'password': dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True),
|
||||
'ssh_keyfile': dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'),
|
||||
|
||||
|
|
|
@ -42,12 +42,13 @@ options:
|
|||
or a hash of username and properties. This argument is mutually
|
||||
exclusive with the C(username) argument. alias C(users).
|
||||
version_added: "2.4"
|
||||
username:
|
||||
name:
|
||||
description:
|
||||
- The username to be configured on the remote Arista EOS
|
||||
device. This argument accepts a stringv value and is mutually
|
||||
exclusive with the C(aggregate) argument.
|
||||
Please note that this option is not same as C(provider username).
|
||||
version_added: "2.4"
|
||||
password:
|
||||
description:
|
||||
- The password to be configured on the remote Arista EOS device. The
|
||||
|
@ -106,7 +107,7 @@ options:
|
|||
EXAMPLES = """
|
||||
- name: create a new user
|
||||
eos_user:
|
||||
username: ansible
|
||||
name: ansible
|
||||
sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
|
||||
state: present
|
||||
|
||||
|
@ -117,14 +118,14 @@ EXAMPLES = """
|
|||
- name: set multiple users to privilege level 15
|
||||
eos_user:
|
||||
aggregate:
|
||||
- username: netop
|
||||
- username: netend
|
||||
- name: netop
|
||||
- name: netend
|
||||
privilege: 15
|
||||
state: present
|
||||
|
||||
- name: Change Password for User netop
|
||||
eos_user:
|
||||
username: netop
|
||||
name: netop
|
||||
password: "{{ new_password }}"
|
||||
update_password: always
|
||||
state: present
|
||||
|
@ -136,8 +137,8 @@ commands:
|
|||
returned: always
|
||||
type: list
|
||||
sample:
|
||||
- username ansible secret password
|
||||
- username admin secret admin
|
||||
- name ansible secret password
|
||||
- name admin secret admin
|
||||
session_name:
|
||||
description: The EOS config session name used to load the configuration
|
||||
returned: when changed is True
|
||||
|
@ -154,10 +155,12 @@ from ansible.module_utils.eos import get_config, load_config
|
|||
from ansible.module_utils.six import iteritems
|
||||
from ansible.module_utils.eos import eos_argument_spec, check_args
|
||||
|
||||
|
||||
def validate_privilege(value, module):
|
||||
if not 1 <= value <= 15:
|
||||
module.fail_json(msg='privilege must be between 1 and 15, got %s' % value)
|
||||
|
||||
|
||||
def map_obj_to_commands(updates, module):
|
||||
commands = list()
|
||||
state = module.params['state']
|
||||
|
@ -167,16 +170,10 @@ def map_obj_to_commands(updates, module):
|
|||
want, have = update
|
||||
|
||||
needs_update = lambda x: want.get(x) and (want.get(x) != have.get(x))
|
||||
if 'name' in want:
|
||||
add = lambda x: commands.append('username %s %s' % (want['name'], x))
|
||||
else:
|
||||
add = lambda x: commands.append('username %s %s' % (want['username'], x))
|
||||
|
||||
if want['state'] == 'absent':
|
||||
if 'name' in want:
|
||||
commands.append('no username %s' % want['name'])
|
||||
else:
|
||||
commands.append('no username %s' % want['username'])
|
||||
continue
|
||||
|
||||
if needs_update('role'):
|
||||
|
@ -196,28 +193,29 @@ def map_obj_to_commands(updates, module):
|
|||
if want['nopassword']:
|
||||
add('nopassword')
|
||||
else:
|
||||
if 'name' in want:
|
||||
add('no username %s nopassword' % want['name'])
|
||||
else:
|
||||
add('no username %s nopassword' % want['username'])
|
||||
|
||||
return commands
|
||||
|
||||
|
||||
def parse_role(data):
|
||||
match = re.search(r'role (\S+)', data, re.M)
|
||||
if match:
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def parse_sshkey(data):
|
||||
match = re.search(r'sshkey (.+)$', data, re.M)
|
||||
if match:
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def parse_privilege(data):
|
||||
match = re.search(r'privilege (\S+)', data, re.M)
|
||||
if match:
|
||||
return int(match.group(1))
|
||||
|
||||
|
||||
def map_config_to_obj(module):
|
||||
data = get_config(module, flags=['section username'])
|
||||
|
||||
|
@ -232,7 +230,7 @@ def map_config_to_obj(module):
|
|||
cfg = re.findall(regex, data, re.M)
|
||||
cfg = '\n'.join(cfg)
|
||||
obj = {
|
||||
'username': user,
|
||||
'name': user,
|
||||
'state': 'present',
|
||||
'nopassword': 'nopassword' in cfg,
|
||||
'password': None,
|
||||
|
@ -244,6 +242,7 @@ def map_config_to_obj(module):
|
|||
|
||||
return instances
|
||||
|
||||
|
||||
def get_param_value(key, item, module):
|
||||
# if key doesn't exist in the item, get it from module.params
|
||||
if not item.get(key):
|
||||
|
@ -263,22 +262,23 @@ def get_param_value(key, item, module):
|
|||
|
||||
return value
|
||||
|
||||
|
||||
def map_params_to_obj(module):
|
||||
aggregate = module.params['aggregate']
|
||||
if not aggregate:
|
||||
if not module.params['username'] and module.params['purge']:
|
||||
if not module.params['name'] and module.params['purge']:
|
||||
return list()
|
||||
elif not module.params['username']:
|
||||
module.fail_json(msg='username is required')
|
||||
elif not module.params['name']:
|
||||
module.fail_json(msg='name is required')
|
||||
else:
|
||||
collection = [{'username': module.params['username']}]
|
||||
collection = [{'name': module.params['name']}]
|
||||
else:
|
||||
collection = list()
|
||||
for item in aggregate:
|
||||
if not isinstance(item, dict):
|
||||
collection.append({'username': item})
|
||||
elif all(u not in item for u in ['username', 'name']):
|
||||
module.fail_json(msg='username is required')
|
||||
collection.append({'name': item})
|
||||
elif 'name' not in item:
|
||||
module.fail_json(msg='name is required')
|
||||
else:
|
||||
collection.append(item)
|
||||
|
||||
|
@ -296,14 +296,12 @@ def map_params_to_obj(module):
|
|||
|
||||
return objects
|
||||
|
||||
|
||||
def update_objects(want, have):
|
||||
updates = list()
|
||||
for entry in want:
|
||||
if 'name' in entry:
|
||||
item = next((i for i in have if i['username'] == entry['name']), None)
|
||||
else:
|
||||
item = next((i for i in have if i['username'] == entry['username']), None)
|
||||
|
||||
item = next((i for i in have if i['name'] == entry['name']), None)
|
||||
if all((item is None, entry['state'] == 'present')):
|
||||
updates.append((entry, {}))
|
||||
elif item:
|
||||
|
@ -312,12 +310,13 @@ def update_objects(want, have):
|
|||
updates.append((entry, item))
|
||||
return updates
|
||||
|
||||
|
||||
def main():
|
||||
""" main entry point for module execution
|
||||
"""
|
||||
argument_spec = dict(
|
||||
aggregate=dict(type='list', aliases=['collection', 'users']),
|
||||
username=dict(aliases=['name']),
|
||||
name=dict(),
|
||||
|
||||
password=dict(no_log=True),
|
||||
nopassword=dict(type='bool'),
|
||||
|
@ -333,7 +332,7 @@ def main():
|
|||
)
|
||||
|
||||
argument_spec.update(eos_argument_spec)
|
||||
mutually_exclusive = [('username', 'aggregate')]
|
||||
mutually_exclusive = [('name', 'aggregate')]
|
||||
|
||||
module = AnsibleModule(argument_spec=argument_spec,
|
||||
mutually_exclusive=mutually_exclusive,
|
||||
|
@ -352,8 +351,8 @@ def main():
|
|||
commands = map_obj_to_commands(update_objects(want, have), module)
|
||||
|
||||
if module.params['purge']:
|
||||
want_users = [x['username'] if 'username' in x else x['name'] for x in want]
|
||||
have_users = [x['username'] for x in have]
|
||||
want_users = [x['name'] for x in want]
|
||||
have_users = [x['name'] for x in have]
|
||||
for item in set(have_users).difference(want_users):
|
||||
if item != 'admin':
|
||||
commands.append('no username %s' % item)
|
||||
|
|
|
@ -1,7 +1,15 @@
|
|||
---
|
||||
- name: Set Up
|
||||
eos_config:
|
||||
lines:
|
||||
- no username ansibletest1
|
||||
- no username ansibletest2
|
||||
- no username ansibletest3
|
||||
provider: "{{ cli }}"
|
||||
|
||||
- name: Create user
|
||||
eos_user:
|
||||
name: netend
|
||||
name: ansibletest1
|
||||
privilege: 15
|
||||
role: network-operator
|
||||
state: present
|
||||
|
@ -12,13 +20,13 @@
|
|||
- assert:
|
||||
that:
|
||||
- 'result.changed == true'
|
||||
- 'result.commands == ["username netend role network-operator", "username netend privilege 15"]'
|
||||
- 'result.commands == ["username ansibletest1 role network-operator", "username ansibletest1 privilege 15"]'
|
||||
|
||||
- name: Collection of users
|
||||
eos_user:
|
||||
aggregate:
|
||||
- name: test1
|
||||
- name: test2
|
||||
- name: ansibletest2
|
||||
- name: ansibletest3
|
||||
authorize: yes
|
||||
state: present
|
||||
role: network-operator
|
||||
|
@ -28,12 +36,12 @@
|
|||
- assert:
|
||||
that:
|
||||
- 'result.changed == true'
|
||||
- 'result.commands == ["username test1 role network-operator", "username test2 role network-operator"]'
|
||||
- 'result.commands == ["username ansibletest2 role network-operator", "username ansibletest3 role network-operator"]'
|
||||
|
||||
- name: tearDown
|
||||
eos_config:
|
||||
lines:
|
||||
- no username netend
|
||||
- no username test1
|
||||
- no username test2
|
||||
- no username ansibletest1
|
||||
- no username ansibletest2
|
||||
- no username ansibletest3
|
||||
provider: "{{ cli }}"
|
||||
|
|
|
@ -44,27 +44,27 @@ class TestEosUserModule(TestEosModule):
|
|||
self.load_config.return_value = dict(diff=None, session='session')
|
||||
|
||||
def test_eos_user_create(self):
|
||||
set_module_args(dict(username='test', nopassword=True))
|
||||
set_module_args(dict(name='test', nopassword=True))
|
||||
commands = ['username test nopassword']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_delete(self):
|
||||
set_module_args(dict(username='ansible', state='absent'))
|
||||
set_module_args(dict(name='ansible', state='absent'))
|
||||
commands = ['no username ansible']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_password(self):
|
||||
set_module_args(dict(username='ansible', password='test'))
|
||||
set_module_args(dict(name='ansible', password='test'))
|
||||
commands = ['username ansible secret test']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_privilege(self):
|
||||
set_module_args(dict(username='ansible', privilege=15))
|
||||
set_module_args(dict(name='ansible', privilege=15))
|
||||
commands = ['username ansible privilege 15']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_privilege_invalid(self):
|
||||
set_module_args(dict(username='ansible', privilege=25))
|
||||
set_module_args(dict(name='ansible', privilege=25))
|
||||
self.execute_module(failed=True)
|
||||
|
||||
def test_eos_user_purge(self):
|
||||
|
@ -73,25 +73,25 @@ class TestEosUserModule(TestEosModule):
|
|||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_role(self):
|
||||
set_module_args(dict(username='ansible', role='test'))
|
||||
set_module_args(dict(name='ansible', role='test'))
|
||||
commands = ['username ansible role test']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_sshkey(self):
|
||||
set_module_args(dict(username='ansible', sshkey='test'))
|
||||
set_module_args(dict(name='ansible', sshkey='test'))
|
||||
commands = ['username ansible sshkey test']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_update_password_changed(self):
|
||||
set_module_args(dict(username='test', password='test', update_password='on_create'))
|
||||
set_module_args(dict(name='test', password='test', update_password='on_create'))
|
||||
commands = ['username test secret test']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
||||
def test_eos_user_update_password_on_create_ok(self):
|
||||
set_module_args(dict(username='ansible', password='test', update_password='on_create'))
|
||||
set_module_args(dict(name='ansible', password='test', update_password='on_create'))
|
||||
self.execute_module()
|
||||
|
||||
def test_eos_user_update_password_always(self):
|
||||
set_module_args(dict(username='ansible', password='test', update_password='always'))
|
||||
set_module_args(dict(name='ansible', password='test', update_password='always'))
|
||||
commands = ['username ansible secret test']
|
||||
self.execute_module(changed=True, commands=commands)
|
||||
|
|
Loading…
Reference in a new issue