Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 4 commits into from
Feb 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 41 additions & 12 deletions lib/ansible/modules/network/eos/eos_vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@
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.
Expand Down Expand Up @@ -80,6 +87,13 @@
- 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
Expand Down Expand Up @@ -235,6 +249,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'])

Expand All @@ -244,23 +261,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:
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 w in want:
for i in w['interfaces']:
obj_in_have = search_obj_in_list(w['vlan_id'], have)
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']))
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():
Expand All @@ -270,6 +299,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'])
Expand Down Expand Up @@ -318,8 +348,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)

Expand Down
49 changes: 35 additions & 14 deletions lib/ansible/modules/network/eos/eos_vrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@
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:
Expand Down Expand Up @@ -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():
Expand All @@ -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'])
Expand Down Expand Up @@ -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)

Expand Down
49 changes: 38 additions & 11 deletions lib/ansible/modules/network/ios/ios_vlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@
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.
Expand All @@ -59,12 +65,21 @@
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
Expand Down Expand Up @@ -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']
})

Expand Down Expand Up @@ -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):

have = None
is_delay = False

for w in want:
if w.get('associated_interfaces') is None:
continue

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']))
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():
Expand All @@ -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'])
Expand Down Expand Up @@ -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()
26 changes: 19 additions & 7 deletions lib/ansible/modules/network/ios/ios_vrf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@
- 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
Expand Down Expand Up @@ -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
Expand All @@ -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))

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

Expand All @@ -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),
Expand Down Expand Up @@ -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()