mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-05-22 00:49:09 -07:00
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:
parent
99a4a3dc33
commit
69dd03d472
2 changed files with 49 additions and 18 deletions
|
@ -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…
Add table
Add a link
Reference in a new issue