Change network *_user modules to use configured_password to set a users password (#28187)

* WIP, update eos_user args

* refactor password for ios_user

* add eos tests, fix ios tests

* fixed password check

* refactor iosxr_user password

* fixed password arg for nxos

* [WIP] fix vyos_user password

* fix vyos tests

* update docs for net_user

* fix typo

* fix eos tests

* add warning when attempting to use password arg

* fix sanity/unit tests

* fix eos unit tests

* fix vyos_user aggregate

* fix typo in eos documentation string

* re add configured_password to vyos tests after rebase
pull/28332/head
David Newswanger 7 years ago committed by Trishna Guha
parent b1d297d144
commit b818e986b6

@ -49,12 +49,13 @@ options:
exclusive with the C(aggregate) argument.
Please note that this option is not same as C(provider username).
version_added: "2.4"
password:
configured_password:
description:
- The password to be configured on the remote Arista EOS device. The
password needs to be provided in clear and it will be encrypted
on the device.
Please note that this option is not same as C(provider password).
version_added: "2.4"
update_password:
description:
- Since passwords are encrypted in the device running config, this
@ -125,8 +126,8 @@ EXAMPLES = """
- name: Change Password for User netop
eos_user:
name: netop
password: "{{ new_password }}"
username: netop
configured_password: "{{ new_password }}"
update_password: always
state: present
"""
@ -182,9 +183,9 @@ def map_obj_to_commands(updates, module):
if needs_update('privilege'):
add('privilege %s' % want['privilege'])
if needs_update('password'):
if needs_update('configured_password'):
if update_password == 'always' or not have:
add('secret %s' % want['password'])
add('secret %s' % want['configured_password'])
if needs_update('sshkey'):
add('sshkey %s' % want['sshkey'])
@ -233,7 +234,7 @@ def map_config_to_obj(module):
'name': user,
'state': 'present',
'nopassword': 'nopassword' in cfg,
'password': None,
'configured_password': None,
'sshkey': parse_sshkey(cfg),
'privilege': parse_privilege(cfg),
'role': parse_role(cfg)
@ -286,7 +287,7 @@ def map_params_to_obj(module):
for item in collection:
get_value = partial(get_param_value, item=item, module=module)
item['password'] = get_value('password')
item['configured_password'] = get_value('configured_password')
item['nopassword'] = get_value('nopassword')
item['privilege'] = get_value('privilege')
item['role'] = get_value('role')
@ -318,7 +319,7 @@ def main():
aggregate=dict(type='list', aliases=['collection', 'users']),
name=dict(),
password=dict(no_log=True),
configured_password=dict(no_log=True),
nopassword=dict(type='bool'),
update_password=dict(default='always', choices=['on_create', 'always']),
@ -339,6 +340,12 @@ def main():
supports_check_mode=True)
warnings = list()
if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
check_args(module, warnings)
result = {'changed': False}

@ -48,7 +48,7 @@ options:
This argument accepts a string value and is mutually exclusive
with the C(aggregate) argument.
Please note that this option is not same as C(provider username).
password:
configured_password:
description:
- The password to be configured on the Cisco IOS device. The
password needs to be provided in clear and it will be encrypted
@ -127,7 +127,7 @@ EXAMPLES = """
- name: Change Password for User netop
ios_user:
name: netop
password: "{{ new_password }}"
configured_password: "{{ new_password }}"
update_password: always
state: present
@ -207,9 +207,9 @@ def map_obj_to_commands(updates, module):
if needs_update(want, have, 'privilege'):
add(commands, want, 'privilege %s' % want['privilege'])
if needs_update(want, have, 'password'):
if needs_update(want, have, 'configured_password'):
if update_password == 'always' or not have:
add(commands, want, 'secret %s' % want['password'])
add(commands, want, 'secret %s' % want['configured_password'])
if needs_update(want, have, 'nopassword'):
if want['nopassword']:
@ -249,7 +249,7 @@ def map_config_to_obj(module):
'name': user,
'state': 'present',
'nopassword': 'nopassword' in cfg,
'password': None,
'configured_password': None,
'privilege': parse_privilege(cfg),
'view': parse_view(cfg)
}
@ -301,7 +301,7 @@ def map_params_to_obj(module):
for item in aggregate:
get_value = partial(get_param_value, item=item, module=module)
item['password'] = get_value('password')
item['configured_password'] = get_value('configured_password')
item['nopassword'] = get_value('nopassword')
item['privilege'] = get_value('privilege')
item['view'] = get_value('view')
@ -330,7 +330,7 @@ def main():
element_spec = dict(
name=dict(),
password=dict(no_log=True),
configured_password=dict(no_log=True),
nopassword=dict(type='bool'),
update_password=dict(default='always', choices=['on_create', 'always']),
@ -360,6 +360,12 @@ def main():
supports_check_mode=True)
warnings = list()
if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
check_args(module, warnings)
result = {'changed': False}

@ -37,7 +37,7 @@ options:
This argument accepts a string value and is mutually exclusive
with the C(aggregate) argument.
Please note that this option is not same as C(provider username).
password:
configured_password:
description:
- The password to be configured on the Cisco IOS XR device. The
password needs to be provided in clear and it will be encrypted
@ -81,7 +81,7 @@ EXAMPLES = """
- name: create a new user
iosxr_user:
name: ansible
password: test
configured_password: test
state: present
- name: remove all users except admin
iosxr_user:
@ -96,7 +96,7 @@ EXAMPLES = """
- name: Change Password for User netop
iosxr_user:
name: netop
password: "{{ new_password }}"
configured_password: "{{ new_password }}"
update_password: always
state: present
"""
@ -142,16 +142,16 @@ def map_obj_to_commands(updates, module):
user_cmd = 'username ' + name
commands.append(user_cmd)
if w['password']:
commands.append(user_cmd + ' secret ' + w['password'])
if w['configured_password']:
commands.append(user_cmd + ' secret ' + w['configured_password'])
if w['group']:
commands.append(user_cmd + ' group ' + w['group'])
elif state == 'present' and obj_in_have:
user_cmd = 'username ' + name
if module.params['update_password'] == 'always' and w['password']:
commands.append(user_cmd + ' secret ' + w['password'])
if module.params['update_password'] == 'always' and w['configured_password']:
commands.append(user_cmd + ' secret ' + w['configured_password'])
if w['group'] and w['group'] != obj_in_have['group']:
commands.append(user_cmd + ' group ' + w['group'])
@ -181,7 +181,7 @@ def map_config_to_obj(module):
obj = {
'name': name,
'state': 'present',
'password': None,
'configured_password': None,
'group': group
}
instances.append(obj)
@ -232,7 +232,7 @@ def map_params_to_obj(module):
for item in aggregate:
get_value = partial(get_param_value, item=item, module=module)
item['password'] = get_value('password')
item['configured_password'] = get_value('configured_password')
item['group'] = get_value('group')
item['state'] = get_value('state')
objects.append(item)
@ -247,7 +247,7 @@ def main():
aggregate=dict(type='list', aliases=['users', 'collection']),
name=dict(),
password=dict(no_log=True),
configured_password=dict(no_log=True),
update_password=dict(default='always', choices=['on_create', 'always']),
group=dict(aliases=['role']),
@ -264,6 +264,12 @@ def main():
supports_check_mode=True)
warnings = list()
if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
check_args(module, warnings)
result = {'changed': False}

@ -51,6 +51,13 @@ options:
exclusive with the C(aggregate) argument.
required: false
default: null
configured_password:
description:
- The password to be configured on the network device. The
password needs to be provided in cleartext and it will be encrypted
on the device.
Please note that this option is not same as C(provider password).
version_added: "2.4"
update_password:
description:
- Since passwords are encrypted in the device running config, this
@ -178,9 +185,9 @@ def map_obj_to_commands(updates, module):
if want['state'] == 'present' and not have:
commands.append('username %s' % want['name'])
if needs_update('password'):
if needs_update('configured_password'):
if update_password == 'always' or not have:
add('password %s' % want['password'])
add('password %s' % want['configured_password'])
if needs_update('sshkey'):
add('sshkey %s' % want['sshkey'])
@ -221,7 +228,7 @@ def map_config_to_obj(module):
for item in to_list(data['TABLE_template']['ROW_template']):
objects.append({
'name': item['usr_name'],
'password': parse_password(item),
'configured_password': parse_password(item),
'sshkey': item.get('sshkey_info'),
'roles': parse_roles(item),
'state': 'present'
@ -266,7 +273,7 @@ def map_params_to_obj(module):
for item in collection:
get_value = partial(get_param_value, item=item, module=module)
item.update({
'password': get_value('password'),
'configured_password': get_value('configured_password'),
'sshkey': get_value('sshkey'),
'roles': get_value('roles'),
'state': get_value('state')
@ -302,7 +309,7 @@ def main():
aggregate=dict(type='list', no_log=True, aliases=['collection', 'users']),
name=dict(),
password=dict(no_log=True),
configured_password=dict(no_log=True),
update_password=dict(default='always', choices=['on_create', 'always']),
roles=dict(type='list', aliases=['role']),
@ -325,6 +332,12 @@ def main():
result = {'changed': False}
warnings = list()
if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
check_args(module, warnings)
result['warnings'] = warnings

@ -37,7 +37,7 @@ options:
This argument accepts a string value and is mutually exclusive
with the C(aggregate) argument.
Please note that this option is not same as C(provider username).
password:
configured_password:
description:
- The password to be configured on the remote network device. The
password needs to be provided in clear and it will be encrypted

@ -53,7 +53,7 @@ options:
- The C(full_name) argument provides the full name of the user
account to be created on the remote device. This argument accepts
any text string value.
password:
configured_password:
description:
- The password to be configured on the VyOS device. The
password needs to be provided in clear and it will be encrypted
@ -95,7 +95,7 @@ EXAMPLES = """
- name: create a new user
vyos_user:
name: ansible
password: password
configured_password: password
state: present
- name: remove all users except admin
vyos_user:
@ -110,7 +110,7 @@ EXAMPLES = """
- name: Change Password for User netop
vyos_user:
name: netop
password: "{{ new_password }}"
configured_password: "{{ new_password }}"
update_password: always
state: present
"""
@ -166,9 +166,9 @@ def spec_to_commands(updates, module):
if needs_update(want, have, 'full_name'):
add(commands, want, "full-name %s" % want['full_name'])
if needs_update(want, have, 'password'):
if needs_update(want, have, 'configured_password'):
if update_password == 'always' or not have:
add(commands, want, 'authentication plaintext-password %s' % want['password'])
add(commands, want, 'authentication plaintext-password %s' % want['configured_password'])
return commands
@ -203,7 +203,7 @@ def config_to_dict(module):
obj = {
'name': user,
'state': 'present',
'password': None,
'configured_password': None,
'level': parse_level(cfg),
'full_name': parse_full_name(cfg)
}
@ -231,20 +231,20 @@ def map_params_to_obj(module):
if not module.params['name'] and module.params['purge']:
return list()
else:
aggregatelist = [{'name': module.params['name']}]
users = [{'name': module.params['name']}]
else:
aggregatelist = list()
users = list()
for item in aggregate:
if not isinstance(item, dict):
aggregatelist.append({'name': item})
users.append({'name': item})
else:
aggregatelist.append(item)
users.append(item)
objects = list()
for item in aggregatelist:
for item in users:
get_value = partial(get_param_value, item=item, module=module)
item['password'] = get_value('password')
item['configured_password'] = get_value('configured_password')
item['full_name'] = get_value('full_name')
item['level'] = get_value('level')
item['state'] = get_value('state')
@ -275,7 +275,7 @@ def main():
full_name=dict(),
level=dict(aliases=['role']),
password=dict(no_log=True),
configured_password=dict(no_log=True),
update_password=dict(default='always', choices=['on_create', 'always']),
purge=dict(type='bool', default=False),
@ -301,6 +301,12 @@ def main():
supports_check_mode=True)
warnings = list()
if module.params['password'] and not module.params['configured_password']:
warnings.append(
'The "password" argument is used to authenticate the current connection. ' +
'To set a user password use "configured_password" instead.'
)
check_args(module, warnings)
result = {'changed': False}

@ -0,0 +1,39 @@
---
- block:
- name: Create user with password
eos_user:
name: auth_user
privilege: 15
role: network-operator
state: present
authorize: yes
provider: "{{ cli }}"
configured_password: pass123
- name: test login
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "pass123"
- name: test login with invalid password (should fail)
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "badpass"
ignore_errors: yes
register: results
- name: check that attempt failed
assert:
that:
- results.failed
always:
- name: delete user
eos_user:
name: auth_user
state: absent
provider: "{{ cli }}"
authorize: yes
register: result

@ -0,0 +1,39 @@
---
- block:
- name: Create user with password
ios_user:
name: auth_user
privilege: 15
role: network-operator
state: present
authorize: yes
provider: "{{ cli }}"
configured_password: pass123
- name: test login
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "pass123"
- name: test login with invalid password (should fail)
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "badpass"
ignore_errors: yes
register: results
- name: check that attempt failed
assert:
that:
- results.failed
always:
- name: delete user
ios_user:
name: auth_user
state: absent
provider: "{{ cli }}"
authorize: yes
register: result

@ -0,0 +1,35 @@
---
- block:
- name: Create user with password
iosxr_user:
name: auth_user
state: present
provider: "{{ cli }}"
configured_password: pass123
- name: test login
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "pass123"
- name: test login with invalid password (should fail)
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "badpass"
ignore_errors: yes
register: results
- name: check that attempt failed
assert:
that:
- results.failed
always:
- name: delete user
iosxr_user:
name: auth_user
state: absent
provider: "{{ cli }}"
register: result

@ -10,7 +10,7 @@
- name: Create user (SetUp)
iosxr_user:
name: ansibletest1
password: test
configured_password: test
state: present
provider: "{{ cli }}"
register: result
@ -24,7 +24,7 @@
- name: Create user with update_password always (not idempotent)
iosxr_user:
name: ansibletest1
password: test
configured_password: test
update_password: always
state: present
provider: "{{ cli }}"
@ -39,7 +39,7 @@
- name: Create user again with update_password on_create (idempotent)
iosxr_user:
name: ansibletest1
password: test
configured_password: test
update_password: on_create
state: present
provider: "{{ cli }}"
@ -53,7 +53,7 @@
- name: Modify user group
iosxr_user:
name: ansibletest1
password: test
configured_password: test
update_password: on_create
group: sysadmin
state: present
@ -69,7 +69,7 @@
- name: Modify user group again (idempotent)
iosxr_user:
name: ansibletest1
password: test
configured_password: test
update_password: on_create
group: sysadmin
state: present
@ -86,7 +86,7 @@
aggregate:
- name: ansibletest2
- name: ansibletest3
password: test
configured_password: test
state: present
group: sysadmin
provider: "{{ cli }}"
@ -107,7 +107,7 @@
aggregate:
- name: ansibletest2
- name: ansibletest3
password: test
configured_password: test
state: present
group: sysadmin
provider: "{{ cli }}"
@ -126,7 +126,7 @@
aggregate:
- name: ansibletest2
- name: ansibletest3
password: test
configured_password: test
update_password: on_create
state: present
group: sysadmin

@ -0,0 +1,36 @@
---
- block:
- name: Create user with password
nxos_user:
name: auth_user
role: network-operator
state: present
provider: "{{ cli }}"
configured_password: pass123
- name: test login
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "pass123"
- name: test login with invalid password (should fail)
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "badpass"
ignore_errors: yes
register: results
- name: check that attempt failed
assert:
that:
- results.failed
always:
- name: delete user
nxos_user:
name: auth_user
state: absent
provider: "{{ cli }}"
register: result

@ -0,0 +1,36 @@
---
- block:
- name: Create user with password
nxos_user:
name: auth_user
role: network-operator
state: present
provider: "{{ nxapi }}"
configured_password: pass123
- name: test login
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "pass123"
- name: test login with invalid password (shoul fail)
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no show version"
responses:
(?i)password: "badpass"
ignore_errors: yes
register: results
- name: check that attempt failed
assert:
that:
- results.failed
always:
- name: delete user
nxos_user:
name: auth_user
state: absent
provider: "{{ nxapi }}"
register: result

@ -0,0 +1,36 @@
---
- block:
- name: Create user with password
vyos_user:
name: auth_user
role: admin
state: present
provider: "{{ cli }}"
configured_password: pass123
- name: test login
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper show version'"
responses:
(?i)password: "pass123"
- name: test login with invalid password (should fail)
expect:
command: "ssh auth_user@{{ inventory_hostname }} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no '/opt/vyatta/sbin/vyatta-cfg-cmd-wrapper show version'"
responses:
(?i)password: "badpass"
ignore_errors: yes
register: results
- name: check that attempt failed
assert:
that:
- results.failed
always:
- name: delete user
vyos_user:
name: auth_user
state: absent
provider: "{{ cli }}"
register: result

@ -10,7 +10,7 @@
- name: Create user
vyos_user:
name: ansibletest1
password: test
configured_password: test
state: present
provider: "{{ cli }}"
register: result
@ -39,7 +39,7 @@
- name: Add user again (Idempotent)
vyos_user:
name: ansibletest1
password: test
configured_password: test
state: present
update_password: on_create
provider: "{{ cli }}"

@ -54,7 +54,7 @@ class TestEosUserModule(TestEosModule):
self.execute_module(changed=True, commands=commands)
def test_eos_user_password(self):
set_module_args(dict(name='ansible', password='test'))
set_module_args(dict(name='ansible', configured_password='test'))
commands = ['username ansible secret test']
self.execute_module(changed=True, commands=commands)
@ -83,15 +83,15 @@ class TestEosUserModule(TestEosModule):
self.execute_module(changed=True, commands=commands)
def test_eos_user_update_password_changed(self):
set_module_args(dict(name='test', password='test', update_password='on_create'))
set_module_args(dict(name='test', configured_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(name='ansible', password='test', update_password='on_create'))
set_module_args(dict(name='ansible', configured_password='test', update_password='on_create'))
self.execute_module()
def test_eos_user_update_password_always(self):
set_module_args(dict(name='ansible', password='test', update_password='always'))
set_module_args(dict(name='ansible', configured_password='test', update_password='always'))
commands = ['username ansible secret test']
self.execute_module(changed=True, commands=commands)

@ -66,7 +66,7 @@ class TestIosUserModule(TestIosModule):
self.assertEqual(result_cmd, [cmd])
def test_ios_user_password(self):
set_module_args(dict(name='ansible', password='test'))
set_module_args(dict(name='ansible', configured_password='test'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['username ansible secret test'])
@ -100,15 +100,15 @@ class TestIosUserModule(TestIosModule):
self.assertEqual(result['commands'], ['username ansible view test'])
def test_ios_user_update_password_changed(self):
set_module_args(dict(name='test', password='test', update_password='on_create'))
set_module_args(dict(name='test', configured_password='test', update_password='on_create'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['username test secret test'])
def test_ios_user_update_password_on_create_ok(self):
set_module_args(dict(name='ansible', password='test', update_password='on_create'))
set_module_args(dict(name='ansible', configured_password='test', update_password='on_create'))
self.execute_module()
def test_ios_user_update_password_always(self):
set_module_args(dict(name='ansible', password='test', update_password='always'))
set_module_args(dict(name='ansible', configured_password='test', update_password='always'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['username ansible secret test'])

@ -51,7 +51,7 @@ class TestIosxrUserModule(TestIosxrModule):
self.assertEqual(result['commands'], ['no username ansible'])
def test_iosxr_user_password(self):
set_module_args(dict(name='ansible', password='test'))
set_module_args(dict(name='ansible', configured_password='test'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['username ansible secret test'])
@ -66,16 +66,16 @@ class TestIosxrUserModule(TestIosxrModule):
self.assertEqual(result['commands'], ['username ansible group sysadmin'])
def test_iosxr_user_update_password_changed(self):
set_module_args(dict(name='test', password='test', update_password='on_create'))
set_module_args(dict(name='test', configured_password='test', update_password='on_create'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'],
['username test', 'username test secret test'])
def test_iosxr_user_update_password_on_create_ok(self):
set_module_args(dict(name='ansible', password='test', update_password='on_create'))
set_module_args(dict(name='ansible', configured_password='test', update_password='on_create'))
self.execute_module()
def test_iosxr_user_update_password_always(self):
set_module_args(dict(name='ansible', password='test', update_password='always'))
set_module_args(dict(name='ansible', configured_password='test', update_password='always'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['username ansible secret test'])

@ -46,7 +46,7 @@ class TestVyosUserModule(TestVyosModule):
self.load_config.return_value = dict(diff=None, session='session')
def test_vyos_user_password(self):
set_module_args(dict(name='ansible', password='test'))
set_module_args(dict(name='ansible', configured_password='test'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['set system login user ansible authentication plaintext-password test'])
@ -71,15 +71,15 @@ class TestVyosUserModule(TestVyosModule):
'delete system login user admin']))
def test_vyos_user_update_password_changed(self):
set_module_args(dict(name='test', password='test', update_password='on_create'))
set_module_args(dict(name='test', configured_password='test', update_password='on_create'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['set system login user test authentication plaintext-password test'])
def test_vyos_user_update_password_on_create_ok(self):
set_module_args(dict(name='ansible', password='test', update_password='on_create'))
set_module_args(dict(name='ansible', configured_password='test', update_password='on_create'))
self.execute_module()
def test_vyos_user_update_password_always(self):
set_module_args(dict(name='ansible', password='test', update_password='always'))
set_module_args(dict(name='ansible', configured_password='test', update_password='always'))
result = self.execute_module(changed=True)
self.assertEqual(result['commands'], ['set system login user ansible authentication plaintext-password test'])

Loading…
Cancel
Save