Decouple config and state check in vlan and vrf network modules (#36386)

* Decouple config and state check in {network_os }_vlan and { network_os }_vrf modules

Fixes #35567
Fixes #34754

`interfaces` option is used for configuration as well as operational state
check. If interface is configured to given vlan or vrf but if
operational state of interface is disabled it results in module failure.

Fix is to decouple same option usage for config and state.
With this fix `interfaces` is used as config option and a new
option named `associated_interfaces` will be used for intent check
for assigned interfaces.

* Fix CI failures

* Fix review comment

* Fixed integration test failure
This commit is contained in:
Ganesh Nalawade 2018-02-26 09:23:54 +05:30 committed by GitHub
commit 5a6b893240
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 457 additions and 100 deletions

View file

@ -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)