ios_user: Add support for multiple sshkeys (#51173)

* Add support for multiple sshkeys

Signed-off-by: NilashishC <nilashishchakraborty8@gmail.com>

* Fix CI

Signed-off-by: NilashishC <nilashishchakraborty8@gmail.com>

* Add the keys at on go

Signed-off-by: NilashishC <nilashishchakraborty8@gmail.com>

* Update tests

Signed-off-by: NilashishC <nilashishchakraborty8@gmail.com>
pull/51377/head
Nilashish Chakraborty 6 years ago committed by GitHub
parent 99a4a3dc33
commit 69dd03d472
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -102,8 +102,9 @@ options:
aliases: ['role'] aliases: ['role']
sshkey: sshkey:
description: description:
- Specifies the SSH public key to configure - Specifies one or more SSH public key(s) to configure
for the given username. This argument accepts a valid SSH key value. for the given username.
- This argument accepts a valid SSH key value.
version_added: "2.7" version_added: "2.7"
nopassword: nopassword:
description: description:
@ -139,6 +140,14 @@ EXAMPLES = """
sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
state: present state: present
- name: create a new user with multiple keys
ios_user:
name: ansible
sshkey:
- "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
- "{{ lookup('file', '~/path/to/public_key') }}"
state: present
- name: remove all users except admin - name: remove all users except admin
ios_user: ios_user:
purge: yes purge: yes
@ -210,19 +219,17 @@ commands:
- username ansible secret password - username ansible secret password
- username admin secret admin - username admin secret admin
""" """
from copy import deepcopy
import re
import base64 import base64
import hashlib import hashlib
import re
from copy import deepcopy
from functools import partial from functools import partial
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.common.utils import remove_default_spec from ansible.module_utils.network.common.utils import remove_default_spec
from ansible.module_utils.network.ios.ios import get_config, load_config from ansible.module_utils.network.ios.ios import get_config, load_config
from ansible.module_utils.six import iteritems
from ansible.module_utils.network.ios.ios import ios_argument_spec, check_args from ansible.module_utils.network.ios.ios import ios_argument_spec, check_args
from ansible.module_utils.six import iteritems
def validate_privilege(value, module): def validate_privilege(value, module):
@ -275,7 +282,8 @@ def map_obj_to_commands(updates, module):
command.append('ip ssh pubkey-chain') command.append('ip ssh pubkey-chain')
if x: if x:
command.append('username %s' % want['name']) command.append('username %s' % want['name'])
command.append('key-hash %s' % x) for item in x:
command.append('key-hash %s' % item)
command.append('exit') command.append('exit')
else: else:
command.append('no username %s' % want['name']) command.append('no username %s' % want['name'])
@ -324,10 +332,15 @@ def parse_view(data):
return match.group(1) return match.group(1)
def parse_sshkey(data): def parse_sshkey(data, user):
match = re.search(r'key-hash (\S+ \S+(?: .+)?)$', data, re.M) sshregex = r'username %s(\n\s+key-hash .+$)+' % user
if match: sshcfg = re.search(sshregex, data, re.M)
return match.group(1) key_list = []
if sshcfg:
match = re.findall(r'key-hash (\S+ \S+(?: .+)?)$', sshcfg.group(), re.M)
if match:
key_list = match
return key_list
def parse_privilege(data): def parse_privilege(data):
@ -356,9 +369,6 @@ def map_config_to_obj(module):
regex = r'username %s .+$' % user regex = r'username %s .+$' % user
cfg = re.findall(regex, data, re.M) cfg = re.findall(regex, data, re.M)
cfg = '\n'.join(cfg) cfg = '\n'.join(cfg)
sshregex = r'username %s\n\s+key-hash .+$' % user
sshcfg = re.findall(sshregex, data, re.M)
sshcfg = '\n'.join(sshcfg)
obj = { obj = {
'name': user, 'name': user,
'state': 'present', 'state': 'present',
@ -366,7 +376,7 @@ def map_config_to_obj(module):
'configured_password': None, 'configured_password': None,
'hashed_password': None, 'hashed_password': None,
'password_type': parse_password_type(cfg), 'password_type': parse_password_type(cfg),
'sshkey': parse_sshkey(sshcfg), 'sshkey': parse_sshkey(data, user),
'privilege': parse_privilege(cfg), 'privilege': parse_privilege(cfg),
'view': parse_view(cfg) 'view': parse_view(cfg)
} }
@ -423,13 +433,21 @@ def map_params_to_obj(module):
item['nopassword'] = get_value('nopassword') item['nopassword'] = get_value('nopassword')
item['privilege'] = get_value('privilege') item['privilege'] = get_value('privilege')
item['view'] = get_value('view') item['view'] = get_value('view')
item['sshkey'] = sshkey_fingerprint(get_value('sshkey')) item['sshkey'] = render_key_list(get_value('sshkey'))
item['state'] = get_value('state') item['state'] = get_value('state')
objects.append(item) objects.append(item)
return objects return objects
def render_key_list(ssh_keys):
key_list = []
if ssh_keys:
for item in ssh_keys:
key_list.append(sshkey_fingerprint(item))
return key_list
def update_objects(want, have): def update_objects(want, have):
updates = list() updates = list()
for entry in want: for entry in want:
@ -463,7 +481,7 @@ def main():
privilege=dict(type='int'), privilege=dict(type='int'),
view=dict(aliases=['role']), view=dict(aliases=['role']),
sshkey=dict(), sshkey=dict(type='list'),
state=dict(default='present', choices=['present', 'absent']) state=dict(default='present', choices=['present', 'absent'])
) )

@ -128,3 +128,16 @@ class TestIosUserModule(TestIosModule):
] ]
result = self.execute_module(changed=True, commands=commands) result = self.execute_module(changed=True, commands=commands)
self.assertEqual(result['commands'], commands) self.assertEqual(result['commands'], commands)
def test_ios_user_set_sshkey_multiple(self):
set_module_args(dict(name='ansible', sshkey=['dGVzdA==', 'eHWacB2==']))
commands = [
'ip ssh pubkey-chain',
'username ansible',
'key-hash ssh-rsa 098F6BCD4621D373CADE4E832627B4F6',
'key-hash ssh-rsa A019918340A1E9183388D9A675603036',
'exit',
'exit'
]
result = self.execute_module(changed=True, commands=commands)
self.assertEqual(result['commands'], commands)

Loading…
Cancel
Save