mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
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 = {
|
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…
Reference in a new issue