Deprecate Entity, EntityCollection and use subspec in network modules (#33575)

* Deprecate Entity, EntityCollection and use subspec in network modules

*  As per proposal https://github.com/ansible/proposals/issues/76
   deprecate use of Entity, EntityCollection, ComplexDict, ComplexList
   and use subspec instead.
*  Refactor ios modules
*  Refactor eos modules
*  Refactor vyos modules
*  Refactor nxos modules
*  Refactor iosxr modules
*  Add support for key in suboptions handling

* Fix CI issues
pull/32423/merge
Ganesh Nalawade 7 years ago committed by GitHub
parent a23da23491
commit 4349b56643
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1929,14 +1929,23 @@ class AnsibleModule(object):
self._options_context.append(k) self._options_context.append(k)
key = None
for (name, value) in spec.items():
# specifies how to map a single value to spec
if value.get('key'):
key = name
break
if isinstance(params[k], dict): if isinstance(params[k], dict):
elements = [params[k]] elements = [params[k]]
else: else:
elements = params[k] elements = params[k]
for param in elements: for index, param in enumerate(elements):
if not isinstance(param, dict): if not isinstance(param, dict):
self.fail_json(msg="value of %s must be of type dict or list of dict" % k) if key is None:
self.fail_json(msg="options spec require a key argument to map it to a single value '%s'" % param)
elements[index] = param = {key: param}
self._set_fallbacks(spec, param) self._set_fallbacks(spec, param)
options_aliases = self._handle_aliases(spec, param) options_aliases = self._handle_aliases(spec, param)

@ -65,6 +65,10 @@ def sort_list(val):
class Entity(object): class Entity(object):
"""Transforms a dict to with an argument spec """Transforms a dict to with an argument spec
This class has been deprecated as of Ansible 2.5 and will be
removed from the code in future release.
Please use the suboptions in module argument spec instead.
This class will take a dict and apply an Ansible argument spec to the This class will take a dict and apply an Ansible argument spec to the
values. The resulting dict will contain all of the keys in the param values. The resulting dict will contain all of the keys in the param
with appropriate values set. with appropriate values set.
@ -183,7 +187,12 @@ class Entity(object):
class EntityCollection(Entity): class EntityCollection(Entity):
"""Extends ```Entity``` to handle a list of dicts """ """Extends ```Entity``` to handle a list of dicts
This class has been deprecated as of Ansible 2.5 and will be
removed from the code in future release.
Please use the suboptions in module argument spec instead.
"""
def __call__(self, iterable, strict=True): def __call__(self, iterable, strict=True):
if iterable is None: if iterable is None:
@ -198,11 +207,21 @@ class EntityCollection(Entity):
# these two are for backwards compatibility and can be removed once all of the # these two are for backwards compatibility and can be removed once all of the
# modules that use them are updated # modules that use them are updated
class ComplexDict(Entity): class ComplexDict(Entity):
"""
This class has been deprecated as of Ansible 2.5 and will be
removed from the code in future release.
Please use the suboptions in module argument spec instead.
"""
def __init__(self, attrs, module, *args, **kwargs): def __init__(self, attrs, module, *args, **kwargs):
super(ComplexDict, self).__init__(module, attrs, *args, **kwargs) super(ComplexDict, self).__init__(module, attrs, *args, **kwargs)
class ComplexList(EntityCollection): class ComplexList(EntityCollection):
"""
This class has been deprecated as of Ansible 2.5 and will be
removed from the code in future release.
Please use the suboptions in module argument spec instead.
"""
def __init__(self, attrs, module, *args, **kwargs): def __init__(self, attrs, module, *args, **kwargs):
super(ComplexList, self).__init__(module, attrs, *args, **kwargs) super(ComplexList, self).__init__(module, attrs, *args, **kwargs)

@ -33,8 +33,8 @@ import time
from ansible.module_utils._text import to_text, to_native from ansible.module_utils._text import to_text, to_native
from ansible.module_utils.basic import env_fallback, return_values from ansible.module_utils.basic import env_fallback, return_values
from ansible.module_utils.connection import exec_command from ansible.module_utils.connection import exec_command
from ansible.module_utils.network.common.utils import to_list, ComplexList from ansible.module_utils.network.common.utils import to_list
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems, string_types
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
_DEVICE_CONNECTION = None _DEVICE_CONNECTION = None
@ -150,7 +150,6 @@ class Cli:
"""Run list of commands on remote device and return results """Run list of commands on remote device and return results
""" """
responses = list() responses = list()
for cmd in to_list(commands): for cmd in to_list(commands):
rc, out, err = self.exec_command(cmd) rc, out, err = self.exec_command(cmd)
out = to_text(out, errors='surrogate_then_replace') out = to_text(out, errors='surrogate_then_replace')
@ -429,22 +428,6 @@ def is_eapi(module):
return 'eapi' in (transport, provider_transport) return 'eapi' in (transport, provider_transport)
def to_command(module, commands):
if is_eapi(module):
default_output = 'json'
else:
default_output = 'text'
transform = ComplexList(dict(
command=dict(key=True),
output=dict(default=default_output),
prompt=dict(),
answer=dict()
), module)
return transform(to_list(commands))
def get_config(module, flags=None): def get_config(module, flags=None):
flags = None if flags is None else flags flags = None if flags is None else flags
@ -454,7 +437,15 @@ def get_config(module, flags=None):
def run_commands(module, commands): def run_commands(module, commands):
conn = get_connection(module) conn = get_connection(module)
return conn.run_commands(to_command(module, commands)) if is_eapi(module):
default_output = 'json'
else:
default_output = 'text'
for index, cmd in enumerate(to_list(commands)):
if isinstance(cmd, string_types):
commands[index] = {'command': cmd, 'output': default_output}
return conn.run_commands(to_list(commands))
def load_config(module, config, commit=False, replace=False): def load_config(module, config, commit=False, replace=False):

@ -27,8 +27,9 @@
# #
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
from ansible.module_utils.basic import env_fallback, return_values from ansible.module_utils.basic import env_fallback, return_values
from ansible.module_utils.network.common.utils import to_list, ComplexList
from ansible.module_utils.connection import exec_command from ansible.module_utils.connection import exec_command
from ansible.module_utils.network.common.utils import to_list
from ansible.module_utils.six import string_types
_DEVICE_CONFIGS = {} _DEVICE_CONFIGS = {}
@ -100,20 +101,12 @@ def get_config(module, flags=None):
return cfg return cfg
def to_commands(module, commands):
spec = {
'command': dict(key=True),
'prompt': dict(),
'answer': dict()
}
transform = ComplexList(spec, module)
return transform(commands)
def run_commands(module, commands, check_rc=True): def run_commands(module, commands, check_rc=True):
responses = list() responses = list()
commands = to_commands(module, to_list(commands)) for cmd in to_list(commands):
for cmd in commands: if isinstance(cmd, string_types):
cmd = {'command': cmd}
cmd = module.jsonify(cmd) cmd = module.jsonify(cmd)
rc, out, err = exec_command(module, cmd) rc, out, err = exec_command(module, cmd)
if check_rc and rc != 0: if check_rc and rc != 0:

@ -79,12 +79,6 @@ iosxr_argument_spec = {
'provider': dict(type='dict', options=iosxr_provider_spec) 'provider': dict(type='dict', options=iosxr_provider_spec)
} }
command_spec = {
'command': dict(),
'prompt': dict(default=None),
'answer': dict(default=None)
}
iosxr_top_spec = { iosxr_top_spec = {
'host': dict(removed_in_version=2.9), 'host': dict(removed_in_version=2.9),
'port': dict(removed_in_version=2.9, type='int'), 'port': dict(removed_in_version=2.9, type='int'),

@ -32,7 +32,7 @@ import collections
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
from ansible.module_utils.basic import env_fallback, return_values from ansible.module_utils.basic import env_fallback, return_values
from ansible.module_utils.network.common.utils import to_list, ComplexList from ansible.module_utils.network.common.utils import to_list
from ansible.module_utils.connection import exec_command from ansible.module_utils.connection import exec_command
from ansible.module_utils.six import iteritems, string_types from ansible.module_utils.six import iteritems, string_types
from ansible.module_utils.urls import fetch_url from ansible.module_utils.urls import fetch_url
@ -399,28 +399,6 @@ def is_nxapi(module):
return 'nxapi' in (transport, provider_transport) return 'nxapi' in (transport, provider_transport)
def to_command(module, commands):
if is_nxapi(module):
default_output = 'json'
else:
default_output = 'text'
transform = ComplexList(dict(
command=dict(key=True),
output=dict(default=default_output),
prompt=dict(),
answer=dict()
), module)
commands = transform(to_list(commands))
for item in commands:
if is_json(item['command']):
item['output'] = 'json'
return commands
def get_config(module, flags=None): def get_config(module, flags=None):
flags = [] if flags is None else flags flags = [] if flags is None else flags
@ -430,7 +408,20 @@ def get_config(module, flags=None):
def run_commands(module, commands, check_rc=True): def run_commands(module, commands, check_rc=True):
conn = get_connection(module) conn = get_connection(module)
return conn.run_commands(to_command(module, commands), check_rc)
if is_nxapi(module):
default_output = 'json'
else:
default_output = 'text'
for index, cmd in enumerate(to_list(commands)):
if isinstance(cmd, string_types):
commands[index] = cmd = {'command': cmd, 'output': default_output}
if is_json(cmd['command']):
cmd['output'] = 'json'
return conn.run_commands(to_list(commands), check_rc)
def load_config(module, config, return_error=False, opts=None): def load_config(module, config, return_error=False, opts=None):

@ -140,9 +140,8 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.pycompat24 import get_exception from ansible.module_utils.pycompat24 import get_exception
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils.network.common.parsing import Conditional from ansible.module_utils.network.common.parsing import Conditional
from ansible.module_utils.network.common.utils import ComplexList
from ansible.module_utils.network.eos.eos import run_commands from ansible.module_utils.network.eos.eos import run_commands
from ansible.module_utils.network.eos.eos import eos_argument_spec, check_args from ansible.module_utils.network.eos.eos import eos_argument_spec
VALID_KEYS = ['command', 'output', 'prompt', 'response'] VALID_KEYS = ['command', 'output', 'prompt', 'response']
@ -157,16 +156,7 @@ def to_lines(stdout):
def parse_commands(module, warnings): def parse_commands(module, warnings):
spec = dict( commands = module.params['commands']
command=dict(key=True),
output=dict(),
prompt=dict(),
answer=dict()
)
transform = ComplexList(spec, module)
commands = transform(module.params['commands'])
if module.check_mode: if module.check_mode:
for item in list(commands): for item in list(commands):
if not item['command'].startswith('show'): if not item['command'].startswith('show'):
@ -189,8 +179,15 @@ def to_cli(obj):
def main(): def main():
"""entry point for module execution """entry point for module execution
""" """
command_spec = dict(
command=dict(key=True),
output=dict(),
prompt=dict(),
answer=dict()
)
argument_spec = dict( argument_spec = dict(
commands=dict(type='list', required=True), commands=dict(type='list', elements='dict', options=command_spec, required=True),
wait_for=dict(type='list', aliases=['waitfor']), wait_for=dict(type='list', aliases=['waitfor']),
match=dict(default='all', choices=['all', 'any']), match=dict(default='all', choices=['all', 'any']),
@ -207,7 +204,6 @@ def main():
result = {'changed': False} result = {'changed': False}
warnings = list() warnings = list()
check_args(module, warnings)
commands = parse_commands(module, warnings) commands = parse_commands(module, warnings)
if warnings: if warnings:
result['warnings'] = warnings result['warnings'] = warnings

@ -129,7 +129,6 @@ session_name:
import re import re
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.common.utils import ComplexList
from ansible.module_utils.network.eos.eos import load_config, get_config from ansible.module_utils.network.eos.eos import load_config, get_config
from ansible.module_utils.network.eos.eos import eos_argument_spec from ansible.module_utils.network.eos.eos import eos_argument_spec
@ -270,31 +269,27 @@ def map_params_to_obj(module):
obj = { obj = {
'hostname': module.params['hostname'], 'hostname': module.params['hostname'],
'domain_name': module.params['domain_name'], 'domain_name': module.params['domain_name'],
'domain_list': module.params['domain_list'] 'domain_list': module.params['domain_list'],
'lookup_source': module.params['lookup_source'],
'name_servers': module.params['name_servers'],
} }
lookup_source = ComplexList(dict(
interface=dict(key=True),
vrf=dict()
), module)
name_servers = ComplexList(dict(
server=dict(key=True),
vrf=dict(default='default')
), module)
for arg, cast in [('lookup_source', lookup_source), ('name_servers', name_servers)]:
if module.params[arg] is not None:
obj[arg] = cast(module.params[arg])
else:
obj[arg] = None
return obj return obj
def main(): def main():
""" main entry point for module execution """ main entry point for module execution
""" """
lookup_source_spec = dict(
interface=dict(key=True),
vrf=dict()
)
name_servers_spec = dict(
server=dict(key=True),
vrf=dict()
)
argument_spec = dict( argument_spec = dict(
hostname=dict(), hostname=dict(),
@ -302,10 +297,10 @@ def main():
domain_list=dict(type='list', aliases=['domain_search']), domain_list=dict(type='list', aliases=['domain_search']),
# { interface: <str>, vrf: <str> } # { interface: <str>, vrf: <str> }
lookup_source=dict(type='list'), lookup_source=dict(type='list', elements='dict', options=lookup_source_spec),
# { server: <str>; vrf: <str> } # { server: <str>; vrf: <str> }
name_servers=dict(type='list'), name_servers=dict(type='list', elements='dict', options=name_servers_spec),
state=dict(default='present', choices=['present', 'absent']) state=dict(default='present', choices=['present', 'absent'])
) )
@ -333,5 +328,6 @@ def main():
module.exit_json(**result) module.exit_json(**result)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

@ -134,9 +134,8 @@ failed_conditions:
import time import time
from ansible.module_utils.network.ios.ios import run_commands from ansible.module_utils.network.ios.ios import run_commands
from ansible.module_utils.network.ios.ios import ios_argument_spec, check_args from ansible.module_utils.network.ios.ios import ios_argument_spec
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.common.utils import ComplexList
from ansible.module_utils.network.common.parsing import Conditional from ansible.module_utils.network.common.parsing import Conditional
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
@ -149,13 +148,8 @@ def to_lines(stdout):
def parse_commands(module, warnings): def parse_commands(module, warnings):
command = ComplexList(dict( commands = module.params['commands']
command=dict(key=True), for item in commands:
prompt=dict(),
answer=dict()
), module)
commands = command(module.params['commands'])
for item in list(commands):
if module.check_mode and not item['command'].startswith('show'): if module.check_mode and not item['command'].startswith('show'):
warnings.append( warnings.append(
'only show commands are supported when using check mode, not ' 'only show commands are supported when using check mode, not '
@ -173,8 +167,14 @@ def parse_commands(module, warnings):
def main(): def main():
"""main entry point for module execution """main entry point for module execution
""" """
command_spec = dict(
command=dict(key=True),
prompt=dict(),
answer=dict()
)
argument_spec = dict( argument_spec = dict(
commands=dict(type='list', required=True), commands=dict(type='list', elements='dict', options=command_spec, required=True),
wait_for=dict(type='list', aliases=['waitfor']), wait_for=dict(type='list', aliases=['waitfor']),
match=dict(default='all', choices=['all', 'any']), match=dict(default='all', choices=['all', 'any']),
@ -191,7 +191,6 @@ def main():
result = {'changed': False} result = {'changed': False}
warnings = list() warnings = list()
check_args(module, warnings)
commands = parse_commands(module, warnings) commands = parse_commands(module, warnings)
result['warnings'] = warnings result['warnings'] = warnings

@ -120,8 +120,7 @@ import re
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
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.network.ios.ios import ios_argument_spec, check_args from ansible.module_utils.network.ios.ios import ios_argument_spec
from ansible.module_utils.network.common.utils import ComplexList
_CONFIGURED_VRFS = None _CONFIGURED_VRFS = None
@ -307,44 +306,43 @@ def map_params_to_obj(module):
'hostname': module.params['hostname'], 'hostname': module.params['hostname'],
'lookup_source': module.params['lookup_source'], 'lookup_source': module.params['lookup_source'],
'lookup_enabled': module.params['lookup_enabled'], 'lookup_enabled': module.params['lookup_enabled'],
'domain_name': module.params['domain_name'],
'domain_search': module.params['domain_search'],
'name_servers': module.params['name_servers']
} }
domain_name = ComplexList(dict( return obj
def main():
""" Main entry point for Ansible module execution
"""
domain_name_spec = dict(
name=dict(key=True), name=dict(key=True),
vrf=dict() vrf=dict()
), module) )
domain_search = ComplexList(dict( domain_search_spec = dict(
name=dict(key=True), name=dict(key=True),
vrf=dict() vrf=dict()
), module) )
name_servers = ComplexList(dict( name_servers_spec = dict(
server=dict(key=True), server=dict(key=True),
vrf=dict() vrf=dict()
), module) )
for arg, cast in [('domain_name', domain_name),
('domain_search', domain_search),
('name_servers', name_servers)]:
if module.params[arg]:
obj[arg] = cast(module.params[arg])
else:
obj[arg] = None
return obj
def main():
""" Main entry point for Ansible module execution
"""
argument_spec = dict( argument_spec = dict(
hostname=dict(), hostname=dict(),
domain_name=dict(type='list'), # { name: <str>, vrf: <str> }
domain_search=dict(type='list'), domain_name=dict(type='list', elements='dict', options=domain_name_spec),
name_servers=dict(type='list'),
# {name: <str>, vrf: <str> }
domain_search=dict(type='list', elements='dict', options=domain_search_spec),
# { server: <str>; vrf: <str> }
name_servers=dict(type='list', elements='dict', options=name_servers_spec),
lookup_source=dict(), lookup_source=dict(),
lookup_enabled=dict(type='bool'), lookup_enabled=dict(type='bool'),
@ -360,7 +358,6 @@ def main():
result = {'changed': False} result = {'changed': False}
warnings = list() warnings = list()
check_args(module, warnings)
result['warnings'] = warnings result['warnings'] = warnings
want = map_params_to_obj(module) want = map_params_to_obj(module)
@ -376,5 +373,6 @@ def main():
module.exit_json(**result) module.exit_json(**result)
if __name__ == "__main__": if __name__ == "__main__":
main() main()

@ -127,8 +127,8 @@ import time
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.iosxr.iosxr import run_command, iosxr_argument_spec from ansible.module_utils.network.iosxr.iosxr import run_command, iosxr_argument_spec
from ansible.module_utils.network.iosxr.iosxr import command_spec
from ansible.module_utils.network.common.parsing import Conditional from ansible.module_utils.network.common.parsing import Conditional
from ansible.module_utils.network.common.utils import to_list
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
@ -142,11 +142,8 @@ def to_lines(stdout):
def parse_commands(module, warnings): def parse_commands(module, warnings):
commands = module.params['commands'] commands = module.params['commands']
for item in list(commands): for item in to_list(commands):
try:
command = item['command'] command = item['command']
except Exception:
command = item
if module.check_mode and not command.startswith('show'): if module.check_mode and not command.startswith('show'):
warnings.append( warnings.append(
'only show commands are supported when using check mode, not ' 'only show commands are supported when using check mode, not '
@ -163,8 +160,14 @@ def parse_commands(module, warnings):
def main(): def main():
command_spec = dict(
command=dict(key=True),
prompt=dict(),
answer=dict()
)
spec = dict( spec = dict(
commands=dict(type='list', required=True), commands=dict(type='list', elements='dict', options=command_spec, required=True),
wait_for=dict(type='list', aliases=['waitfor']), wait_for=dict(type='list', aliases=['waitfor']),
match=dict(default='all', choices=['all', 'any']), match=dict(default='all', choices=['all', 'any']),
@ -175,13 +178,10 @@ def main():
spec.update(iosxr_argument_spec) spec.update(iosxr_argument_spec)
spec.update(command_spec)
module = AnsibleModule(argument_spec=spec, module = AnsibleModule(argument_spec=spec,
supports_check_mode=True) supports_check_mode=True)
warnings = list() warnings = list()
commands = parse_commands(module, warnings) commands = parse_commands(module, warnings)
wait_for = module.params['wait_for'] or list() wait_for = module.params['wait_for'] or list()

@ -147,8 +147,7 @@ import time
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.common.parsing import Conditional, FailedConditionalError from ansible.module_utils.network.common.parsing import Conditional, FailedConditionalError
from ansible.module_utils.network.common.utils import ComplexList from ansible.module_utils.network.nxos.nxos import nxos_argument_spec, run_commands
from ansible.module_utils.network.nxos.nxos import check_args, nxos_argument_spec, run_commands
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_native from ansible.module_utils._text import to_native
@ -163,14 +162,7 @@ def to_lines(stdout):
def parse_commands(module, warnings): def parse_commands(module, warnings):
transform = ComplexList(dict( commands = module.params['commands']
command=dict(key=True),
output=dict(),
prompt=dict(),
answer=dict()
), module)
commands = transform(module.params['commands'])
if module.check_mode: if module.check_mode:
for item in list(commands): for item in list(commands):
@ -194,9 +186,16 @@ def to_cli(obj):
def main(): def main():
"""entry point for module execution """entry point for module execution
""" """
command_spec = dict(
command=dict(key=True),
output=dict(),
prompt=dict(),
answer=dict()
)
argument_spec = dict( argument_spec = dict(
# { command: <str>, output: <str>, prompt: <str>, response: <str> } # { command: <str>, output: <str>, prompt: <str>, response: <str> }
commands=dict(type='list', required=True), commands=dict(type='list', elements='dict', options=command_spec, required=True),
wait_for=dict(type='list', aliases=['waitfor']), wait_for=dict(type='list', aliases=['waitfor']),
match=dict(default='all', choices=['any', 'all']), match=dict(default='all', choices=['any', 'all']),
@ -213,7 +212,6 @@ def main():
result = {'changed': False} result = {'changed': False}
warnings = list() warnings = list()
check_args(module, warnings)
commands = parse_commands(module, warnings) commands = parse_commands(module, warnings)
result['warnings'] = warnings result['warnings'] = warnings

@ -112,11 +112,10 @@ commands:
import re import re
from ansible.module_utils.network.nxos.nxos import get_config, load_config from ansible.module_utils.network.nxos.nxos import get_config, load_config
from ansible.module_utils.network.nxos.nxos import nxos_argument_spec, check_args from ansible.module_utils.network.nxos.nxos import nxos_argument_spec
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six import iteritems from ansible.module_utils.six import iteritems
from ansible.module_utils.network.common.config import NetworkConfig from ansible.module_utils.network.common.config import NetworkConfig
from ansible.module_utils.network.common.utils import ComplexList
_CONFIGURED_VRFS = None _CONFIGURED_VRFS = None
@ -302,49 +301,45 @@ def map_params_to_obj(module):
obj = { obj = {
'hostname': module.params['hostname'], 'hostname': module.params['hostname'],
'domain_lookup': module.params['domain_lookup'], 'domain_lookup': module.params['domain_lookup'],
'system_mtu': module.params['system_mtu'] 'system_mtu': module.params['system_mtu'],
'domain_name': module.params['domain_name'],
'domain_search': module.params['domain_search'],
'name_servers': module.params['name_servers']
} }
domain_name = ComplexList(dict( return obj
def main():
""" main entry point for module execution
"""
domain_name_spec = dict(
name=dict(key=True), name=dict(key=True),
vrf=dict() vrf=dict()
), module) )
domain_search = ComplexList(dict( domain_search_spec = dict(
name=dict(key=True), name=dict(key=True),
vrf=dict() vrf=dict()
), module) )
name_servers = ComplexList(dict( name_servers_spec = dict(
server=dict(key=True), server=dict(key=True),
vrf=dict() vrf=dict()
), module) )
for arg, cast in [('domain_name', domain_name), ('domain_search', domain_search),
('name_servers', name_servers)]:
if module.params[arg] is not None:
obj[arg] = cast(module.params[arg])
else:
obj[arg] = None
return obj
def main():
""" main entry point for module execution
"""
argument_spec = dict( argument_spec = dict(
hostname=dict(), hostname=dict(),
domain_lookup=dict(type='bool'), domain_lookup=dict(type='bool'),
# { name: <str>, vrf: <str> } # { name: <str>, vrf: <str> }
domain_name=dict(type='list'), domain_name=dict(type='list', elements='dict', options=domain_name_spec),
# {name: <str>, vrf: <str> } # {name: <str>, vrf: <str> }
domain_search=dict(type='list'), domain_search=dict(type='list', elements='dict', options=domain_search_spec),
# { server: <str>; vrf: <str> } # { server: <str>; vrf: <str> }
name_servers=dict(type='list'), name_servers=dict(type='list', elements='dict', options=name_servers_spec),
system_mtu=dict(type='int'), system_mtu=dict(type='int'),
lookup_source=dict(), lookup_source=dict(),
@ -357,7 +352,6 @@ def main():
supports_check_mode=True) supports_check_mode=True)
warnings = list() warnings = list()
check_args(module, warnings)
result = {'changed': False} result = {'changed': False}
if warnings: if warnings:
@ -376,5 +370,6 @@ def main():
module.exit_json(**result) module.exit_json(**result)
if __name__ == '__main__': if __name__ == '__main__':
main() main()

@ -137,7 +137,6 @@ import time
from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.pycompat24 import get_exception from ansible.module_utils.pycompat24 import get_exception
from ansible.module_utils.network.common.parsing import Conditional from ansible.module_utils.network.common.parsing import Conditional
from ansible.module_utils.network.common.utils import ComplexList
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.module_utils.network.vyos.vyos import run_commands from ansible.module_utils.network.vyos.vyos import run_commands
from ansible.module_utils.network.vyos.vyos import vyos_argument_spec from ansible.module_utils.network.vyos.vyos import vyos_argument_spec
@ -151,12 +150,7 @@ def to_lines(stdout):
def parse_commands(module, warnings): def parse_commands(module, warnings):
command = ComplexList(dict( commands = module.params['commands']
command=dict(key=True),
prompt=dict(),
answer=dict(),
), module)
commands = command(module.params['commands'])
items = [] items = []
for item in commands: for item in commands:
@ -170,8 +164,15 @@ def parse_commands(module, warnings):
def main(): def main():
command_spec = dict(
command=dict(key=True),
prompt=dict(),
answer=dict()
)
spec = dict( spec = dict(
commands=dict(type='list', required=True), commands=dict(type='list', elements='dict', options=command_spec, required=True),
wait_for=dict(type='list', aliases=['waitfor']), wait_for=dict(type='list', aliases=['waitfor']),
match=dict(default='all', choices=['all', 'any']), match=dict(default='all', choices=['all', 'any']),

@ -575,6 +575,21 @@ class TestModuleUtilsBasic(ModuleTestCase):
supports_check_mode=True, supports_check_mode=True,
) )
# should test ok, handles key argument
key_spec = dict(foo=dict(key=True), bar=dict())
args = json.dumps(dict(ANSIBLE_MODULE_ARGS={'foobar': ['test-1', 'test-2']}))
with swap_stdin_and_argv(stdin_data=args):
basic._ANSIBLE_ARGS = None
am = basic.AnsibleModule(
argument_spec=dict(foobar=dict(type='list', elements='dict', options=key_spec, required=True)),
no_log=True,
check_invalid_arguments=False,
add_file_common_args=True,
supports_check_mode=True
)
self.assertEqual(am.params['foobar'][0]['foo'], 'test-1')
self.assertEqual(am.params['foobar'][1]['foo'], 'test-2')
def test_module_utils_basic_ansible_module_type_check(self): def test_module_utils_basic_ansible_module_type_check(self):
from ansible.module_utils import basic from ansible.module_utils import basic

Loading…
Cancel
Save