diff --git a/lib/ansible/modules/network/eos/eos_vlan.py b/lib/ansible/modules/network/eos/eos_vlan.py index 3ee50b160d..5958b9b0b0 100644 --- a/lib/ansible/modules/network/eos/eos_vlan.py +++ b/lib/ansible/modules/network/eos/eos_vlan.py @@ -47,6 +47,13 @@ options: description: - List of interfaces that should be associated to the VLAN. The name of interface should be in expanded format and not abbreviated. + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vlan C(name) + for associated interfaces. The name of interface should be in expanded format and not abbreviated. + If the value in the C(associated_interfaces) does not match with the operational state of vlan + interfaces on device it will result in failure. + version_added: "2.5" delay: description: - Delay the play should wait to check for declarative intent params values. @@ -80,6 +87,13 @@ EXAMPLES = """ - Ethernet1 - Ethernet2 +- name: Check if interfaces is assigned to vlan + eos_vlan: + vlan_id: 4000 + associated_interfaces: + - Ethernet1 + - Ethernet2 + - name: Suspend vlan eos_vlan: vlan_id: 4000 @@ -233,6 +247,9 @@ def map_params_to_obj(module): if item.get('interfaces'): item['interfaces'] = [intf.replace(" ", "").lower() for intf in item.get('interfaces') if intf] + if item.get('associated_interfaces'): + item['associated_interfaces'] = [intf.replace(" ", "").lower() for intf in item.get('associated_interfaces') if intf] + d = item.copy() d['vlan_id'] = str(d['vlan_id']) @@ -242,23 +259,35 @@ def map_params_to_obj(module): 'vlan_id': str(module.params['vlan_id']), 'name': module.params['name'], 'state': module.params['state'], - 'interfaces': [intf.replace(" ", "").lower() for intf in module.params['interfaces']] if module.params['interfaces'] else [] + 'interfaces': [intf.replace(" ", "").lower() for intf in module.params['interfaces']] if module.params['interfaces'] else [], + 'associated_interfaces': [intf.replace(" ", "").lower() for intf in + module.params['associated_interfaces']] if module.params['associated_interfaces'] else [] + }) return obj -def check_declarative_intent_params(want, module): - if module.params['interfaces']: - time.sleep(module.params['delay']) - have = map_config_to_obj(module) +def check_declarative_intent_params(want, module, result): + have = None + is_delay = False - for w in want: - for i in w['interfaces']: - obj_in_have = search_obj_in_list(w['vlan_id'], have) + for w in want: + if w.get('associated_interfaces') is None: + continue - if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: - module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) + if result['changed'] and not is_delay: + time.sleep(module.params['delay']) + is_delay = True + + if have is None: + have = map_config_to_obj(module) + + for i in w['associated_interfaces']: + obj_in_have = search_obj_in_list(w['vlan_id'], have) + + if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: + module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) def main(): @@ -268,6 +297,7 @@ def main(): vlan_id=dict(type='int'), name=dict(), interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent', 'active', 'suspend']) @@ -316,8 +346,7 @@ def main(): result['session_name'] = response.get('session') result['changed'] = True - if result['changed']: - check_declarative_intent_params(want, module) + check_declarative_intent_params(want, module, result) module.exit_json(**result) diff --git a/lib/ansible/modules/network/eos/eos_vrf.py b/lib/ansible/modules/network/eos/eos_vrf.py index e26a9f12bc..c773355c3a 100644 --- a/lib/ansible/modules/network/eos/eos_vrf.py +++ b/lib/ansible/modules/network/eos/eos_vrf.py @@ -49,6 +49,12 @@ options: should be configured in the VRF. Interfaces must be routed interfaces in order to be placed into a VRF. The name of interface should be in expanded format and not abbreviated. + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vrf C(name) + for associated interfaces. If the value in the C(associated_interfaces) does not match with + the operational state of vrf interfaces on device it will result in failure. + version_added: "2.5" aggregate: description: List of VRFs definitions purge: @@ -238,31 +244,46 @@ def map_params_to_obj(module): if item.get('interfaces'): item['interfaces'] = [intf.replace(" ", "").lower() for intf in item.get('interfaces') if intf] + if item.get('associated_interfaces'): + item['associated_interfaces'] = [intf.replace(" ", "").lower() for intf in item.get('associated_interfaces') if intf] + obj.append(item.copy()) else: obj.append({ 'name': module.params['name'], 'state': module.params['state'], 'rd': module.params['rd'], - 'interfaces': [intf.replace(" ", "").lower() for intf in module.params['interfaces']] if module.params['interfaces'] else [] + 'interfaces': [intf.replace(" ", "").lower() for intf in module.params['interfaces']] if module.params['interfaces'] else [], + 'associated_interfaces': [intf.replace(" ", "").lower() for intf in + module.params['associated_interfaces']] if module.params['associated_interfaces'] else [] + }) return obj -def check_declarative_intent_params(want, module): - if module.params['interfaces']: - time.sleep(module.params['delay']) - have = map_config_to_obj(module) +def check_declarative_intent_params(want, module, result): + have = None + is_delay = False - for w in want: - for i in w['interfaces']: - obj_in_have = search_obj_in_list(w['name'], have) + for w in want: + if w.get('associated_interfaces') is None: + continue - if obj_in_have: - interfaces = obj_in_have.get('interfaces') - if interfaces is not None and i not in interfaces: - module.fail_json(msg="Interface %s not configured on vrf %s" % (i, w['name'])) + if result['changed'] and not is_delay: + time.sleep(module.params['delay']) + is_delay = True + + if have is None: + have = map_config_to_obj(module) + + for i in w['associated_interfaces']: + obj_in_have = search_obj_in_list(w['name'], have) + + if obj_in_have: + interfaces = obj_in_have.get('interfaces') + if interfaces is not None and i not in interfaces: + module.fail_json(msg="Interface %s not configured on vrf %s" % (i, w['name'])) def main(): @@ -271,6 +292,7 @@ def main(): element_spec = dict( name=dict(), interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), delay=dict(default=10, type='int'), rd=dict(), state=dict(default='present', choices=['present', 'absent']) @@ -318,8 +340,7 @@ def main(): result['session_name'] = response.get('session') result['changed'] = True - if result['changed']: - check_declarative_intent_params(want, module) + check_declarative_intent_params(want, module, result) module.exit_json(**result) diff --git a/lib/ansible/modules/network/ios/ios_vlan.py b/lib/ansible/modules/network/ios/ios_vlan.py index 9037120c93..cd3617e9bf 100644 --- a/lib/ansible/modules/network/ios/ios_vlan.py +++ b/lib/ansible/modules/network/ios/ios_vlan.py @@ -35,6 +35,12 @@ options: description: - List of interfaces that should be associated to the VLAN. required: true + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vlan C(name) + for associated interfaces. If the value in the C(associated_interfaces) does not match with + the operational state of vlan interfaces on device it will result in failure. + version_added: "2.5" delay: description: - Delay the play should wait to check for declarative intent params values. @@ -59,12 +65,21 @@ EXAMPLES = """ vlan_id: 100 name: test-vlan state: present + - name: Add interfaces to VLAN ios_vlan: vlan_id: 100 interfaces: - GigabitEthernet0/0 - GigabitEthernet0/1 + +- name: Check if interfaces is assigned to VLAN + ios_vlan: + vlan_id: 100 + associated_interfaces: + - GigabitEthernet0/0 + - GigabitEthernet0/1 + - name: Delete vlan ios_vlan: vlan_id: 100 @@ -189,6 +204,7 @@ def map_params_to_obj(module): 'vlan_id': str(module.params['vlan_id']), 'name': module.params['name'], 'interfaces': module.params['interfaces'], + 'associated_interfaces': module.params['associated_interfaces'], 'state': module.params['state'] }) @@ -227,16 +243,26 @@ def map_config_to_obj(module): return objs -def check_declarative_intent_params(want, module): - if module.params['interfaces']: - time.sleep(module.params['delay']) - have = map_config_to_obj(module) +def check_declarative_intent_params(want, module, result): - for w in want: - for i in w['interfaces']: - obj_in_have = search_obj_in_list(w['vlan_id'], have) - if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: - module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) + have = None + is_delay = False + + for w in want: + if w.get('associated_interfaces') is None: + continue + + if result['changed'] and not is_delay: + time.sleep(module.params['delay']) + is_delay = True + + if have is None: + have = map_config_to_obj(module) + + for i in w['associated_interfaces']: + obj_in_have = search_obj_in_list(w['vlan_id'], have) + if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: + module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) def main(): @@ -246,6 +272,7 @@ def main(): vlan_id=dict(type='int'), name=dict(), interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent', 'active', 'suspend']) @@ -287,10 +314,10 @@ def main(): load_config(module, commands) result['changed'] = True - if result['changed']: - check_declarative_intent_params(want, module) + check_declarative_intent_params(want, module, result) module.exit_json(**result) + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/network/ios/ios_vrf.py b/lib/ansible/modules/network/ios/ios_vrf.py index de3e58e9d8..70fee2f745 100644 --- a/lib/ansible/modules/network/ios/ios_vrf.py +++ b/lib/ansible/modules/network/ios/ios_vrf.py @@ -64,6 +64,12 @@ options: - Identifies the set of interfaces that should be configured in the VRF. Interfaces must be routed interfaces in order to be placed into a VRF. + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vrf C(name) + for associated interfaces. If the value in the C(associated_interfaces) does not match with + the operational state of vrf interfaces on device it will result in failure. + version_added: "2.5" delay: description: - Time in seconds to wait before checking for the operational state on remote @@ -400,6 +406,7 @@ def map_params_to_obj(module): item['route_import'] = get_value('route_import') item['route_export'] = get_value('route_export') item['route_both'] = get_value('route_both') + item['associated_interfaces'] = get_value('associated_interfaces') objects.append(item) return objects @@ -424,8 +431,12 @@ def update_objects(want, have): return updates -def check_declarative_intent_params(want, module): - if module.params['interfaces']: +def check_declarative_intent_params(want, module, result): + if module.params['associated_interfaces']: + + if result['changed']: + time.sleep(module.params['delay']) + name = module.params['name'] rc, out, err = exec_command(module, 'show vrf | include {0}'.format(name)) @@ -439,7 +450,9 @@ def check_declarative_intent_params(want, module): for w in want: if w['name'] == vrf: - for i in w['interfaces']: + if w.get('associated_interfaces') is None: + continue + for i in w['associated_interfaces']: if get_interface_type(i) is not get_interface_type(interface): module.fail_json(msg="Interface %s not configured on vrf %s" % (interface, name)) @@ -458,6 +471,7 @@ def main(): route_both=dict(type='list'), interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), delay=dict(default=10, type='int'), purge=dict(type='bool', default=False), @@ -497,12 +511,10 @@ def main(): load_config(module, commands) result['changed'] = True - if result['changed']: - time.sleep(module.params['delay']) - - check_declarative_intent_params(want, module) + check_declarative_intent_params(want, module, result) module.exit_json(**result) + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/network/nxos/nxos_vlan.py b/lib/ansible/modules/network/nxos/nxos_vlan.py index cc668dbdbb..cb5d339b67 100644 --- a/lib/ansible/modules/network/nxos/nxos_vlan.py +++ b/lib/ansible/modules/network/nxos/nxos_vlan.py @@ -49,6 +49,12 @@ options: description: - List of interfaces that should be associated to the VLAN. version_added: "2.5" + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vlan C(name) + for associated interfaces. If the value in the C(associated_interfaces) does not match with + the operational state of vlan interfaces on device it will result in failure. + version_added: "2.5" vlan_state: description: - Manage the vlan operational state of the VLAN @@ -116,12 +122,22 @@ EXAMPLES = ''' vlan_id: 50 state: absent -- name: Add interfaces to VLAN +- name: Add interfaces to VLAN and check intent (config + intent) nxos_vlan: vlan_id: 100 interfaces: - Ethernet2/1 - Ethernet2/5 + associated_interfaces: + - Ethernet2/1 + - Ethernet2/5 + +- name: Check interfaces assigned to VLAN + nxos_vlan: + vlan_id: 100 + associated_interfaces: + - Ethernet2/1 + - Ethernet2/5 - name: Create aggregate of vlans nxos_vlan: @@ -156,13 +172,15 @@ def search_obj_in_list(vlan_id, lst): def get_diff(w, have): - del w['interfaces'] - del w['name'] + c = deepcopy(w) + del c['interfaces'] + del c['name'] + del c['associated_interfaces'] for o in have: del o['interfaces'] del o['name'] if o['vlan_id'] == w['vlan_id']: - diff_dict = dict(set(w.items()) - set(o.items())) + diff_dict = dict(set(c.items()) - set(o.items())) return diff_dict @@ -339,7 +357,8 @@ def map_params_to_obj(module): 'mapped_vni': str(module.params['mapped_vni']), 'state': module.params['state'], 'admin_state': module.params['admin_state'], - 'mode': module.params['mode'] + 'mode': module.params['mode'], + 'associated_interfaces': module.params['associated_interfaces'] }) return obj @@ -451,16 +470,26 @@ def map_config_to_obj(module, os_platform): return objs -def check_declarative_intent_params(want, module, os_platform): - if module.params['interfaces']: - time.sleep(module.params['delay']) - have = map_config_to_obj(module, os_platform) +def check_declarative_intent_params(want, module, os_platform, result): - for w in want: - for i in w['interfaces']: - obj_in_have = search_obj_in_list(w['vlan_id'], have) - if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: - module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) + have = None + is_delay = False + + for w in want: + if w.get('associated_interfaces') is None: + continue + + if result['changed'] and not is_delay: + time.sleep(module.params['delay']) + is_delay = True + + if have is None: + have = map_config_to_obj(module, os_platform) + + for i in w['associated_interfaces']: + obj_in_have = search_obj_in_list(w['vlan_id'], have) + if obj_in_have and 'interfaces' in obj_in_have and i not in obj_in_have['interfaces']: + module.fail_json(msg="Interface %s not configured on vlan %s" % (i, w['vlan_id'])) def main(): @@ -471,6 +500,7 @@ def main(): vlan_range=dict(required=False), name=dict(required=False), interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), vlan_state=dict(choices=['active', 'suspend'], required=False, default='active'), mapped_vni=dict(required=False, type='int'), delay=dict(default=10, type='int'), @@ -526,10 +556,11 @@ def main(): load_config(module, commands) result['changed'] = True - if want and result['changed']: - check_declarative_intent_params(want, module, os_platform) + if want: + check_declarative_intent_params(want, module, os_platform, result) module.exit_json(**result) + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/network/nxos/nxos_vrf.py b/lib/ansible/modules/network/nxos/nxos_vrf.py index 59a458e2e6..35388606fe 100644 --- a/lib/ansible/modules/network/nxos/nxos_vrf.py +++ b/lib/ansible/modules/network/nxos/nxos_vrf.py @@ -76,6 +76,12 @@ options: - List of interfaces to check the VRF has been configured correctly. version_added: 2.5 + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vrf C(name) + for associated interfaces. If the value in the C(associated_interfaces) does not match with + the operational state of vrf interfaces on device it will result in failure. + version_added: "2.5" aggregate: description: List of VRFs definitions. version_added: 2.5 @@ -137,6 +143,13 @@ EXAMPLES = ''' - Ethernet2/3 - Ethernet2/5 +- name: Check interfaces assigend to VRF + nxos_vrf: + name: test1 + associated_interfaces: + - Ethernet2/3 + - Ethernet2/5 + - name: Ensure VRF is tagged with interface Ethernet2/5 only (Removes from Ethernet2/3) nxos_vrf: name: test1 @@ -349,7 +362,8 @@ def map_params_to_obj(module): 'rd': module.params['rd'], 'admin_state': module.params['admin_state'], 'state': module.params['state'], - 'interfaces': module.params['interfaces'] + 'interfaces': module.params['interfaces'], + 'associated_interfaces': module.params['associated_interfaces'] }) return obj @@ -408,19 +422,29 @@ def map_config_to_obj(want, element_spec, module): return objs -def check_declarative_intent_params(want, element_spec, module): - if module.params['interfaces']: - time.sleep(module.params['delay']) - have = map_config_to_obj(want, element_spec, module) +def check_declarative_intent_params(want, module, element_spec, result): - for w in want: - for i in w['interfaces']: - obj_in_have = search_obj_in_list(w['name'], have) + have = None + is_delay = False - if obj_in_have: - interfaces = obj_in_have.get('interfaces') - if interfaces is not None and i not in interfaces: - module.fail_json(msg="Interface %s not configured on vrf %s" % (i, w['name'])) + for w in want: + if w.get('associated_interfaces') is None: + continue + + if result['changed'] and not is_delay: + time.sleep(module.params['delay']) + is_delay = True + + if have is None: + have = map_config_to_obj(want, element_spec, module) + + for i in w['associated_interfaces']: + obj_in_have = search_obj_in_list(w['name'], have) + + if obj_in_have: + interfaces = obj_in_have.get('interfaces') + if interfaces is not None and i not in interfaces: + module.fail_json(msg="Interface %s not configured on vrf %s" % (i, w['name'])) def main(): @@ -433,6 +457,7 @@ def main(): rd=dict(type=str), admin_state=dict(default='up', choices=['up', 'down']), interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent']) ) @@ -472,8 +497,7 @@ def main(): load_config(module, commands) result['changed'] = True - if result['changed']: - check_declarative_intent_params(want, element_spec, module) + check_declarative_intent_params(want, module, element_spec, result) module.exit_json(**result) diff --git a/lib/ansible/modules/network/vyos/vyos_vlan.py b/lib/ansible/modules/network/vyos/vyos_vlan.py index e298d5dbf9..d2613ed663 100644 --- a/lib/ansible/modules/network/vyos/vyos_vlan.py +++ b/lib/ansible/modules/network/vyos/vyos_vlan.py @@ -38,6 +38,12 @@ options: description: - List of interfaces that should be associated to the VLAN. required: true + associated_interfaces: + description: + - This is a intent option and checks the operational state of the for given vlan C(name) + for associated interfaces. If the value in the C(associated_interfaces) does not match with + the operational state of vlan on device it will result in failure. + version_added: "2.5" delay: description: - Delay the play should wait to check for declarative intent params values. @@ -77,6 +83,20 @@ EXAMPLES = """ interfaces: eth1 address: 172.26.100.37/24 +- name: vlan interface config + intent + vyos_vlan: + vlan_id: 100 + interfaces: eth0 + associated_interfaces: + - eth0 + +- name: vlan intent check + vyos_vlan: + vlan_id: 100 + associated_interfaces: + - eth3 + - eth4 + - name: Delete vlan vyos_vlan: vlan_id: 100 @@ -166,6 +186,7 @@ def map_params_to_obj(module): d = item.copy() d['vlan_id'] = str(d['vlan_id']) + module._check_required_one_of(module.required_one_of, item) obj.append(d) else: @@ -174,7 +195,8 @@ def map_params_to_obj(module): 'name': module.params['name'], 'address': module.params['address'], 'state': module.params['state'], - 'interfaces': module.params['interfaces'] + 'interfaces': module.params['interfaces'], + 'associated_interfaces': module.params['associated_interfaces'] }) return obj @@ -213,26 +235,34 @@ def map_config_to_obj(module): return objs -def check_declarative_intent_params(want, module): - if module.params['interfaces']: - time.sleep(module.params['delay']) - have = map_config_to_obj(module) +def check_declarative_intent_params(want, module, result): - want_interface = list() - obj_interface = list() + have = None + obj_interface = list() + is_delay = False - for w in want: - for i in w['interfaces']: - want_interface.append(i) - obj_in_have = search_obj_in_list(w['vlan_id'], have) - if obj_in_have: - for obj in obj_in_have: - obj_interface.extend(obj['interfaces']) + for w in want: + if w.get('associated_interfaces') is None: + continue - for w in want: - for i in w['interfaces']: - if (set(obj_interface) - set(want_interface)) != set([]): - module.fail_json(msg='Interface {0} not configured on vlan {1}'.format(i, w['vlan_id'])) + if result['changed'] and not is_delay: + time.sleep(module.params['delay']) + is_delay = True + + if have is None: + have = map_config_to_obj(module) + + obj_in_have = search_obj_in_list(w['vlan_id'], have) + if obj_in_have: + for obj in obj_in_have: + obj_interface.extend(obj['interfaces']) + + for w in want: + if w.get('associated_interfaces') is None: + continue + for i in w['associated_interfaces']: + if (set(obj_interface) - set(w['associated_interfaces'])) != set([]): + module.fail_json(msg='Interface {0} not configured on vlan {1}'.format(i, w['vlan_id'])) def main(): @@ -242,7 +272,8 @@ def main(): vlan_id=dict(type='int', required=True), name=dict(), address=dict(), - interfaces=dict(type='list', required=True), + interfaces=dict(type='list'), + associated_interfaces=dict(type='list'), delay=dict(default=10, type='int'), state=dict(default='present', choices=['present', 'absent']) @@ -261,7 +292,9 @@ def main(): argument_spec.update(element_spec) argument_spec.update(vyos_argument_spec) - required_one_of = [['vlan_id', 'aggregate']] + required_one_of = [['vlan_id', 'aggregate'], + ['interfaces', 'associated_interfaces']] + mutually_exclusive = [['vlan_id', 'aggregate']] module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, @@ -285,10 +318,10 @@ def main(): load_config(module, commands, commit=commit) result['changed'] = True - if result['changed']: - check_declarative_intent_params(want, module) + check_declarative_intent_params(want, module, result) module.exit_json(**result) + if __name__ == '__main__': main() diff --git a/test/integration/targets/eos_vlan/tests/cli/basic.yaml b/test/integration/targets/eos_vlan/tests/cli/basic.yaml index 7da49d6080..b3821230e6 100644 --- a/test/integration/targets/eos_vlan/tests/cli/basic.yaml +++ b/test/integration/targets/eos_vlan/tests/cli/basic.yaml @@ -118,13 +118,16 @@ # Ensure sessions contains epoc. Will fail after 18th May 2033 - "'ansible_1' in result.session_name" -- name: Add interfaces to vlan +- name: Add interfaces to vlan and check state eos_vlan: vlan_id: 4000 state: present interfaces: - Ethernet1 - Ethernet2 + associated_interfaces: + - Ethernet1 + - Ethernet2 authorize: yes provider: "{{ cli }}" become: yes @@ -160,6 +163,22 @@ # Ensure sessions contains epoc. Will fail after 18th May 2033 - "result.session_name is not defined" +- name: vlan interface intent fail + eos_vlan: + vlan_id: 4000 + state: present + associated_interfaces: + - test + authorize: yes + provider: "{{ cli }}" + become: yes + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == True" + - name: Remove interface from vlan eos_vlan: vlan_id: 4000 diff --git a/test/integration/targets/eos_vrf/tests/cli/basic.yaml b/test/integration/targets/eos_vrf/tests/cli/basic.yaml index 2413864c4a..efcf721007 100644 --- a/test/integration/targets/eos_vrf/tests/cli/basic.yaml +++ b/test/integration/targets/eos_vrf/tests/cli/basic.yaml @@ -85,7 +85,7 @@ # Ensure sessions contains epoc. Will fail after 18th May 2033 - "result.session_name is not defined" -- name: Add Ethernet2 to vrf +- name: Add Ethernet2 to vrf and check interface assigned state eos_vrf: name: test rd: 1:201 @@ -93,6 +93,8 @@ authorize: yes interfaces: - Ethernet2 + associated_interfaces: + - Ethernet2 provider: "{{ cli }}" become: yes register: result @@ -124,6 +126,22 @@ # Ensure sessions contains epoc. Will fail after 18th May 2033 - "'session_name' not in result.commands" +- name: vrf interface intent fail + eos_vrf: + name: test + state: present + authorize: yes + associated_interfaces: + - test + provider: "{{ cli }}" + become: yes + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == True" + - name: Add multiple interfaces to vrf eos_vrf: name: test1 diff --git a/test/integration/targets/ios_vlan/tests/cli/basic.yaml b/test/integration/targets/ios_vlan/tests/cli/basic.yaml index 599a869114..1634b091fe 100644 --- a/test/integration/targets/ios_vlan/tests/cli/basic.yaml +++ b/test/integration/targets/ios_vlan/tests/cli/basic.yaml @@ -72,6 +72,31 @@ that: - "result.changed == false" + - name: Check interface assigned to vrf (intent) + ios_vlan: + vlan_id: 100 + associated_interfaces: + - GigabitEthernet0/1 + - GigabitEthernet0/2 + provider: "{{ cli }}" + register: result + + - assert: + that: + - "result.failed == false" + + - name: Check interface assigned to vrf (fail) + ios_vlan: + vlan_id: 100 + associated_interfaces: + - test + provider: "{{ cli }}" + register: result + + - assert: + that: + - "result.failed == True" + - name: Remove interface from vlan ios_vlan: &single_int vlan_id: 100 diff --git a/test/integration/targets/nxos_vlan/tests/common/interface.yaml b/test/integration/targets/nxos_vlan/tests/common/interface.yaml index 7adc108b8a..cba7372ce5 100644 --- a/test/integration/targets/nxos_vlan/tests/common/interface.yaml +++ b/test/integration/targets/nxos_vlan/tests/common/interface.yaml @@ -29,12 +29,15 @@ vlan_id: 100 provider: "{{ connection }}" -- name: Add interfaces to vlan +- name: Add interfaces to vlan and check intent (config + intent) nxos_vlan: &interfaces vlan_id: 100 interfaces: - "{{ testint1 }}" - "{{ testint2 }}" + associated_interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" provider: "{{ connection }}" register: result @@ -58,6 +61,32 @@ that: - 'result.changed == false' +- name: Check interfaces intent + nxos_vlan: + vlan_id: 100 + associated_interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" + provider: "{{ connection }}" + register: result + +- assert: + that: + - "result.failed == false" + +- name: Check interfaces intent fail + nxos_vlan: + vlan_id: 100 + associated_interfaces: + - test + provider: "{{ connection }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == True" + - name: Remove interface from vlan nxos_vlan: &single_int vlan_id: 100 diff --git a/test/integration/targets/nxos_vrf/tests/common/intent.yaml b/test/integration/targets/nxos_vrf/tests/common/intent.yaml index 25da09f865..5fa5a00581 100644 --- a/test/integration/targets/nxos_vrf/tests/common/intent.yaml +++ b/test/integration/targets/nxos_vrf/tests/common/intent.yaml @@ -64,18 +64,22 @@ that: - "result.changed == false" -- name: Assign interfaces to VRF +- name: Assign interfaces to VRF (Config + intent) nxos_vrf: &interfaces name: test1 interfaces: - "{{ testint1 }}" - "{{ testint2 }}" + associated_interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" provider: "{{ connection }}" register: result - assert: that: - 'result.changed == true' + - "result.failed == false" - '"interface {{ testint1 }}" in result.commands' - '"vrf member test1" in result.commands' - '"interface {{ testint2 }}" in result.commands' @@ -89,6 +93,32 @@ that: - 'result.changed == false' +- name: Check interfaces assigned to VRF (intent) + nxos_vrf: + name: test1 + associated_interfaces: + - "{{ testint1 }}" + - "{{ testint2 }}" + provider: "{{ connection }}" + register: result + +- assert: + that: + - "result.failed == false" + +- name: Assign interfaces to VRF (intent fail) + nxos_vrf: + name: test1 + associated_interfaces: + - test + provider: "{{ connection }}" + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == True" + - name: Remove interface from vrf nxos_vrf: &single_int name: test1 diff --git a/test/integration/targets/vyos_vlan/tests/cli/intent.yaml b/test/integration/targets/vyos_vlan/tests/cli/intent.yaml new file mode 100644 index 0000000000..98c8697d18 --- /dev/null +++ b/test/integration/targets/vyos_vlan/tests/cli/intent.yaml @@ -0,0 +1,59 @@ +--- +- debug: msg="START cli/intent.yaml on connection={{ ansible_connection }}" + +- name: setup - remove vlan used in test + vyos_config: &delete + lines: + - delete interfaces ethernet eth1 vif 100 + - delete interfaces ethernet eth0 vif 100 + +- name: set vlan with name + vyos_vlan: + vlan_id: 100 + name: vlan-100 + interfaces: eth1 + register: result + +- assert: + that: + - "result.changed == true" + - "'set interfaces ethernet eth1 vif 100 description vlan-100' in result.commands" + +- name: check vlan interface intent + vyos_vlan: + vlan_id: 100 + name: vlan-100 + associated_interfaces: eth1 + register: result + +- assert: + that: + - "result.failed == false" + +- name: vlan interface config + intent + vyos_vlan: + vlan_id: 100 + interfaces: eth0 + associated_interfaces: + - eth0 + - eth1 + register: result + +- assert: + that: + - "result.failed == false" + +- name: vlan intent fail + vyos_vlan: + vlan_id: 100 + associated_interfaces: + - eth3 + - eth4 + register: result + ignore_errors: yes + +- assert: + that: + - "result.failed == True" + +- debug: msg="End cli/intent.yaml on connection={{ ansible_connection }}"