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
pull/28265/head
Trishna Guha 7 years ago committed by GitHub
parent d8b1cb9a63
commit ce3d1c6ba0

@ -42,7 +42,7 @@ _DEVICE_CONNECTION = None
eos_argument_spec = { eos_argument_spec = {
'host': dict(), 'host': dict(),
'port': dict(type='int'), '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), 'password': dict(fallback=(env_fallback, ['ANSIBLE_NET_PASSWORD']), no_log=True),
'ssh_keyfile': dict(fallback=(env_fallback, ['ANSIBLE_NET_SSH_KEYFILE']), type='path'), '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 or a hash of username and properties. This argument is mutually
exclusive with the C(username) argument. alias C(users). exclusive with the C(username) argument. alias C(users).
version_added: "2.4" version_added: "2.4"
username: name:
description: description:
- The username to be configured on the remote Arista EOS - The username to be configured on the remote Arista EOS
device. This argument accepts a stringv value and is mutually device. This argument accepts a stringv value and is mutually
exclusive with the C(aggregate) argument. exclusive with the C(aggregate) argument.
Please note that this option is not same as C(provider username). Please note that this option is not same as C(provider username).
version_added: "2.4"
password: password:
description: description:
- The password to be configured on the remote Arista EOS device. The - The password to be configured on the remote Arista EOS device. The
@ -106,7 +107,7 @@ options:
EXAMPLES = """ EXAMPLES = """
- name: create a new user - name: create a new user
eos_user: eos_user:
username: ansible name: ansible
sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
state: present state: present
@ -117,14 +118,14 @@ EXAMPLES = """
- name: set multiple users to privilege level 15 - name: set multiple users to privilege level 15
eos_user: eos_user:
aggregate: aggregate:
- username: netop - name: netop
- username: netend - name: netend
privilege: 15 privilege: 15
state: present state: present
- name: Change Password for User netop - name: Change Password for User netop
eos_user: eos_user:
username: netop name: netop
password: "{{ new_password }}" password: "{{ new_password }}"
update_password: always update_password: always
state: present state: present
@ -136,8 +137,8 @@ commands:
returned: always returned: always
type: list type: list
sample: sample:
- username ansible secret password - name ansible secret password
- username admin secret admin - name admin secret admin
session_name: session_name:
description: The EOS config session name used to load the configuration description: The EOS config session name used to load the configuration
returned: when changed is True 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.six import iteritems
from ansible.module_utils.eos import eos_argument_spec, check_args from ansible.module_utils.eos import eos_argument_spec, check_args
def validate_privilege(value, module): def validate_privilege(value, module):
if not 1 <= value <= 15: if not 1 <= value <= 15:
module.fail_json(msg='privilege must be between 1 and 15, got %s' % value) module.fail_json(msg='privilege must be between 1 and 15, got %s' % value)
def map_obj_to_commands(updates, module): def map_obj_to_commands(updates, module):
commands = list() commands = list()
state = module.params['state'] state = module.params['state']
@ -167,16 +170,10 @@ def map_obj_to_commands(updates, module):
want, have = update want, have = update
needs_update = lambda x: want.get(x) and (want.get(x) != have.get(x)) 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))
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 want['state'] == 'absent':
if 'name' in want: commands.append('no username %s' % want['name'])
commands.append('no username %s' % want['name'])
else:
commands.append('no username %s' % want['username'])
continue continue
if needs_update('role'): if needs_update('role'):
@ -196,28 +193,29 @@ def map_obj_to_commands(updates, module):
if want['nopassword']: if want['nopassword']:
add('nopassword') add('nopassword')
else: else:
if 'name' in want: add('no username %s nopassword' % want['name'])
add('no username %s nopassword' % want['name'])
else:
add('no username %s nopassword' % want['username'])
return commands return commands
def parse_role(data): def parse_role(data):
match = re.search(r'role (\S+)', data, re.M) match = re.search(r'role (\S+)', data, re.M)
if match: if match:
return match.group(1) return match.group(1)
def parse_sshkey(data): def parse_sshkey(data):
match = re.search(r'sshkey (.+)$', data, re.M) match = re.search(r'sshkey (.+)$', data, re.M)
if match: if match:
return match.group(1) return match.group(1)
def parse_privilege(data): def parse_privilege(data):
match = re.search(r'privilege (\S+)', data, re.M) match = re.search(r'privilege (\S+)', data, re.M)
if match: if match:
return int(match.group(1)) return int(match.group(1))
def map_config_to_obj(module): def map_config_to_obj(module):
data = get_config(module, flags=['section username']) 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 = re.findall(regex, data, re.M)
cfg = '\n'.join(cfg) cfg = '\n'.join(cfg)
obj = { obj = {
'username': user, 'name': user,
'state': 'present', 'state': 'present',
'nopassword': 'nopassword' in cfg, 'nopassword': 'nopassword' in cfg,
'password': None, 'password': None,
@ -244,6 +242,7 @@ def map_config_to_obj(module):
return instances return instances
def get_param_value(key, item, module): def get_param_value(key, item, module):
# if key doesn't exist in the item, get it from module.params # if key doesn't exist in the item, get it from module.params
if not item.get(key): if not item.get(key):
@ -263,22 +262,23 @@ def get_param_value(key, item, module):
return value return value
def map_params_to_obj(module): def map_params_to_obj(module):
aggregate = module.params['aggregate'] aggregate = module.params['aggregate']
if not aggregate: if not aggregate:
if not module.params['username'] and module.params['purge']: if not module.params['name'] and module.params['purge']:
return list() return list()
elif not module.params['username']: elif not module.params['name']:
module.fail_json(msg='username is required') module.fail_json(msg='name is required')
else: else:
collection = [{'username': module.params['username']}] collection = [{'name': module.params['name']}]
else: else:
collection = list() collection = list()
for item in aggregate: for item in aggregate:
if not isinstance(item, dict): if not isinstance(item, dict):
collection.append({'username': item}) collection.append({'name': item})
elif all(u not in item for u in ['username', 'name']): elif 'name' not in item:
module.fail_json(msg='username is required') module.fail_json(msg='name is required')
else: else:
collection.append(item) collection.append(item)
@ -296,14 +296,12 @@ def map_params_to_obj(module):
return objects return objects
def update_objects(want, have): def update_objects(want, have):
updates = list() updates = list()
for entry in want: for entry in want:
if 'name' in entry: if 'name' in entry:
item = next((i for i in have if i['username'] == entry['name']), None) item = next((i for i in have if i['name'] == entry['name']), None)
else:
item = next((i for i in have if i['username'] == entry['username']), None)
if all((item is None, entry['state'] == 'present')): if all((item is None, entry['state'] == 'present')):
updates.append((entry, {})) updates.append((entry, {}))
elif item: elif item:
@ -312,12 +310,13 @@ def update_objects(want, have):
updates.append((entry, item)) updates.append((entry, item))
return updates return updates
def main(): def main():
""" main entry point for module execution """ main entry point for module execution
""" """
argument_spec = dict( argument_spec = dict(
aggregate=dict(type='list', aliases=['collection', 'users']), aggregate=dict(type='list', aliases=['collection', 'users']),
username=dict(aliases=['name']), name=dict(),
password=dict(no_log=True), password=dict(no_log=True),
nopassword=dict(type='bool'), nopassword=dict(type='bool'),
@ -333,7 +332,7 @@ def main():
) )
argument_spec.update(eos_argument_spec) argument_spec.update(eos_argument_spec)
mutually_exclusive = [('username', 'aggregate')] mutually_exclusive = [('name', 'aggregate')]
module = AnsibleModule(argument_spec=argument_spec, module = AnsibleModule(argument_spec=argument_spec,
mutually_exclusive=mutually_exclusive, mutually_exclusive=mutually_exclusive,
@ -352,8 +351,8 @@ def main():
commands = map_obj_to_commands(update_objects(want, have), module) commands = map_obj_to_commands(update_objects(want, have), module)
if module.params['purge']: if module.params['purge']:
want_users = [x['username'] if 'username' in x else x['name'] for x in want] want_users = [x['name'] for x in want]
have_users = [x['username'] for x in have] have_users = [x['name'] for x in have]
for item in set(have_users).difference(want_users): for item in set(have_users).difference(want_users):
if item != 'admin': if item != 'admin':
commands.append('no username %s' % item) 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 - name: Create user
eos_user: eos_user:
name: netend name: ansibletest1
privilege: 15 privilege: 15
role: network-operator role: network-operator
state: present state: present
@ -12,13 +20,13 @@
- assert: - assert:
that: that:
- 'result.changed == true' - '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 - name: Collection of users
eos_user: eos_user:
aggregate: aggregate:
- name: test1 - name: ansibletest2
- name: test2 - name: ansibletest3
authorize: yes authorize: yes
state: present state: present
role: network-operator role: network-operator
@ -28,12 +36,12 @@
- assert: - assert:
that: that:
- 'result.changed == true' - '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 - name: tearDown
eos_config: eos_config:
lines: lines:
- no username netend - no username ansibletest1
- no username test1 - no username ansibletest2
- no username test2 - no username ansibletest3
provider: "{{ cli }}" provider: "{{ cli }}"

@ -44,27 +44,27 @@ class TestEosUserModule(TestEosModule):
self.load_config.return_value = dict(diff=None, session='session') self.load_config.return_value = dict(diff=None, session='session')
def test_eos_user_create(self): 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'] commands = ['username test nopassword']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_delete(self): 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'] commands = ['no username ansible']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_password(self): 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'] commands = ['username ansible secret test']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_privilege(self): 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'] commands = ['username ansible privilege 15']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_privilege_invalid(self): 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) self.execute_module(failed=True)
def test_eos_user_purge(self): def test_eos_user_purge(self):
@ -73,25 +73,25 @@ class TestEosUserModule(TestEosModule):
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_role(self): 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'] commands = ['username ansible role test']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_sshkey(self): 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'] commands = ['username ansible sshkey test']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_update_password_changed(self): 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'] commands = ['username test secret test']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)
def test_eos_user_update_password_on_create_ok(self): 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() self.execute_module()
def test_eos_user_update_password_always(self): 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'] commands = ['username ansible secret test']
self.execute_module(changed=True, commands=commands) self.execute_module(changed=True, commands=commands)

Loading…
Cancel
Save