diff options
author | Ansible Core Team <info@ansible.com> | 2020-03-09 09:40:29 +0000 |
---|---|---|
committer | Ansible Core Team <info@ansible.com> | 2020-03-09 09:40:29 +0000 |
commit | 6e048cc2689d033b7757174d582077dd4af494b5 (patch) | |
tree | 05eb51738d05d26c992b439214c3dd7ffd1af538 /lib/ansible/modules/network/cnos/cnos_vrf.py | |
parent | cb06e04e718f73173a6dcae1b082637063bae786 (diff) | |
download | ansible-6e048cc2689d033b7757174d582077dd4af494b5.tar.gz |
Migrated to community.general
Diffstat (limited to 'lib/ansible/modules/network/cnos/cnos_vrf.py')
-rw-r--r-- | lib/ansible/modules/network/cnos/cnos_vrf.py | 370 |
1 files changed, 0 insertions, 370 deletions
diff --git a/lib/ansible/modules/network/cnos/cnos_vrf.py b/lib/ansible/modules/network/cnos/cnos_vrf.py deleted file mode 100644 index 5196af0cab..0000000000 --- a/lib/ansible/modules/network/cnos/cnos_vrf.py +++ /dev/null @@ -1,370 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type -# -# Copyright (C) 2019 Lenovo. -# (c) 2017, Ansible by 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/>. -# -# Module to work on management of local users on Lenovo CNOS Switches -# Lenovo Networking -# -ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = """ ---- -module: cnos_vrf -version_added: "2.8" -author: "Anil Kumar Muraleedharan (@amuraleedhar)" -short_description: Manage VRFs on Lenovo CNOS network devices -description: - - This module provides declarative management of VRFs - on Lenovo CNOS network devices. -notes: - - Tested against CNOS 10.9.1 -options: - name: - description: - - Name of the VRF. - required: true - rd: - description: - - Route distinguisher of the VRF - interfaces: - description: - - 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. 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. - aggregate: - description: List of VRFs contexts - purge: - description: - - Purge VRFs not defined in the I(aggregate) parameter. - default: no - type: bool - delay: - description: - - Time in seconds to wait before checking for the operational state on - remote device. This wait is applicable for operational state arguments. - default: 10 - state: - description: - - State of the VRF configuration. - default: present - choices: ['present', 'absent'] -""" - -EXAMPLES = """ -- name: Create vrf - cnos_vrf: - name: test - rd: 1:200 - interfaces: - - Ethernet1/33 - state: present - -- name: Delete VRFs - cnos_vrf: - name: test - state: absent - -- name: Create aggregate of VRFs with purge - cnos_vrf: - aggregate: - - { name: test4, rd: "1:204" } - - { name: test5, rd: "1:205" } - state: present - purge: yes - -- name: Delete aggregate of VRFs - cnos_vrf: - aggregate: - - name: test2 - - name: test3 - - name: test4 - - name: test5 - state: absent -""" - -RETURN = """ -commands: - description: The list of configuration mode commands to send to the device - returned: always - type: list - sample: - - vrf context test - - rd 1:100 - - interface Ethernet1/44 - - vrf member test -""" -import re -import time - -from copy import deepcopy - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.network.common.utils import remove_default_spec -from ansible.module_utils.network.cnos.cnos import load_config, run_commands -from ansible.module_utils.network.cnos.cnos import cnos_argument_spec, check_args - - -def search_obj_in_list(name, lst): - for o in lst: - if o['name'] == name: - return o - - -def get_interface_type(interface): - intf_type = 'unknown' - if interface.upper()[:2] in ('ET', 'GI', 'FA', 'TE', 'FO', 'HU', 'TWE'): - intf_type = 'ethernet' - elif interface.upper().startswith('VL'): - intf_type = 'svi' - elif interface.upper().startswith('LO'): - intf_type = 'loopback' - elif interface.upper()[:2] in ('MG', 'MA'): - intf_type = 'management' - elif interface.upper().startswith('PO'): - intf_type = 'portchannel' - elif interface.upper().startswith('NV'): - intf_type = 'nve' - - return intf_type - - -def is_switchport(name, module): - intf_type = get_interface_type(name) - - if intf_type in ('ethernet', 'portchannel'): - config = run_commands(module, - ['show interface {0} switchport'.format(name)])[0] - match = re.search(r'Switchport : enabled', config) - return bool(match) - return False - - -def map_obj_to_commands(updates, module): - commands = list() - want, have = updates - state = module.params['state'] - purge = module.params['purge'] - - for w in want: - name = w['name'] - rd = w['rd'] - interfaces = w['interfaces'] - - obj_in_have = search_obj_in_list(name, have) - - if name == 'default': - module.fail_json(msg='VRF context default is reserved') - elif len(name) > 63: - module.fail_json(msg='VRF name is too long') - if state == 'absent': - if name == 'management': - module.fail_json(msg='Management VRF context cannot be deleted') - if obj_in_have: - commands.append('no vrf context %s' % name) - elif state == 'present': - if not obj_in_have: - commands.append('vrf context %s' % name) - - if rd is not None: - commands.append('rd %s' % rd) - - if w['interfaces']: - for i in w['interfaces']: - commands.append('interface %s' % i) - commands.append('vrf member %s' % w['name']) - else: - if w['rd'] is not None and w['rd'] != obj_in_have['rd']: - commands.append('vrf context %s' % w['name']) - commands.append('rd %s' % w['rd']) - - if w['interfaces']: - if not obj_in_have['interfaces']: - for i in w['interfaces']: - commands.append('interface %s' % i) - commands.append('vrf member %s' % w['name']) - elif set(w['interfaces']) != obj_in_have['interfaces']: - missing_interfaces = list(set(w['interfaces']) - set(obj_in_have['interfaces'])) - - for i in missing_interfaces: - commands.append('interface %s' % i) - commands.append('vrf member %s' % w['name']) - - if purge: - for h in have: - obj_in_want = search_obj_in_list(h['name'], want) - if not obj_in_want: - commands.append('no vrf context %s' % h['name']) - - return commands - - -def map_config_to_obj(module): - objs = [] - output = run_commands(module, {'command': 'show vrf'}) - if output is not None: - vrfText = output[0].strip() - vrfList = vrfText.split('VRF') - for vrfItem in vrfList: - if 'FIB ID' in vrfItem: - obj = dict() - list_of_words = vrfItem.split() - vrfName = list_of_words[0] - obj['name'] = vrfName[:-1] - obj['rd'] = list_of_words[list_of_words.index('RD') + 1] - start = False - obj['interfaces'] = [] - for intName in list_of_words: - if 'Interfaces' in intName: - start = True - if start is True: - if '!' not in intName and 'Interfaces' not in intName: - obj['interfaces'].append(intName.strip().lower()) - objs.append(obj) - else: - module.fail_json(msg='Could not fetch VRF details from device') - return objs - - -def map_params_to_obj(module): - obj = [] - aggregate = module.params.get('aggregate') - if aggregate: - for item in aggregate: - for key in item: - if item.get(key) is None: - item[key] = module.params[key] - - 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 [], - '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, 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 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(): - """ main entry point for module execution - """ - 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']) - ) - - aggregate_spec = deepcopy(element_spec) - - # remove default in aggregate spec, to handle common arguments - remove_default_spec(aggregate_spec) - - argument_spec = dict( - aggregate=dict(type='list', elements='dict', options=aggregate_spec), - purge=dict(default=False, type='bool') - ) - - argument_spec.update(element_spec) - - required_one_of = [['name', 'aggregate']] - mutually_exclusive = [['name', 'aggregate']] - module = AnsibleModule(argument_spec=argument_spec, - required_one_of=required_one_of, - mutually_exclusive=mutually_exclusive, - supports_check_mode=True) - - warnings = list() - check_args(module, warnings) - - result = {'changed': False} - - if warnings: - result['warnings'] = warnings - - want = map_params_to_obj(module) - for w in want: - name = w['name'] - name = name.lower() - if is_switchport(name, module): - module.fail_json(msg='Ensure interface is configured to be a L3' - '\nport first before using this module. You can use' - '\nthe cnos_interface module for this.') - have = map_config_to_obj(module) - - commands = map_obj_to_commands((want, have), module) - result['commands'] = commands - - if commands: - if not module.check_mode: - load_config(module, commands) - result['changed'] = True - check_declarative_intent_params(want, module, result) - module.exit_json(**result) - - -if __name__ == '__main__': - main() |