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>
This commit is contained in:
Nilashish Chakraborty 2019-01-28 13:44:15 +05:30 committed by GitHub
parent 99a4a3dc33
commit 69dd03d472
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 18 deletions

View file

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

View file

@ -128,3 +128,16 @@ class TestIosUserModule(TestIosModule):
]
result = self.execute_module(changed=True, 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)