|
|
|
@ -73,6 +73,21 @@ options:
|
|
|
|
|
default: secret
|
|
|
|
|
choices: ['secret', 'password']
|
|
|
|
|
version_added: "2.8"
|
|
|
|
|
hashed_password:
|
|
|
|
|
description:
|
|
|
|
|
- This option allows configuring hashed passwords on Cisco IOS devices.
|
|
|
|
|
suboptions:
|
|
|
|
|
type:
|
|
|
|
|
description:
|
|
|
|
|
- Specifies the type of hash (e.g., 5 for MD5, 8 for PBKDF2, etc.)
|
|
|
|
|
- For this to work, the device needs to support the desired hash type
|
|
|
|
|
type: int
|
|
|
|
|
required: True
|
|
|
|
|
value:
|
|
|
|
|
description:
|
|
|
|
|
- The actual hashed password to be configured on the device
|
|
|
|
|
required: True
|
|
|
|
|
version_added: "2.8"
|
|
|
|
|
privilege:
|
|
|
|
|
description:
|
|
|
|
|
- The C(privilege) argument configures the privilege level of the
|
|
|
|
@ -170,6 +185,13 @@ EXAMPLES = """
|
|
|
|
|
configured_password: "{{ new_password }}"
|
|
|
|
|
password_type: password
|
|
|
|
|
|
|
|
|
|
- name: Add a user with MD5 hashed password
|
|
|
|
|
ios_user:
|
|
|
|
|
name: ansibletest5
|
|
|
|
|
hashed_password:
|
|
|
|
|
type: 5
|
|
|
|
|
value: $3$8JcDilcYgFZi.yz4ApaqkHG2.8/
|
|
|
|
|
|
|
|
|
|
- name: Delete users with aggregate
|
|
|
|
|
ios_user:
|
|
|
|
|
aggregate:
|
|
|
|
@ -191,6 +213,7 @@ commands:
|
|
|
|
|
from copy import deepcopy
|
|
|
|
|
|
|
|
|
|
import re
|
|
|
|
|
import ast
|
|
|
|
|
import base64
|
|
|
|
|
import hashlib
|
|
|
|
|
|
|
|
|
@ -245,6 +268,10 @@ def map_obj_to_commands(updates, module):
|
|
|
|
|
def add(command, want, x):
|
|
|
|
|
command.append('username %s %s' % (want['name'], x))
|
|
|
|
|
|
|
|
|
|
def add_hashed_password(command, want, x):
|
|
|
|
|
command.append('username %s secret %s %s' % (want['name'], ast.literal_eval(x)['type'],
|
|
|
|
|
ast.literal_eval(x)['value']))
|
|
|
|
|
|
|
|
|
|
def add_ssh(command, want, x=None):
|
|
|
|
|
command.append('ip ssh pubkey-chain')
|
|
|
|
|
if x:
|
|
|
|
@ -280,6 +307,9 @@ def map_obj_to_commands(updates, module):
|
|
|
|
|
' Please choose one or the other.')
|
|
|
|
|
add(commands, want, '%s %s' % (password_type, want['configured_password']))
|
|
|
|
|
|
|
|
|
|
if needs_update(want, have, 'hashed_password'):
|
|
|
|
|
add_hashed_password(commands, want, want['hashed_password'])
|
|
|
|
|
|
|
|
|
|
if needs_update(want, have, 'nopassword'):
|
|
|
|
|
if want['nopassword']:
|
|
|
|
|
add(commands, want, 'nopassword')
|
|
|
|
@ -335,6 +365,7 @@ def map_config_to_obj(module):
|
|
|
|
|
'state': 'present',
|
|
|
|
|
'nopassword': 'nopassword' in cfg,
|
|
|
|
|
'configured_password': None,
|
|
|
|
|
'hashed_password': None,
|
|
|
|
|
'password_type': parse_password_type(cfg),
|
|
|
|
|
'sshkey': parse_sshkey(sshcfg),
|
|
|
|
|
'privilege': parse_privilege(cfg),
|
|
|
|
@ -389,6 +420,7 @@ def map_params_to_obj(module):
|
|
|
|
|
for item in aggregate:
|
|
|
|
|
get_value = partial(get_param_value, item=item, module=module)
|
|
|
|
|
item['configured_password'] = get_value('configured_password')
|
|
|
|
|
item['hashed_password'] = get_value('hashed_password')
|
|
|
|
|
item['nopassword'] = get_value('nopassword')
|
|
|
|
|
item['privilege'] = get_value('privilege')
|
|
|
|
|
item['view'] = get_value('view')
|
|
|
|
@ -415,10 +447,16 @@ def update_objects(want, have):
|
|
|
|
|
def main():
|
|
|
|
|
""" main entry point for module execution
|
|
|
|
|
"""
|
|
|
|
|
hashed_password_spec = dict(
|
|
|
|
|
type=dict(type='int', required=True),
|
|
|
|
|
value=dict(no_log=True, required=True)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
element_spec = dict(
|
|
|
|
|
name=dict(),
|
|
|
|
|
|
|
|
|
|
configured_password=dict(no_log=True),
|
|
|
|
|
hashed_password=dict(no_log=True, elements='dict', options=hashed_password_spec),
|
|
|
|
|
nopassword=dict(type='bool'),
|
|
|
|
|
update_password=dict(default='always', choices=['on_create', 'always']),
|
|
|
|
|
password_type=dict(default='secret', choices=['secret', 'password']),
|
|
|
|
@ -444,7 +482,7 @@ def main():
|
|
|
|
|
argument_spec.update(element_spec)
|
|
|
|
|
argument_spec.update(ios_argument_spec)
|
|
|
|
|
|
|
|
|
|
mutually_exclusive = [('name', 'aggregate')]
|
|
|
|
|
mutually_exclusive = [('name', 'aggregate'), ('nopassword', 'hashed_password', 'configured_password')]
|
|
|
|
|
|
|
|
|
|
module = AnsibleModule(argument_spec=argument_spec,
|
|
|
|
|
mutually_exclusive=mutually_exclusive,
|
|
|
|
|