Add ios_vrf declarative intent config check (#28001)

* Add ios_vrf declarative intent config check

Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>

* add version for delay param

* modify ios_vrf unit test
This commit is contained in:
Trishna Guha 2017-08-14 12:27:03 +05:30 committed by GitHub
parent eb33cc88bd
commit 12460dd713
2 changed files with 61 additions and 6 deletions

View file

@ -62,6 +62,11 @@ 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.
delay:
description:
- Time in seconds to wait before checking for the operational state on remote
device.
version_added: "2.4"
purge:
description:
- Instructs the module to consider the
@ -127,16 +132,37 @@ delta:
sample: "0:00:10.469466"
"""
import re
import time
from functools import partial
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.connection import exec_command
from ansible.module_utils.ios import load_config, get_config
from ansible.module_utils.ios import ios_argument_spec, check_args
from ansible.module_utils.netcfg import NetworkConfig
from ansible.module_utils.six import iteritems
def get_interface_type(interface):
if interface.upper().startswith('ET'):
return 'ethernet'
elif interface.upper().startswith('VL'):
return 'svi'
elif interface.upper().startswith('LO'):
return 'loopback'
elif interface.upper().startswith('MG'):
return 'management'
elif interface.upper().startswith('MA'):
return 'management'
elif interface.upper().startswith('PO'):
return 'portchannel'
elif interface.upper().startswith('NV'):
return 'nve'
else:
return 'unknown'
def add_command_to_vrf(name, cmd, commands):
if 'vrf definition %s' % name not in commands:
commands.append('vrf definition %s' % name)
@ -149,7 +175,8 @@ def map_obj_to_commands(updates, module):
for update in updates:
want, have = update
needs_update = lambda x: want.get(x) and (want.get(x) != have.get(x))
def needs_update(want, have, x):
return want.get(x) and (want.get(x) != have.get(x))
if want['state'] == 'absent':
commands.append('no vrf definition %s' % want['name'])
@ -158,11 +185,11 @@ def map_obj_to_commands(updates, module):
if not have.get('state'):
commands.append('vrf definition %s' % want['name'])
if needs_update('description'):
if needs_update(want, have, 'description'):
cmd = 'description %s' % want['description']
add_command_to_vrf(want['name'], cmd, commands)
if needs_update('rd'):
if needs_update(want, have, 'rd'):
cmd = 'rd %s' % want['rd']
add_command_to_vrf(want['name'], cmd, commands)
@ -300,18 +327,36 @@ def update_objects(want, have):
updates.append((entry, item))
return updates
def check_declarative_intent_params(want, module):
if module.params['interfaces']:
name = module.params['name']
rc, out, err = exec_command(module, 'show vrf | include {0}'.format(name))
if rc == 0:
data = out.strip().split()
vrf = data[0]
interface = data[-1]
for w in want:
if w['name'] == vrf:
for i in w['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))
def main():
""" main entry point for module execution
"""
argument_spec = dict(
vrfs=dict(type='list'),
name=dict(),
name=dict(),
description=dict(),
rd=dict(),
interfaces=dict(type='list'),
delay=dict(default=10, type='int'),
purge=dict(type='bool', default=False),
state=dict(default='present', choices=['present', 'absent'])
)
@ -350,6 +395,11 @@ def main():
load_config(module, commands)
result['changed'] = True
if result['changed']:
time.sleep(module.params['delay'])
check_declarative_intent_params(want, module)
module.exit_json(**result)
if __name__ == '__main__':

View file

@ -38,12 +38,17 @@ class TestIosVrfModule(TestIosModule):
self.mock_load_config = patch('ansible.modules.network.ios.ios_vrf.load_config')
self.load_config = self.mock_load_config.start()
self.mock_exec_command = patch('ansible.modules.network.ios.ios_vrf.exec_command')
self.exec_command = self.mock_exec_command.start()
def tearDown(self):
self.mock_get_config.stop()
self.mock_load_config.stop()
self.mock_exec_command.stop()
def load_fixtures(self, commands=None):
self.get_config.return_value = load_fixture('ios_vrf_config.cfg')
self.exec_command.return_value = (0, load_fixture('ios_vrf_config.cfg').strip(), None)
self.load_config.return_value = None
def test_ios_vrf_name(self):