diff --git a/lib/ansible/modules/network/interface/net_interface.py b/lib/ansible/modules/network/interface/net_interface.py index 34fb6d5314..19592d8349 100644 --- a/lib/ansible/modules/network/interface/net_interface.py +++ b/lib/ansible/modules/network/interface/net_interface.py @@ -87,6 +87,24 @@ EXAMPLES = """ name: ge-0/0/1 description: test-interface enabled: False + +- name: Create interface using aggregate + net_interface: + aggregate: + - name: ge-0/0/1 + description: test-interface-1 + - name: ge-0/0/2 + description: test-interface-2 + speed: 1g + duplex: full + mtu: 512 + +- name: Delete interface using aggregate + junos_interface: + aggregate: + - name: ge-0/0/1 + - name: ge-0/0/2 + state: absent """ RETURN = """ diff --git a/lib/ansible/modules/network/interface/net_linkagg.py b/lib/ansible/modules/network/interface/net_linkagg.py index 52cc545cf6..007b58badd 100644 --- a/lib/ansible/modules/network/interface/net_linkagg.py +++ b/lib/ansible/modules/network/interface/net_linkagg.py @@ -70,6 +70,18 @@ EXAMPLES = """ name: bond0 state: absent +- name: Create aggregate of linkagg definitions + net_linkagg: + aggregate: + - { name: bond0, members: [eth1] } + - { name: bond1, members: [eth2] } + +- name: Remove aggregate of linkagg definitions + net_linkagg: + aggregate: + - name: bond0 + - name: bond1 + state: absent """ RETURN = """ diff --git a/lib/ansible/modules/network/interface/net_lldp_interface.py b/lib/ansible/modules/network/interface/net_lldp_interface.py index 5f27a8f68d..562eddf193 100644 --- a/lib/ansible/modules/network/interface/net_lldp_interface.py +++ b/lib/ansible/modules/network/interface/net_lldp_interface.py @@ -58,6 +58,20 @@ EXAMPLES = """ net_lldp_interface: name: eth1 state: absent + +- name: Create aggregate of LLDP interface configurations + net_lldp_interface: + aggregate: + - name: eth1 + - name: eth2 + state: present + +- name: Delete aggregate of LLDP interface configurations + net_lldp_interface: + aggregate: + - name: eth1 + - name: eth2 + state: absent """ RETURN = """ diff --git a/lib/ansible/modules/network/layer3/net_l3_interface.py b/lib/ansible/modules/network/layer3/net_l3_interface.py index 976a316bac..93e3fd7eae 100644 --- a/lib/ansible/modules/network/layer3/net_l3_interface.py +++ b/lib/ansible/modules/network/layer3/net_l3_interface.py @@ -55,6 +55,19 @@ EXAMPLES = """ net_l3_interface: name: eth0 state: absent + +- name: Set IP addresses on aggregate + net_l3_interface: + aggregate: + - { name: eth1, ipv4: 192.168.2.10/24 } + - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } + +- name: Remove IP addresses on aggregate + net_l3_interface: + aggregate: + - { name: eth1, ipv4: 192.168.2.10/24 } + - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } + state: absent """ RETURN = """ diff --git a/lib/ansible/modules/network/routing/net_static_route.py b/lib/ansible/modules/network/routing/net_static_route.py index 79924b6d1e..e6c32ac17a 100644 --- a/lib/ansible/modules/network/routing/net_static_route.py +++ b/lib/ansible/modules/network/routing/net_static_route.py @@ -70,6 +70,13 @@ EXAMPLES = """ aggregate: - { prefix: 192.168.2.0, mask 255.255.255.0, next_hop: 10.0.0.1 } - { prefix: 192.168.3.0, mask 255.255.255.0, next_hop: 10.0.2.1 } + +- name: Remove static route collections + net_static_route: + aggregate: + - { prefix: 172.24.1.0/24, next_hop: 192.168.42.64 } + - { prefix: 172.24.3.0/24, next_hop: 192.168.42.64 } + state: absent """ RETURN = """ diff --git a/lib/ansible/modules/network/system/net_user.py b/lib/ansible/modules/network/system/net_user.py index 96f601c8c9..9ba7c8872c 100644 --- a/lib/ansible/modules/network/system/net_user.py +++ b/lib/ansible/modules/network/system/net_user.py @@ -98,9 +98,11 @@ EXAMPLES = """ name: ansible sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" state: present + - name: remove all users except admin net_user: purge: yes + - name: set multiple users to privilege level 15 net_user: aggregate: @@ -108,6 +110,7 @@ EXAMPLES = """ - name: netend privilege: 15 state: present + - name: Change Password for User netop net_user: name: netop diff --git a/lib/ansible/modules/network/vyos/vyos_interface.py b/lib/ansible/modules/network/vyos/vyos_interface.py index 212346af0b..3a6d336de9 100644 --- a/lib/ansible/modules/network/vyos/vyos_interface.py +++ b/lib/ansible/modules/network/vyos/vyos_interface.py @@ -93,6 +93,26 @@ EXAMPLES = """ speed: 100 mtu: 256 duplex: full + +- name: Set interface using aggregate + vyos_interface: + aggregate: + - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512} + - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256} + +- name: Disable interface on aggregate + net_interface: + aggregate: + - name: eth1 + - name: eth2 + enabled: False + +- name: Delete interface using aggregate + net_interface: + aggregate: + - name: eth1 + - name: eth2 + state: absent """ RETURN = """ @@ -108,12 +128,13 @@ commands: """ import re +from copy import deepcopy from time import sleep from ansible.module_utils._text import to_text from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.connection import exec_command -from ansible.module_utils.network_common import conditional +from ansible.module_utils.network_common import conditional, remove_default_spec from ansible.module_utils.vyos import load_config, get_config from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -213,40 +234,19 @@ def map_config_to_obj(module): def map_params_to_obj(module): obj = [] - - params = ['speed', 'description', 'duplex', 'mtu'] aggregate = module.params.get('aggregate') - if aggregate: - for c in aggregate: - d = c.copy() - if 'name' not in d: - module.fail_json(msg="missing required arguments: %s" % 'name') - - for item in params: - if item not in d: - d[item] = None - - if d.get('description') is None: - d['description'] = DEFAULT_DESCRIPTION - - if not d.get('state'): - d['state'] = module.params['state'] - - if d.get('enabled') is None: - d['enabled'] = module.params['enabled'] + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module.params[key] + d = item.copy() if d['enabled']: d['disable'] = False else: d['disable'] = True - if d.get('delay') is None: - d['delay'] = module.params['delay'] - - if d.get('speed'): - d['speed'] = str(d['speed']) - obj.append(d) else: params = { @@ -300,7 +300,7 @@ def check_declarative_intent_params(module, want, result): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( name=dict(), description=dict(default=DEFAULT_DESCRIPTION), speed=dict(), @@ -308,11 +308,21 @@ def main(): duplex=dict(choices=['full', 'half', 'auto']), enabled=dict(default=True, type='bool'), delay=dict(default=10, type='int'), - aggregate=dict(type='list'), state=dict(default='present', choices=['present', 'absent', 'up', 'down']) ) + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec), + ) + + argument_spec.update(element_spec) argument_spec.update(vyos_argument_spec) required_one_of = [['name', 'aggregate']] diff --git a/lib/ansible/modules/network/vyos/vyos_l3_interface.py b/lib/ansible/modules/network/vyos/vyos_l3_interface.py index 38125d2062..54d1ad262f 100644 --- a/lib/ansible/modules/network/vyos/vyos_l3_interface.py +++ b/lib/ansible/modules/network/vyos/vyos_l3_interface.py @@ -45,10 +45,6 @@ options: - IPv6 of the L3 interface. aggregate: description: List of L3 interfaces definitions - purge: - description: - - Purge L3 interfaces not defined in the aggregate parameter. - default: no state: description: - State of the L3 interface configuration. @@ -66,6 +62,19 @@ EXAMPLES = """ vyos_l3_interface: name: eth0 state: absent + +- name: Set IP addresses on aggregate + vyos_l3_interface: + aggregate: + - { name: eth1, ipv4: 192.168.2.10/24 } + - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } + +- name: Remove IP addresses on aggregate + vyos_l3_interface: + aggregate: + - { name: eth1, ipv4: 192.168.2.10/24 } + - { name: eth2, ipv4: 192.168.3.10/24, ipv6: "fd5d:12c9:2201:1::1/64" } + state: absent """ RETURN = """ @@ -76,7 +85,10 @@ commands: sample: - set interfaces ethernet eth0 address '192.168.0.1/24' """ +from copy import deepcopy + from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network_common import remove_default_spec from ansible.module_utils.vyos import load_config, run_commands from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -153,18 +165,14 @@ def map_config_to_obj(module): def map_params_to_obj(module): obj = [] - if 'aggregate' in module.params and module.params['aggregate']: - for c in module.params['aggregate']: - d = c.copy() + aggregate = module.params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module.params[key] - if 'ipv4' not in d: - d['ipv4'] = None - if 'ipv6' not in d: - d['ipv6'] = None - if 'state' not in d: - d['state'] = module.params['state'] - - obj.append(d) + obj.append(item.copy()) else: obj.append({ 'name': module.params['name'], @@ -179,16 +187,25 @@ def map_params_to_obj(module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( name=dict(), ipv4=dict(), ipv6=dict(), - aggregate=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent']) ) + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec), + ) + + argument_spec.update(element_spec) argument_spec.update(vyos_argument_spec) required_one_of = [['name', 'aggregate']] diff --git a/lib/ansible/modules/network/vyos/vyos_linkagg.py b/lib/ansible/modules/network/vyos/vyos_linkagg.py index b2ca325ea3..9972a9cdff 100644 --- a/lib/ansible/modules/network/vyos/vyos_linkagg.py +++ b/lib/ansible/modules/network/vyos/vyos_linkagg.py @@ -49,10 +49,6 @@ options: - List of members of the link aggregation group. aggregate: description: List of link aggregation definitions. - purge: - description: - - Purge link aggregation groups not defined in the aggregates parameter. - default: no state: description: - State of the link aggregation group. @@ -73,6 +69,18 @@ EXAMPLES = """ name: bond0 state: absent +- name: Create aggregate of linkagg definitions + vyos_linkagg: + aggregate: + - { name: bond0, members: [eth1] } + - { name: bond1, members: [eth2] } + +- name: Remove aggregate of linkagg definitions + vyos_linkagg: + aggregate: + - name: bond0 + - name: bond1 + state: absent """ RETURN = """ @@ -85,7 +93,10 @@ commands: - set interfaces ethernet eth0 bond-group 'bond0' - set interfaces ethernet eth1 bond-group 'bond0' """ +from copy import deepcopy + from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network_common import remove_default_spec from ansible.module_utils.vyos import load_config, run_commands from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -173,17 +184,14 @@ def map_config_to_obj(module): def map_params_to_obj(module): obj = [] + aggregate = module.params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module.params[key] - if 'aggregate' in module.params and module.params['aggregate']: - for c in module.params['aggregate']: - d = c.copy() - - if 'state' not in d: - d['state'] = module.params['state'] - if 'mode' not in d: - d['mode'] = module.params['mode'] - - obj.append(d) + obj.append(item.copy()) else: obj.append({ 'name': module.params['name'], @@ -198,25 +206,35 @@ def map_params_to_obj(module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( name=dict(), mode=dict(choices=['802.3ad', 'active-backup', 'broadcast', 'round-robin', 'transmit-load-balance', 'adaptive-load-balance', 'xor-hash', 'on'], default='802.3ad'), members=dict(type='list'), - aggregate=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent', 'up', 'down']) ) + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec), + ) + + argument_spec.update(element_spec) argument_spec.update(vyos_argument_spec) required_one_of = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() diff --git a/lib/ansible/modules/network/vyos/vyos_lldp.py b/lib/ansible/modules/network/vyos/vyos_lldp.py index 8292633f55..09eb6f7ee5 100644 --- a/lib/ansible/modules/network/vyos/vyos_lldp.py +++ b/lib/ansible/modules/network/vyos/vyos_lldp.py @@ -78,7 +78,6 @@ def main(): """ argument_spec = dict( interfaces=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent', 'enabled', 'disabled']) diff --git a/lib/ansible/modules/network/vyos/vyos_lldp_interface.py b/lib/ansible/modules/network/vyos/vyos_lldp_interface.py index bab7d75fff..a19d8e5b32 100644 --- a/lib/ansible/modules/network/vyos/vyos_lldp_interface.py +++ b/lib/ansible/modules/network/vyos/vyos_lldp_interface.py @@ -39,10 +39,6 @@ options: - Name of the interface LLDP should be configured on. aggregate: description: List of interfaces LLDP should be configured on. - purge: - description: - - Purge interfaces not defined in the aggregate parameter. - default: no state: description: - State of the LLDP configuration. @@ -64,7 +60,21 @@ EXAMPLES = """ - name: Disable LLDP globally net_lldp_interface: - state: lldp + state: disabled + +- name: Create aggregate of LLDP interface configurations + vyos_lldp_interface: + aggregate: + - name: eth1 + - name: eth2 + state: present + +- name: Delete aggregate of LLDP interface configurations + vyos_lldp_interface: + aggregate: + - name: eth1 + - name: eth2 + state: absent """ RETURN = """ @@ -76,7 +86,10 @@ commands: - set service lldp eth1 - set service lldp eth2 disable """ +from copy import deepcopy + from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network_common import remove_default_spec from ansible.module_utils.vyos import get_config, load_config from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -142,14 +155,14 @@ def map_config_to_obj(module): def map_params_to_obj(module): obj = [] - if module.params['aggregate']: - for i in module.params['aggregate']: - d = i.copy() + aggregate = module.params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module.params[key] - if 'state' not in d: - d['state'] = module.params['state'] - - obj.append(d) + obj.append(item.copy()) else: obj.append({'name': module.params['name'], 'state': module.params['state']}) @@ -159,16 +172,26 @@ def map_params_to_obj(module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( name=dict(), - aggregate=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent', 'enabled', 'disabled']) ) + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec), + ) + + argument_spec.update(element_spec) argument_spec.update(vyos_argument_spec) + required_one_of = [['name', 'aggregate']] mutually_exclusive = [['name', 'aggregate']] diff --git a/lib/ansible/modules/network/vyos/vyos_logging.py b/lib/ansible/modules/network/vyos/vyos_logging.py index d1d6241bcd..0b1298e63d 100644 --- a/lib/ansible/modules/network/vyos/vyos_logging.py +++ b/lib/ansible/modules/network/vyos/vyos_logging.py @@ -50,10 +50,6 @@ options: - Set logging severity levels. aggregate: description: List of logging definitions. - purge: - description: - - Purge logging not defined in the aggregate parameter. - default: no state: description: - State of the logging configuration. @@ -67,16 +63,33 @@ EXAMPLES = """ dest: console facility: all level: crit + - name: remove console logging configuration vyos_logging: dest: console state: absent + - name: configure file logging vyos_logging: dest: file name: test facility: local3 level: err + +- name: Add logging aggregate + vyos_logging: + aggregate: + - { dest: file, name: test1, facility: all, level: info } + - { dest: file, name: test2, facility: news, level: debug } + state: present + +- name: Remove logging aggregate + vyos_logging: + aggregate: + - { dest: console, facility: all, level: info } + - { dest: console, facility: daemon, level: warning } + - { dest: file, name: test2, facility: news, level: debug } + state: absent """ RETURN = """ @@ -90,7 +103,10 @@ commands: import re +from copy import deepcopy + from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network_common import remove_default_spec from ansible.module_utils.vyos import get_config, load_config from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -160,21 +176,18 @@ def config_to_dict(module): return obj -def map_params_to_obj(module): +def map_params_to_obj(module, required_if=None): obj = [] - if 'aggregate' in module.params and module.params['aggregate']: - for c in module.params['aggregate']: - d = c.copy() - if d['dest'] not in ('host', 'file', 'user'): - d['name'] = None - else: - pass + aggregate = module.params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module.params[key] - if 'state' not in d: - d['state'] = module.params['state'] - - obj.append(d) + module._check_required_if(required_if, item) + obj.append(item.copy()) else: if module.params['dest'] not in ('host', 'file', 'user'): @@ -194,16 +207,25 @@ def map_params_to_obj(module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( dest=dict(type='str', choices=['console', 'file', 'global', 'host', 'user']), name=dict(type='str'), facility=dict(type='str'), level=dict(type='str'), state=dict(default='present', choices=['present', 'absent']), - aggregate=dict(type='list'), - purge=dict(default=False, type='bool') ) + aggregate_spec = deepcopy(element_spec) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec), + ) + + argument_spec.update(element_spec) + argument_spec.update(vyos_argument_spec) required_if = [('dest', 'host', ['name', 'facility', 'level']), ('dest', 'file', ['name', 'facility', 'level']), @@ -221,7 +243,7 @@ def main(): result = {'changed': False} if warnings: result['warnings'] = warnings - want = map_params_to_obj(module) + want = map_params_to_obj(module, required_if=required_if) have = config_to_dict(module) commands = spec_to_commands((want, have), module) diff --git a/lib/ansible/modules/network/vyos/vyos_static_route.py b/lib/ansible/modules/network/vyos/vyos_static_route.py index eff7ed1cf6..8a0bf5c749 100644 --- a/lib/ansible/modules/network/vyos/vyos_static_route.py +++ b/lib/ansible/modules/network/vyos/vyos_static_route.py @@ -50,10 +50,6 @@ options: - Admin distance of the static route. aggregate: description: List of static route definitions - purge: - description: - - Purge static routes not defined in the aggregates parameter. - default: no state: description: - State of the static route configuration. @@ -67,22 +63,32 @@ EXAMPLES = """ prefix: 192.168.2.0 mask: 24 next_hop: 10.0.0.1 + - name: configure static route prefix/mask vyos_static_route: prefix: 192.168.2.0/16 next_hop: 10.0.0.1 + - name: remove configuration vyos_static_route: prefix: 192.168.2.0 mask: 16 next_hop: 10.0.0.1 state: absent + - name: configure aggregates of static routes vyos_static_route: aggregate: - { prefix: 192.168.2.0, mask: 24, next_hop: 10.0.0.1 } - { prefix: 192.168.3.0, mask: 16, next_hop: 10.0.2.1 } - { prefix: 192.168.3.0/16, next_hop: 10.0.2.1 } + +- name: Remove static route collections + vyos_static_route: + aggregate: + - { prefix: 172.24.1.0/24, next_hop: 192.168.42.64 } + - { prefix: 172.24.3.0/24, next_hop: 192.168.42.64 } + state: absent """ RETURN = """ @@ -93,10 +99,12 @@ commands: sample: - set protocols static route 192.168.2.0/16 next-hop 10.0.0.1 """ - import re +from copy import deepcopy + from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network_common import remove_default_spec from ansible.module_utils.vyos import get_config, load_config from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -156,20 +164,23 @@ def config_to_dict(module): return obj -def map_params_to_obj(module): +def map_params_to_obj(module, required_together=None): obj = [] + aggregate = module.params.get('aggregate') + if aggregate: + for item in aggregate: + for key in item: + if item.get(key) is None: + item[key] = module.params[key] - if 'aggregate' in module.params and module.params['aggregate']: - for c in module.params['aggregate']: - d = c.copy() + module._check_required_together(required_together, item) + d = item.copy() if '/' in d['prefix']: d['mask'] = d['prefix'].split('/')[1] d['prefix'] = d['prefix'].split('/')[0] - if 'state' not in d: - d['state'] = module.params['state'] - if 'admin_distance' not in d: - d['admin_distance'] = str(module.params['admin_distance']) + if 'admin_distance' in d: + d['admin_distance'] = str(d['admin_distance']) obj.append(d) else: @@ -197,16 +208,27 @@ def map_params_to_obj(module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( prefix=dict(type='str'), mask=dict(type='str'), next_hop=dict(type='str'), admin_distance=dict(type='int'), - aggregate=dict(type='list'), - purge=dict(type='bool'), state=dict(default='present', choices=['present', 'absent']) ) + aggregate_spec = deepcopy(element_spec) + aggregate_spec['prefix'] = dict(required=True) + + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec), + ) + + argument_spec.update(element_spec) + argument_spec.update(vyos_argument_spec) + argument_spec.update(vyos_argument_spec) required_one_of = [['aggregate', 'prefix']] required_together = [['prefix', 'next_hop']] @@ -215,6 +237,7 @@ def main(): module = AnsibleModule(argument_spec=argument_spec, required_one_of=required_one_of, required_together=required_together, + mutually_exclusive=mutually_exclusive, supports_check_mode=True) warnings = list() @@ -223,7 +246,7 @@ def main(): result = {'changed': False} if warnings: result['warnings'] = warnings - want = map_params_to_obj(module) + want = map_params_to_obj(module, required_together=required_together) have = config_to_dict(module) commands = spec_to_commands((want, have), module) diff --git a/lib/ansible/modules/network/vyos/vyos_user.py b/lib/ansible/modules/network/vyos/vyos_user.py index 333d6bba36..1de6e25495 100644 --- a/lib/ansible/modules/network/vyos/vyos_user.py +++ b/lib/ansible/modules/network/vyos/vyos_user.py @@ -127,9 +127,11 @@ commands: import re +from copy import deepcopy from functools import partial from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network_common import remove_default_spec from ansible.module_utils.vyos import get_config, load_config from ansible.module_utils.six import iteritems from ansible.module_utils.vyos import vyos_argument_spec, check_args @@ -215,13 +217,6 @@ def get_param_value(key, item, module): if not item.get(key): value = module.params[key] - # if key does exist, do a type check on it to validate it - else: - value_type = module.argument_spec[key].get('type', 'str') - type_checker = module._CHECK_ARGUMENT_TYPES_DISPATCHER[value_type] - type_checker(item[key]) - value = item[key] - # validate the param value (if validator func exists) validator = globals().get('validate_%s' % key) if all((value, validator)): @@ -231,21 +226,17 @@ def get_param_value(key, item, module): def map_params_to_obj(module): - users = module.params['users'] - if not users: + aggregate = module.params['aggregate'] + if not aggregate: if not module.params['name'] and module.params['purge']: return list() - elif not module.params['name']: - module.fail_json(msg='username is required') else: aggregate = [{'name': module.params['name']}] else: aggregate = list() - for item in users: + for item in aggregate: if not isinstance(item, dict): aggregate.append({'name': item}) - elif 'name' not in item: - module.fail_json(msg='name is required') else: aggregate.append(item) @@ -278,8 +269,7 @@ def update_objects(want, have): def main(): """ main entry point for module execution """ - argument_spec = dict( - users=dict(type='list', aliases=['aggregate']), + element_spec = dict( name=dict(), full_name=dict(), @@ -292,9 +282,20 @@ def main(): state=dict(default='present', choices=['present', 'absent']) ) - argument_spec.update(vyos_argument_spec) - mutually_exclusive = [('name', 'users')] + aggregate_spec = deepcopy(element_spec) + aggregate_spec['name'] = dict(required=True) + # remove default in aggregate spec, to handle common arguments + remove_default_spec(aggregate_spec) + + argument_spec = dict( + aggregate=dict(type='list', elements='dict', options=aggregate_spec, aliases=['users']), + ) + + argument_spec.update(element_spec) + argument_spec.update(vyos_argument_spec) + + mutually_exclusive = [('name', 'aggregate')] module = AnsibleModule(argument_spec=argument_spec, mutually_exclusive=mutually_exclusive, supports_check_mode=True) diff --git a/test/integration/targets/net_interface/tests/vyos/basic.yaml b/test/integration/targets/net_interface/tests/vyos/basic.yaml index 777016964a..fa7d7f6603 100644 --- a/test/integration/targets/net_interface/tests/vyos/basic.yaml +++ b/test/integration/targets/net_interface/tests/vyos/basic.yaml @@ -138,8 +138,9 @@ - name: Disable interface on aggregate net_interface: aggregate: - - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, enabled: False} - - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, enabled: False} + - name: eth1 + - name: eth2 + enabled: False register: result - assert: @@ -151,8 +152,9 @@ - name: Enable interface on aggregate net_interface: aggregate: - - { name: eth1, description: test-interface-1, speed: 100, duplex: half, mtu: 512, enabled: True} - - { name: eth2, description: test-interface-2, speed: 1000, duplex: full, mtu: 256, enabled: True} + - name: eth1 + - name: eth2 + enabled: True register: result - assert: @@ -164,8 +166,9 @@ - name: Delete interface aggregate net_interface: aggregate: - - { name: eth1, state: absent} - - { name: eth2, state: absent} + - name: eth1 + - name: eth2 + state: absent register: result - assert: @@ -177,8 +180,9 @@ - name: Delete interface aggregate (idempotent) net_interface: aggregate: - - { name: eth1, state: absent} - - { name: eth2, state: absent} + - name: eth1 + - name: eth2 + state: absent register: result - assert: diff --git a/test/integration/targets/vyos_interface/tests/cli/basic.yaml b/test/integration/targets/vyos_interface/tests/cli/basic.yaml index a4c3a7cd40..83c2a27b9a 100644 --- a/test/integration/targets/vyos_interface/tests/cli/basic.yaml +++ b/test/integration/targets/vyos_interface/tests/cli/basic.yaml @@ -167,8 +167,9 @@ - name: Disable interface on aggregate vyos_interface: aggregate: - - { name: eth1, description: test-interface-1, enabled: False} - - { name: eth2, description: test-interface-2, enabled: False} + - name: eth1 + - name: eth2 + enabled: False register: result - assert: @@ -180,8 +181,9 @@ - name: Enable interface on aggregate vyos_interface: aggregate: - - { name: eth1, description: test-interface-1, enabled: True} - - { name: eth2, description: test-interface-2, enabled: True} + - name: eth1 + - name: eth2 + enabled: True register: result - assert: @@ -193,8 +195,9 @@ - name: Delete interface aggregate vyos_interface: aggregate: - - { name: eth1, state: absent} - - { name: eth2, state: absent} + - name: eth1 + - name: eth2 + state: absent register: result - assert: @@ -206,8 +209,9 @@ - name: Delete interface aggregate (idempotent) vyos_interface: aggregate: - - { name: eth1, state: absent} - - { name: eth2, state: absent} + - name: eth1 + - name: eth2 + state: absent register: result - assert: diff --git a/test/integration/targets/vyos_linkagg/tests/cli/basic.yaml b/test/integration/targets/vyos_linkagg/tests/cli/basic.yaml index 0b66905de4..27c2df1209 100644 --- a/test/integration/targets/vyos_linkagg/tests/cli/basic.yaml +++ b/test/integration/targets/vyos_linkagg/tests/cli/basic.yaml @@ -156,8 +156,8 @@ - name: Remove collection of linkagg definitions vyos_linkagg: aggregate: - - { name: bond0 } - - { name: bond1 } + - name: bond0 + - name: bond1 state: absent register: result @@ -172,8 +172,8 @@ - name: Remove collection of linkagg definitions again (idempotent) vyos_linkagg: aggregate: - - { name: bond0 } - - { name: bond1 } + - name: bond0 + - name: bond1 state: absent register: result diff --git a/test/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml b/test/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml index 53c8f4c47a..089d9b7a98 100644 --- a/test/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml +++ b/test/integration/targets/vyos_lldp_interface/tests/cli/basic.yaml @@ -90,8 +90,8 @@ - name: Create aggregate of LLDP interface configurations vyos_lldp_interface: aggregate: - - { name: eth1 } - - { name: eth2 } + - name: eth1 + - name: eth2 state: present register: result @@ -104,8 +104,8 @@ - name: Create aggregate of LLDP interface configurations again (idempotent) vyos_lldp_interface: aggregate: - - { name: eth1 } - - { name: eth2 } + - name: eth1 + - name: eth2 state: present register: result @@ -116,7 +116,7 @@ - name: Override LLDP interface configuration on aggregate vyos_lldp_interface: aggregate: - - { name: eth1 } + - name: eth1 - { name: eth2, state: disabled } state: present register: result @@ -129,7 +129,7 @@ - name: Override LLDP interface configuration on aggregate again (idempotent) vyos_lldp_interface: aggregate: - - { name: eth1 } + - name: eth1 - { name: eth2, state: disabled } state: present register: result @@ -141,8 +141,8 @@ - name: Delete aggregate of LLDP interface configurations vyos_lldp_interface: aggregate: - - { name: eth1 } - - { name: eth2 } + - name: eth1 + - name: eth2 state: absent register: result @@ -155,8 +155,8 @@ - name: Delete aggregate of LLDP interface configurations (idempotent) vyos_lldp_interface: aggregate: - - { name: eth1 } - - { name: eth2 } + - name: eth1 + - name: eth2 state: absent register: result