summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrishna Guha <trishnaguha17@gmail.com>2017-05-05 15:38:30 +0530
committerGitHub <noreply@github.com>2017-05-05 15:38:30 +0530
commitad0a01ffb5f84755ad914858f957ed5c74166433 (patch)
treefb30d2a6be3ac7511251c4aa7ac574e9b68957fc
parent1582e9bf7d94dcb5bd17c89c6f9289e112d9ec2e (diff)
downloadansible-ad0a01ffb5f84755ad914858f957ed5c74166433.tar.gz
nxos_vrf refactor (#24280)
* nxos_vrf refactor Signed-off-by: Trishna Guha <trishnaguha17@gmail.com> * Unit test for nxos_vrf Remove unnecessary keys() method Signed-off-by: Trishna Guha <trishnaguha17@gmail.com>
-rw-r--r--lib/ansible/modules/network/nxos/nxos_vrf.py205
-rw-r--r--test/units/modules/network/nxos/test_nxos_vrf.py64
2 files changed, 142 insertions, 127 deletions
diff --git a/lib/ansible/modules/network/nxos/nxos_vrf.py b/lib/ansible/modules/network/nxos/nxos_vrf.py
index 3d25fb4f1c..1acfcf7af1 100644
--- a/lib/ansible/modules/network/nxos/nxos_vrf.py
+++ b/lib/ansible/modules/network/nxos/nxos_vrf.py
@@ -16,9 +16,11 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
#
-ANSIBLE_METADATA = {'metadata_version': '1.0',
- 'status': ['preview'],
- 'supported_by': 'community'}
+ANSIBLE_METADATA = {
+ 'metadata_version': '1.0',
+ 'status': ['preview'],
+ 'supported_by': 'community'
+}
DOCUMENTATION = '''
@@ -28,96 +30,71 @@ extends_documentation_fragment: nxos
version_added: "2.1"
short_description: Manages global VRF configuration.
description:
- - Manages global VRF configuration.
+ - Manages global VRF configuration.
author:
- - Jason Edelman (@jedelman8)
- - Gabriele Gerbino (@GGabriele)
+ - Jason Edelman (@jedelman8)
+ - Gabriele Gerbino (@GGabriele)
notes:
- - Cisco NX-OS creates the default VRF by itself. Therefore,
- you're not allowed to use default as I(vrf) name in this module.
- - C(vrf) name must be shorter than 32 chars.
- - VRF names are not case sensible in NX-OS. Anyway, the name is stored
- just like it's inserted by the user and it'll not be changed again
- unless the VRF is removed and re-created. i.e. C(vrf=NTC) will create
- a VRF named NTC, but running it again with C(vrf=ntc) will not cause
- a configuration change.
+ - Cisco NX-OS creates the default VRF by itself. Therefore,
+ you're not allowed to use default as I(vrf) name in this module.
+ - C(vrf) name must be shorter than 32 chars.
+ - VRF names are not case sensible in NX-OS. Anyway, the name is stored
+ just like it's inserted by the user and it'll not be changed again
+ unless the VRF is removed and re-created. i.e. C(vrf=NTC) will create
+ a VRF named NTC, but running it again with C(vrf=ntc) will not cause
+ a configuration change.
options:
- vrf:
- description:
- - Name of VRF to be managed.
- required: true
- admin_state:
- description:
- - Administrative state of the VRF.
- required: false
- default: up
- choices: ['up','down']
- vni:
- description:
- - Specify virtual network identifier. Valid values are Integer
- or keyword 'default'.
- required: false
- default: null
- version_added: "2.2"
- route_distinguisher:
- description:
- - VPN Route Distinguisher (RD). Valid values are a string in
- one of the route-distinguisher formats (ASN2:NN, ASN4:NN, or
- IPV4:NN); the keyword 'auto', or the keyword 'default'.
- required: false
- default: null
- version_added: "2.2"
- state:
- description:
- - Manages desired state of the resource.
- required: false
- default: present
- choices: ['present','absent']
+ vrf:
description:
- description:
- - Description of the VRF.
- required: false
- default: null
+ - Name of VRF to be managed.
+ required: true
+ admin_state:
+ description:
+ - Administrative state of the VRF.
+ required: false
+ default: up
+ choices: ['up','down']
+ vni:
+ description:
+ - Specify virtual network identifier. Valid values are Integer
+ or keyword 'default'.
+ required: false
+ default: null
+ version_added: "2.2"
+ route_distinguisher:
+ description:
+ - VPN Route Distinguisher (RD). Valid values are a string in
+ one of the route-distinguisher formats (ASN2:NN, ASN4:NN, or
+ IPV4:NN); the keyword 'auto', or the keyword 'default'.
+ required: false
+ default: null
+ version_added: "2.2"
+ state:
+ description:
+ - Manages desired state of the resource.
+ required: false
+ default: present
+ choices: ['present','absent']
+ description:
+ description:
+ - Description of the VRF.
+ required: false
+ default: null
'''
EXAMPLES = '''
- name: Ensure ntc VRF exists on switch
nxos_vrf:
vrf: ntc
- username: "{{ un }}"
- password: "{{ pwd }}"
- host: "{{ inventory_hostname }}"
+ state: present
'''
RETURN = '''
-proposed:
- description: k/v pairs of parameters passed into module
- returned: always
- type: dict
- sample: {"admin_state": "Up", "description": "Test test",
- "vrf": "ntc"}
-existing:
- description: k/v pairs of existing vrf
- returned: always
- type: dict
- sample: {"admin_state": "Up", "description": "Old test",
- "vrf": "old_ntc"}
-end_state:
- description: k/v pairs of vrf info after module execution
- returned: always
- type: dict
- sample: {"admin_state": "Up", "description": "Test test",
- "vrf": "ntc"}
-updates:
+commands:
description: commands sent to the device
returned: always
type: list
sample: ["vrf context ntc", "shutdown"]
-changed:
- description: check to see if a change was made on the device
- returned: always
- type: boolean
- sample: true
'''
import re
@@ -139,14 +116,10 @@ def execute_show_command(command, module):
def apply_key_map(key_map, table):
new_dict = {}
- for key, value in table.items():
+ for key in table:
new_key = key_map.get(key)
if new_key:
- value = table.get(key)
- if value:
- new_dict[new_key] = str(value)
- else:
- new_dict[new_key] = value
+ new_dict[new_key] = str(table.get(key))
return new_dict
@@ -177,29 +150,29 @@ def get_vrf_description(vrf, module):
description = ''
descr_regex = r".*description\s(?P<descr>[\S+\s]+).*"
- body = execute_show_command(command, module)
try:
- body = body[0]
- splitted_body = body.split('\n')
- except (AttributeError, IndexError):
+ body = execute_show_command(command, module)[0]
+ except IndexError:
return description
- for element in splitted_body:
- if 'description' in element:
- match_description = re.match(descr_regex, element,
- re.DOTALL)
- group_description = match_description.groupdict()
- description = group_description["descr"]
+ if body:
+ splitted_body = body.split('\n')
+ for element in splitted_body:
+ if 'description' in element:
+ match_description = re.match(descr_regex, element,
+ re.DOTALL)
+ group_description = match_description.groupdict()
+ description = group_description["descr"]
return description
def get_value(arg, config, module):
- REGEX = re.compile(r'(?:{0}\s)(?P<value>.*)$'.format(arg), re.M)
+ extra_arg_regex = re.compile(r'(?:{0}\s)(?P<value>.*)$'.format(arg), re.M)
value = ''
if arg in config:
- value = REGEX.search(config).group('value')
+ value = extra_arg_regex.search(config).group('value')
return value
@@ -210,19 +183,19 @@ def get_vrf(vrf, module):
'vrf_state': 'admin_state'
}
- body = execute_show_command(command, module)
try:
- vrf_table = body[0]['TABLE_vrf']['ROW_vrf']
+ body = execute_show_command(command, module)[0]
+ vrf_table = body['TABLE_vrf']['ROW_vrf']
except (TypeError, IndexError):
return {}
parsed_vrf = apply_key_map(vrf_key, vrf_table)
command = 'show run all | section vrf.context.{0}'.format(vrf)
- body = execute_show_command(command, module)
+ body = execute_show_command(command, module)[0]
extra_params = ['vni', 'rd', 'description']
for param in extra_params:
- parsed_vrf[param] = get_value(param, body[0], module)
+ parsed_vrf[param] = get_value(param, body, module)
return parsed_vrf
@@ -233,10 +206,8 @@ def main():
description=dict(default=None, required=False),
vni=dict(required=False, type='str'),
rd=dict(required=False, type='str'),
- admin_state=dict(default='up', choices=['up', 'down'],
- required=False),
- state=dict(default='present', choices=['present', 'absent'],
- required=False),
+ admin_state=dict(default='up', choices=['up', 'down'], required=False),
+ state=dict(default='present', choices=['present', 'absent'], required=False),
include_defaults=dict(default=False),
config=dict(),
save=dict(type='bool', default=False)
@@ -244,11 +215,11 @@ def main():
argument_spec.update(nxos_argument_spec)
- module = AnsibleModule(argument_spec=argument_spec,
- supports_check_mode=True)
+ module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
warnings = list()
check_args(module, warnings)
+ results = dict(changed=False, warnings=warnings)
vrf = module.params['vrf']
@@ -261,27 +232,15 @@ def main():
if vrf == 'default':
module.fail_json(msg='cannot use default as name of a VRF')
elif len(vrf) > 32:
- module.fail_json(msg='VRF name exceeded max length of 32',
- vrf=vrf)
+ module.fail_json(msg='VRF name exceeded max length of 32', vrf=vrf)
existing = get_vrf(vrf, module)
args = dict(vrf=vrf, description=description, vni=vni,
admin_state=admin_state, rd=rd)
- end_state = existing
- changed = False
proposed = dict((k, v) for k, v in args.items() if v is not None)
- """Since 'admin_state' is either 'Up' or 'Down' from outputs,
- we use the following to make sure right letter case is used so that delta
- results will be consistent to the actual configuration."""
- if existing:
- if existing['admin_state'].lower() == admin_state:
- proposed['admin_state'] = existing['admin_state']
-
delta = dict(set(proposed.items()).difference(existing.items()))
- changed = False
- end_state = existing
commands = []
if state == 'absent':
if existing:
@@ -304,22 +263,14 @@ def main():
module.exit_json(changed=True, commands=commands)
else:
load_config(module, commands)
- changed = True
- end_state = get_vrf(vrf, module)
+ results['changed'] = True
if 'configure' in commands:
commands.pop(0)
- results = {}
- results['proposed'] = proposed
- results['existing'] = existing
- results['end_state'] = end_state
- results['updates'] = commands
- results['changed'] = changed
- results['warnings'] = warnings
+ results['commands'] = commands
module.exit_json(**results)
if __name__ == '__main__':
main()
-
diff --git a/test/units/modules/network/nxos/test_nxos_vrf.py b/test/units/modules/network/nxos/test_nxos_vrf.py
new file mode 100644
index 0000000000..174fa1cd53
--- /dev/null
+++ b/test/units/modules/network/nxos/test_nxos_vrf.py
@@ -0,0 +1,64 @@
+# (c) 2016 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+# Make coding more python3-ish
+from __future__ import (absolute_import, division, print_function)
+__metaclass__ = type
+
+import json
+
+from ansible.compat.tests.mock import patch
+from ansible.modules.network.nxos import nxos_vrf
+from .nxos_module import TestNxosModule, load_fixture, set_module_args
+
+
+class TestNxosVrfModule(TestNxosModule):
+
+ module = nxos_vrf
+
+ def setUp(self):
+ self.mock_run_commands = patch('ansible.modules.network.nxos.nxos_vrf.run_commands')
+ self.run_commands = self.mock_run_commands.start()
+
+ self.mock_load_config = patch('ansible.modules.network.nxos.nxos_vrf.load_config')
+ self.load_config = self.mock_load_config.start()
+
+ self.mock_get_config = patch('ansible.modules.network.nxos.nxos_vrf.get_config')
+ self.get_config = self.mock_get_config.start()
+
+ def tearDown(self):
+ self.mock_run_commands.stop()
+ self.mock_load_config.stop()
+ self.mock_get_config.stop()
+
+ def load_fixtures(self, commands=None):
+ self.load_config.return_value = None
+
+ def test_nxos_vrf_present(self):
+ set_module_args(dict(vrf='ntc', state='present', admin_state='up'))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result['commands'], ['vrf context ntc', 'no shutdown'])
+
+ def test_nxos_vrf_absent(self):
+ set_module_args(dict(vrf='ntc', state='absent'))
+ result = self.execute_module(changed=True)
+ self.assertEqual(result['commands'], ['no vrf context ntc'])
+
+ def test_nxos_vrf_default(self):
+ set_module_args(dict(vrf='default'))
+ result = self.execute_module(failed=True)
+ self.assertEqual(result['msg'], 'cannot use default as name of a VRF')