diff --git a/lib/ansible/modules/network/eos/eos_logging.py b/lib/ansible/modules/network/eos/eos_logging.py index 1aaa6c9240c..453ab3ea797 100644 --- a/lib/ansible/modules/network/eos/eos_logging.py +++ b/lib/ansible/modules/network/eos/eos_logging.py @@ -55,10 +55,6 @@ options: 'warnings', 'notifications', 'informational', 'debugging'] 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. @@ -72,24 +68,35 @@ EXAMPLES = """ dest: host name: 172.16.0.1 state: present + - name: remove host logging configuration eos_logging: dest: host name: 172.16.0.1 state: absent + - name: configure console logging level and facility eos_logging: dest: console facility: local7 level: debugging state: present + - name: enable logging to all eos_logging: dest : on + - name: configure buffer size eos_logging: dest: buffered size: 5000 + +- name: Configure logging using aggregate + eos_logging: + aggregate: + - { dest: console, level: warnings } + - { dest: buffered, size: 480000 } + state: present """ RETURN = """ @@ -104,7 +111,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.eos import get_config, load_config from ansible.module_utils.eos import eos_argument_spec, check_args @@ -268,30 +278,21 @@ def parse_obj(obj, module): return obj -def map_params_to_obj(module): +def map_params_to_obj(module, required_if=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']: - args = {'dest': '', - 'name': '', - 'size': '', - 'facility': '', - 'level': '', - } - - for c in module.params['aggregate']: - d = c.copy() - - for key in args: - if key not in d: - d[key] = None + module._check_required_if(required_if, item) + d = item.copy() if d['dest'] != 'host': d['name'] = None - if 'state' not in d: - d['state'] = module.params['state'] - if d['dest'] == 'buffered': if 'size' in d: d['size'] = str(validate_size(d['size'], module)) @@ -323,17 +324,25 @@ def map_params_to_obj(module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( dest=dict(choices=DEST_GROUP), name=dict(), size=dict(type='int'), facility=dict(), level=dict(choices=LEVEL_GROUP), 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(eos_argument_spec) required_if = [('dest', 'host', ['name'])] @@ -349,7 +358,7 @@ def main(): if warnings: result['warnings'] = warnings - want = map_params_to_obj(module) + want = map_params_to_obj(module, required_if=required_if) have = map_config_to_obj(module) commands = map_obj_to_commands((want, have), module) diff --git a/lib/ansible/modules/network/eos/eos_user.py b/lib/ansible/modules/network/eos/eos_user.py index 38248a997af..9ac693605cd 100644 --- a/lib/ansible/modules/network/eos/eos_user.py +++ b/lib/ansible/modules/network/eos/eos_user.py @@ -149,9 +149,11 @@ session_name: 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.eos import get_config, load_config from ansible.module_utils.six import iteritems from ansible.module_utils.eos import eos_argument_spec, check_args @@ -315,8 +317,7 @@ def update_objects(want, have): def main(): """ main entry point for module execution """ - argument_spec = dict( - aggregate=dict(type='list', aliases=['collection', 'users']), + element_spec = dict( name=dict(), configured_password=dict(no_log=True), @@ -328,10 +329,20 @@ def main(): sshkey=dict(), - purge=dict(type='bool', default=False), state=dict(default='present', choices=['present', 'absent']) ) + 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, aliases=['collection', 'users']), + purge=dict(type='bool', default=False) + ) + + argument_spec.update(element_spec) argument_spec.update(eos_argument_spec) mutually_exclusive = [('name', 'aggregate')] diff --git a/lib/ansible/modules/network/eos/eos_vlan.py b/lib/ansible/modules/network/eos/eos_vlan.py index 9e4b75ad7e1..7803cd4786c 100644 --- a/lib/ansible/modules/network/eos/eos_vlan.py +++ b/lib/ansible/modules/network/eos/eos_vlan.py @@ -62,6 +62,35 @@ options: """ EXAMPLES = """ +- name: Create vlan + eos_vlan: + vlan_id: 4000 + name: vlan-4000 + state: present + +- name: Add interfaces to vlan + eos_vlan: + vlan_id: 4000 + state: present + interfaces: + - Ethernet1 + - Ethernet2 + +- name: Suspend vlan + eos_vlan: + vlan_id: 4000 + state: suspend + +- name: Unsuspend vlan + eos_vlan: + vlan_id: 4000 + state: active + +- name: Create aggregate of vlans + eos_vlan: + aggregate: + - vlan_id: 4000 + - {vlan_id: 4001, name: vlan-4001} """ RETURN = """ @@ -73,13 +102,15 @@ commands: - vlan 20 - name test-vlan """ +import re +import time + +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.eos import load_config, run_commands from ansible.module_utils.eos import eos_argument_spec, check_args -from ansible.module_utils.six import iteritems - -import re -import time def search_obj_in_list(vlan_id, lst): @@ -187,34 +218,23 @@ def map_config_to_obj(module): def map_params_to_obj(module): obj = [] - - if 'aggregate' in module.params and module.params['aggregate']: - for v in module.params['aggregate']: - d = v.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] + + d = item.copy() d['vlan_id'] = str(d['vlan_id']) - if 'state' not in d: - d['state'] = module.params['state'] - - if 'name' not in d: - d['name'] = None - - if 'interfaces' not in d: - d['interfaces'] = [] - obj.append(d) else: - vlan_id = str(module.params['vlan_id']) - name = module.params['name'] - state = module.params['state'] - interfaces = module.params['interfaces'] - obj.append({ - 'vlan_id': vlan_id, - 'name': name, - 'state': state, - 'interfaces': interfaces + 'vlan_id': str(module.params['vlan_id']), + 'name': module.params['name'], + 'state': module.params['state'], + 'interfaces': module.params['interfaces'] }) return obj @@ -236,23 +256,35 @@ def check_declarative_intent_params(want, module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( vlan_id=dict(type='int'), name=dict(), interfaces=dict(type='list'), delay=dict(default=10, type='int'), - aggregate=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent', 'active', 'suspend']) ) + aggregate_spec = deepcopy(element_spec) + aggregate_spec['vlan_id'] = 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), + purge=dict(default=False, type='bool') + ) + + argument_spec.update(element_spec) argument_spec.update(eos_argument_spec) required_one_of = [['vlan_id', 'aggregate']] mutually_exclusive = [['vlan_id', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, - supports_check_mode=True) + supports_check_mode=True, + required_one_of=required_one_of, + mutually_exclusive=mutually_exclusive) warnings = list() check_args(module, warnings) diff --git a/lib/ansible/modules/network/eos/eos_vrf.py b/lib/ansible/modules/network/eos/eos_vrf.py index 1986c49a7cc..46eaf758be7 100644 --- a/lib/ansible/modules/network/eos/eos_vrf.py +++ b/lib/ansible/modules/network/eos/eos_vrf.py @@ -59,6 +59,35 @@ options: """ EXAMPLES = """ +- name: Create vrf + eos_vrf: + name: test + rd: 1:200 + interfaces: + - Ethernet2 + state: present + +- name: Delete VRFs + eos_vrf: + name: test + state: absent + +- name: Create aggregate of VRFs with purge + eos_vrf: + aggregate: + - { name: test4, rd: "1:204" } + - { name: test5, rd: "1:205" } + state: present + purge: yes + +- name: Delete aggregate of VRFs + eos_vrf: + aggregate: + - name: test2 + - name: test3 + - name: test4 + - name: test5 + state: absent """ RETURN = """ @@ -72,13 +101,15 @@ commands: - interface Ethernet1 - vrf forwarding test """ +import re +import time + +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.eos import load_config, run_commands from ansible.module_utils.eos import eos_argument_spec, check_args -from ansible.module_utils.six import iteritems - -import re -import time def search_obj_in_list(name, lst): @@ -172,25 +203,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() - - if 'state' not in d: - d['state'] = module.params['state'] - if 'rd' not in d: - d['rd'] = module.params['rd'] - if 'interfaces' not in d: - d['interfaces'] = module.params['interfaces'] - - obj.append(d) + 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] + obj.append(item.copy()) else: - name = module.params['name'], - state = module.params['state'], - rd = module.params['rd'], - interfaces = module.params['interfaces'] - obj.append({ 'name': module.params['name'], 'state': module.params['state'], @@ -217,16 +237,25 @@ def check_declarative_intent_params(want, module): def main(): """ main entry point for module execution """ - argument_spec = dict( + element_spec = dict( name=dict(), interfaces=dict(type='list'), delay=dict(default=10, type='int'), rd=dict(), - aggregate=dict(type='list'), - purge=dict(default=False, type='bool'), state=dict(default='present', choices=['present', 'absent']) ) + 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), + purge=dict(default=False, type='bool') + ) + + argument_spec.update(element_spec) argument_spec.update(eos_argument_spec) required_one_of = [['name', 'aggregate']] diff --git a/lib/ansible/modules/network/layer3/net_vrf.py b/lib/ansible/modules/network/layer3/net_vrf.py index 9e0586ddf6f..aa385b010d9 100644 --- a/lib/ansible/modules/network/layer3/net_vrf.py +++ b/lib/ansible/modules/network/layer3/net_vrf.py @@ -51,6 +51,23 @@ EXAMPLES = """ net_vrf: name: MANAGEMENT state: absent + +- name: Create aggregate of VRFs with purge + net_vrf: + aggregate: + - { name: test4, rd: "1:204" } + - { name: test5, rd: "1:205" } + state: present + purge: yes + +- name: Delete aggregate of VRFs + net_vrf: + aggregate: + - name: test2 + - name: test3 + - name: test4 + - name: test5 + state: absent """ RETURN = """