From ce3d1c6ba00e1a36c016575ea7d7d04b71923486 Mon Sep 17 00:00:00 2001 From: Trishna Guha Date: Wed, 16 Aug 2017 12:08:59 +0530 Subject: [PATCH] eos_user fix username param (#28114) * eos_user fix username param Signed-off-by: Trishna Guha * Add setup eos_user test and rename username for consistency Signed-off-by: Trishna Guha * update unit test and pep8 fix Signed-off-by: Trishna Guha * pep8 fix --- lib/ansible/module_utils/eos.py | 2 +- lib/ansible/modules/network/eos/eos_user.py | 69 +++++++++---------- .../targets/eos_user/tests/cli/basic.yaml | 24 ++++--- .../modules/network/eos/test_eos_user.py | 20 +++--- 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/lib/ansible/module_utils/eos.py b/lib/ansible/module_utils/eos.py index bce5469941..a6ecb985a2 100644 --- a/lib/ansible/module_utils/eos.py +++ b/lib/ansible/module_utils/eos.py @@ -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'), diff --git a/lib/ansible/modules/network/eos/eos_user.py b/lib/ansible/modules/network/eos/eos_user.py index c152da4187..cde382123a 100644 --- a/lib/ansible/modules/network/eos/eos_user.py +++ b/lib/ansible/modules/network/eos/eos_user.py @@ -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)) + add = lambda x: commands.append('username %s %s' % (want['name'], x)) if want['state'] == 'absent': - if 'name' in want: - commands.append('no username %s' % want['name']) - else: - commands.append('no username %s' % want['username']) + commands.append('no username %s' % want['name']) 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']) + add('no username %s nopassword' % want['name']) 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) diff --git a/test/integration/targets/eos_user/tests/cli/basic.yaml b/test/integration/targets/eos_user/tests/cli/basic.yaml index 2de8fa369c..1e646e6fd5 100644 --- a/test/integration/targets/eos_user/tests/cli/basic.yaml +++ b/test/integration/targets/eos_user/tests/cli/basic.yaml @@ -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 }}" diff --git a/test/units/modules/network/eos/test_eos_user.py b/test/units/modules/network/eos/test_eos_user.py index b8acfc9b01..9dd5d03635 100644 --- a/test/units/modules/network/eos/test_eos_user.py +++ b/test/units/modules/network/eos/test_eos_user.py @@ -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)