From 3558651d393611b20e1a6d2c9553e4a281cab0f1 Mon Sep 17 00:00:00 2001 From: Adharsh Srivats R Date: Sun, 1 Mar 2020 10:22:25 -0500 Subject: [PATCH] nxos_lldp_interfaces resource module (#67802) * Added nxos_lldp_interfaces module * Linting * Added RTT, resolved shippable errors * Added new states * New states edit * Updated states * Updated tests * Show all interfaces in facts * Test changes * Added unit tests * Linting * Handled portchannel failing condition --- .../nxos/argspec/lldp_interfaces/__init__.py | 0 .../lldp_interfaces/lldp_interfaces.py | 75 +++++ .../nxos/config/lldp_interfaces/__init__.py | 0 .../config/lldp_interfaces/lldp_interfaces.py | 304 ++++++++++++++++++ .../module_utils/network/nxos/facts/facts.py | 2 + .../nxos/facts/lldp_interfaces/__init__.py | 0 .../facts/lldp_interfaces/lldp_interfaces.py | 121 +++++++ .../network/nxos/nxos_lldp_interfaces.py | 250 ++++++++++++++ .../nxos_lldp_interfaces/defaults/main.yaml | 2 + .../nxos_lldp_interfaces/meta/main.yml | 2 + .../nxos_lldp_interfaces/tasks/cli.yaml | 20 ++ .../nxos_lldp_interfaces/tasks/main.yaml | 2 + .../nxos_lldp_interfaces/tasks/nxapi.yaml | 33 ++ .../tests/cli/deleted.yml | 73 +++++ .../tests/cli/gathered.yml | 52 +++ .../nxos_lldp_interfaces/tests/cli/merged.yml | 60 ++++ .../tests/cli/overridden.yml | 66 ++++ .../nxos_lldp_interfaces/tests/cli/parsed.yml | 47 +++ .../tests/cli/remove_config.yaml | 8 + .../tests/cli/rendered.yml | 42 +++ .../tests/cli/replaced.yml | 62 ++++ .../nxos_lldp_interfaces/tests/cli/rtt.yml | 70 ++++ .../nxos_lldp_interfaces/vars/main.yml | 14 + .../network/nxos/test_nxos_lldp_interfaces.py | 236 ++++++++++++++ 24 files changed, 1541 insertions(+) create mode 100644 lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/__init__.py create mode 100644 lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/lldp_interfaces.py create mode 100644 lib/ansible/module_utils/network/nxos/config/lldp_interfaces/__init__.py create mode 100644 lib/ansible/module_utils/network/nxos/config/lldp_interfaces/lldp_interfaces.py create mode 100644 lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/__init__.py create mode 100644 lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/lldp_interfaces.py create mode 100644 lib/ansible/modules/network/nxos/nxos_lldp_interfaces.py create mode 100644 test/integration/targets/nxos_lldp_interfaces/defaults/main.yaml create mode 100644 test/integration/targets/nxos_lldp_interfaces/meta/main.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tasks/main.yaml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/deleted.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/gathered.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/merged.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/overridden.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/parsed.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/remove_config.yaml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/rendered.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/replaced.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/tests/cli/rtt.yml create mode 100644 test/integration/targets/nxos_lldp_interfaces/vars/main.yml create mode 100644 test/units/modules/network/nxos/test_nxos_lldp_interfaces.py diff --git a/lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/__init__.py b/lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/lldp_interfaces.py b/lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000000..ee223eafe59 --- /dev/null +++ b/lib/ansible/module_utils/network/nxos/argspec/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,75 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# +""" +The arg spec for the nxos_lldp_interfaces module +""" +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +class Lldp_interfacesArgs(object): # pylint: disable=R0903 + """The arg spec for the nxos_lldp_interfaces module + """ + + def __init__(self, **kwargs): + pass + + argument_spec = { + 'config': { + 'elements': 'dict', + 'options': { + 'name': { + 'required': True, + 'type': 'str' + }, + 'receive': { + 'type': 'bool' + }, + 'tlv_set': { + 'options': { + 'management_address': { + 'type': 'str' + }, + 'vlan': { + 'type': 'int' + } + }, + 'type': 'dict' + }, + 'transmit': { + 'type': 'bool' + } + }, + 'type': 'list' + }, + 'running_config': { + 'type': 'str' + }, + 'state': { + 'choices': ['deleted', 'gathered', 'merged', 'overridden', 'rendered', + 'replaced', 'parsed'], + 'default': 'merged', + 'type': 'str' + } + } # pylint: disable=C0301 diff --git a/lib/ansible/module_utils/network/nxos/config/lldp_interfaces/__init__.py b/lib/ansible/module_utils/network/nxos/config/lldp_interfaces/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/ansible/module_utils/network/nxos/config/lldp_interfaces/lldp_interfaces.py b/lib/ansible/module_utils/network/nxos/config/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000000..37e29ae5c60 --- /dev/null +++ b/lib/ansible/module_utils/network/nxos/config/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,304 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The nxos_lldp_interfaces class +It is in this file where the current configuration (as dict) +is compared to the provided configuration (as dict) and the command set +necessary to bring the current configuration to it's desired end-state is +created +""" +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +from ansible.module_utils.network.common.cfg.base import ConfigBase +from ansible.module_utils.network.common.utils import to_list, remove_empties, dict_diff +from ansible.module_utils.network.nxos.facts.facts import Facts +from ansible.module_utils.network.nxos.utils.utils import flatten_dict, search_obj_in_list, get_interface_type, normalize_interface + + +class Lldp_interfaces(ConfigBase): + """ + The nxos_lldp_interfaces class + """ + + gather_subset = [ + '!all', + '!min', + ] + + gather_network_resources = [ + 'lldp_interfaces', + ] + + def __init__(self, module): + super(Lldp_interfaces, self).__init__(module) + + def get_lldp_interfaces_facts(self, data=None): + """ Get the 'facts' (the current configuration) + + :rtype: A dictionary + :returns: The current configuration as a dictionary + """ + facts, _warnings = Facts(self._module).get_facts( + self.gather_subset, self.gather_network_resources, data=data) + lldp_interfaces_facts = facts['ansible_network_resources'].get( + 'lldp_interfaces') + if not lldp_interfaces_facts: + return [] + return lldp_interfaces_facts + + def edit_config(self, commands): + """Wrapper method for `_connection.edit_config()` + This exists solely to allow the unit test framework to mock device connection calls. + """ + return self._connection.edit_config(commands) + + def execute_module(self): + """ Execute the module + + :rtype: A dictionary + :returns: The result from module execution + """ + result = {'changed': False} + commands = list() + warnings = list() + state = self._module.params['state'] + action_states = ['merged', 'replaced', 'deleted', 'overridden'] + + if state == 'gathered': + result['gathered'] = self.get_lldp_interfaces_facts() + elif state == 'rendered': + result['rendered'] = self.set_config({}) + elif state == 'parsed': + result['parsed'] = self.set_config({}) + else: + existing_lldp_interfaces_facts = self.get_lldp_interfaces_facts() + commands.extend(self.set_config(existing_lldp_interfaces_facts)) + if commands and state in action_states: + if not self._module.check_mode: + self._connection.edit_config(commands) + result['changed'] = True + result['before'] = existing_lldp_interfaces_facts + result['commands'] = commands + result['commands'] = commands + + changed_lldp_interfaces_facts = self.get_lldp_interfaces_facts() + + if result['changed']: + result['after'] = changed_lldp_interfaces_facts + + result['warnings'] = warnings + return result + + def set_config(self, existing_lldp_interfaces_facts): + """ Collect the configuration from the args passed to the module, + collect the current configuration (as a dict from facts) + + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + config = self._module.params['config'] + want = [] + if config: + for w in config: + if get_interface_type(w['name']) not in ('management', + 'ethernet'): + self._module.fail_json( + msg='This module works with either management or ethernet') + w.update({'name': normalize_interface(w['name'])}) + want.append(remove_empties(w)) + have = existing_lldp_interfaces_facts + resp = self.set_state(want, have) + return to_list(resp) + + def set_state(self, want, have): + """ Select the appropriate function based on the state provided + + :param want: the desired configuration as a dictionary + :param have: the current configuration as a dictionary + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + commands = [] + state = self._module.params['state'] + if state == 'overridden': + commands = self._state_overridden(want, have) + elif state == 'deleted': + commands = self._state_deleted(want, have) + elif state == 'rendered': + commands = self._state_rendered(want) + elif state == 'parsed': + want = self._module.params['running_config'] + commands = self._state_parsed(want) + else: + for w in want: + if state == 'merged': + commands.extend(self._state_merged(flatten_dict(w), have)) + elif state == 'replaced': + commands.extend(self._state_replaced( + flatten_dict(w), have)) + return commands + + def _state_parsed(self, want): + return self.get_lldp_interfaces_facts(want) + + def _state_rendered(self, want): + commands = [] + for w in want: + commands.extend(self.set_commands(w, {})) + return commands + + def _state_gathered(self, have): + """ The command generator when state is gathered + + :rtype: A list + :returns: the commands necessary to reproduce the current configuration + """ + commands = [] + want = {} + commands.append(self.set_commands(want, have)) + return commands + + def _state_replaced(self, want, have): + """ The command generator when state is replaced + + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + commands = [] + del_commands = [] + delete_dict = {} + obj_in_have = flatten_dict( + search_obj_in_list(want['name'], have, 'name')) + for k1 in obj_in_have.keys(): + if k1 not in want.keys(): + delete_dict.update({k1: obj_in_have[k1]}) + + if delete_dict: + delete_dict.update({'name': want['name']}) + del_commands = self.del_commands(delete_dict) + merged_commands = self.set_commands(want, have) + + if merged_commands: + cmds = set(del_commands).intersection(set(merged_commands)) + for cmd in cmds: + merged_commands.remove(cmd) + + commands.extend(del_commands) + commands.extend(merged_commands) + return commands + + def _state_overridden(self, want, have): + """ The command generator when state is overridden + + :rtype: A list + :returns: the commands necessary to migrate the current configuration + to the desired configuration + """ + commands = [] + want_intfs = [w['name'] for w in want] + for h in have: + h = flatten_dict(h) + delete_dict = {} + if h['name'] in want_intfs: + for w in want: + if w['name'] == h['name']: + delete_keys = list(set(h) - set(flatten_dict(w))) + for k in delete_keys: + delete_dict.update({k: h[k]}) + delete_dict.update({'name': h['name']}) + break + else: + delete_dict.update(h) + commands.extend(self.del_commands(delete_dict)) + for w in want: + commands.extend(self.set_commands(flatten_dict(w), have)) + return commands + + def _state_merged(self, want, have): + """ The command generator when state is merged + + :rtype: A list + :returns: the commands necessary to merge the provided into + the current configuration + """ + return self.set_commands(want, have) + + def _state_deleted(self, want, have): + """ The command generator when state is deleted + + :rtype: A list + :returns: the commands necessary to remove the current configuration + of the provided objects + """ + commands = [] + if want: + for w in want: + obj_in_have = flatten_dict( + search_obj_in_list(w['name'], have, 'name')) + commands.extend(self.del_commands(obj_in_have)) + else: + if not have: + return commands + for h in have: + commands.extend(self.del_commands(flatten_dict(h))) + return commands + + def set_commands(self, want, have): + commands = [] + obj_in_have = flatten_dict( + search_obj_in_list(want['name'], have, 'name')) + if not obj_in_have: + commands = self.add_commands(flatten_dict(want)) + else: + diff = dict_diff(obj_in_have, want) + if diff: + diff.update({'name': want['name']}) + commands = self.add_commands(diff) + return commands + + def add_commands(self, d): + commands = [] + if not d: + return commands + commands.append('interface ' + d['name']) + if 'transmit' in d: + if (d['transmit']): + commands.append('lldp transmit') + else: + commands.append('no lldp transmit') + if 'receive' in d: + if (d['receive']): + commands.append('lldp receive') + else: + commands.append('no lldp receive') + if 'management_address' in d: + commands.append('lldp tlv-set management-address ' + + d['management_address']) + if 'vlan' in d: + commands.append('lldp tlv-set vlan ' + str(d['vlan'])) + + return commands + + def del_commands(self, obj): + commands = [] + if not obj or len(obj.keys()) == 1: + return commands + commands.append('interface ' + obj['name']) + if 'transmit' in obj: + commands.append('lldp transmit') + if 'receive' in obj: + commands.append('lldp receive') + if 'management_address' in obj: + commands.append('no lldp tlv-set management-address ' + + obj['management_address']) + if 'vlan' in obj: + commands.append('no lldp tlv-set vlan ' + str(obj['vlan'])) + + return commands diff --git a/lib/ansible/module_utils/network/nxos/facts/facts.py b/lib/ansible/module_utils/network/nxos/facts/facts.py index 84d6fd32778..e36d7b3357f 100644 --- a/lib/ansible/module_utils/network/nxos/facts/facts.py +++ b/lib/ansible/module_utils/network/nxos/facts/facts.py @@ -22,6 +22,7 @@ from ansible.module_utils.network.nxos.facts.telemetry.telemetry import Telemetr from ansible.module_utils.network.nxos.facts.vlans.vlans import VlansFacts from ansible.module_utils.network.nxos.facts.lacp_interfaces.lacp_interfaces import Lacp_interfacesFacts from ansible.module_utils.network.nxos.facts.lldp_global.lldp_global import Lldp_globalFacts +from ansible.module_utils.network.nxos.facts.lldp_interfaces.lldp_interfaces import Lldp_interfacesFacts FACT_LEGACY_SUBSETS = dict( @@ -44,6 +45,7 @@ FACT_RESOURCE_SUBSETS = dict( interfaces=InterfacesFacts, l3_interfaces=L3_interfacesFacts, l2_interfaces=L2_interfacesFacts, + lldp_interfaces=Lldp_interfacesFacts, ) diff --git a/lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/__init__.py b/lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/lldp_interfaces.py b/lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/lldp_interfaces.py new file mode 100644 index 00000000000..63ee03e7f6b --- /dev/null +++ b/lib/ansible/module_utils/network/nxos/facts/lldp_interfaces/lldp_interfaces.py @@ -0,0 +1,121 @@ +# +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +""" +The nxos lldp_interfaces fact class +It is in this file the configuration is collected from the device +for a given resource, parsed, and the facts tree is populated +based on the configuration. +""" +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +import re +from copy import deepcopy + +from ansible.module_utils.network.common import utils +from ansible.module_utils.network.nxos.argspec.lldp_interfaces.lldp_interfaces import Lldp_interfacesArgs +from ansible.module_utils.network.nxos.utils.utils import get_interface_type + + +class Lldp_interfacesFacts(object): + """ The nxos lldp_interfaces fact class + """ + + def __init__(self, module, subspec='config', options='options'): + self._module = module + self.argument_spec = Lldp_interfacesArgs.argument_spec + spec = deepcopy(self.argument_spec) + if subspec: + if options: + facts_argument_spec = spec[subspec][options] + else: + facts_argument_spec = spec[subspec] + else: + facts_argument_spec = spec + + self.generated_spec = utils.generate_dict(facts_argument_spec) + + def get_device_data(self, connection): + return connection.get('show running-config | section ^interface') + + def populate_facts(self, connection, ansible_facts, data=None): + """ Populate the facts for lldp_interfaces + :param connection: the device connection + :param ansible_facts: Facts dictionary + :param data: previously collected conf + :rtype: dictionary + :returns: facts + """ + if not data: + data = self.get_device_data(connection) + + objs = [] + + data = data.split('interface') + resources = [] + + for i in range(len(data)): + intf = data[i].split('\n') + for l in range(1, len(intf)): + if not re.search('lldp', intf[l]): + intf[l] = '' + intf = list(filter(None, intf)) + intf = ''.join(i for i in intf) + resources.append(intf) + + for resource in resources: + if resource: # and re.search(r'lldp', resource): + obj = self.render_config(self.generated_spec, resource) + if obj and len(obj.keys()) >= 1: + objs.append(obj) + + ansible_facts['ansible_network_resources'].pop('lldp_interfaces', None) + facts = {} + if objs: + facts['lldp_interfaces'] = [] + params = utils.validate_config( + self.argument_spec, {'config': objs}) + for cfg in params['config']: + facts['lldp_interfaces'].append(utils.remove_empties(cfg)) + + ansible_facts['ansible_network_resources'].update(facts) + + return ansible_facts + + def render_config(self, spec, conf): + """ + Render config as dictionary structure and delete keys + from spec for null values + + :param spec: The facts tree, generated from the argspec + :param conf: The configuration + :rtype: dictionary + :returns: The generated config + """ + config = deepcopy(spec) + match = re.search(r'^ (\S+)', conf) + if match is None: + return {} + intf = match.group(1) + if get_interface_type(intf) not in ['management', 'ethernet']: + return {} + config['name'] = intf + if 'lldp receive' in conf: # for parsed state only + config['receive'] = True + if 'no lldp receive' in conf: + config['receive'] = False + + if 'lldp transmit' in conf: # for parsed state only + config['transmit'] = True + if 'no lldp transmit' in conf: + config['transmit'] = False + if 'management-address' in conf: + config['tlv_set']['management_address'] = re.search( + r'management-address (\S*)', conf).group(1) + if 'vlan' in conf: + config['tlv_set']['vlan'] = re.search( + r'vlan (\S*)', conf).group(1) + return utils.remove_empties(config) diff --git a/lib/ansible/modules/network/nxos/nxos_lldp_interfaces.py b/lib/ansible/modules/network/nxos/nxos_lldp_interfaces.py new file mode 100644 index 00000000000..5c31015d57a --- /dev/null +++ b/lib/ansible/modules/network/nxos/nxos_lldp_interfaces.py @@ -0,0 +1,250 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# Copyright 2019 Red Hat +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +############################################# +# WARNING # +############################################# +# +# This file is auto generated by the resource +# module builder playbook. +# +# Do not edit this file manually. +# +# Changes to this file will be over written +# by the resource module builder. +# +# Changes should be made in the model used to +# generate this file or in the resource module +# builder template. +# +############################################# +""" +The module file for nxos_lldp_interfaces +""" + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'network' +} + +DOCUMENTATION = """ +--- +module: nxos_lldp_interfaces +version_added: "2.10" +short_description: Manages interfaces' configuration for Link Layer Discovery Protocol (LLDP) on NX-OS platforms. +description: This module manages interfaces' configuration for Link Layer Discovery Protocol (LLDP) on NX-OS platforms. +author: Adharsh Srivats Rangarajan (@adharshsrivatsr) +notes: + - Tested against NXOS 7.3.(0)D1(1) on VIRL + - The LLDP feature needs to be enabled before using this module +options: + running_config: + description: + - Used to parse given commands into structured format, only in parsed state + type: str + config: + description: + - A list of link layer discovery configurations for interfaces. + type: list + elements: dict + suboptions: + name: + description: + - Name of the interface + required: true + type: str + receive: + description: + - Used to enable or disable the reception of LLDP packets on that interface. By default, this is enabled after LLDP is enabled globally. + type: bool + transmit: + description: + - Used to enable or disable the transmission of LLDP packets on that interface. By default, this is enabled after LLDP is enabled globally. + type: bool + tlv_set: + description: + - Used to configure TLV parameters on the interface + type: dict + suboptions: + management_address: + description: + - Used to mention the IPv4 or IPv6 management address for the interface + type: str + vlan: + description: + - Used to mention the VLAN for the interface + type: int + state: + description: + - The state the configuration should be left in + type: str + choices: + - merged + - replaced + - overridden + - deleted + - gathered + - rendered + - parsed + default: merged +""" +EXAMPLES = """ +# Using merged + +# Before state: +# ------------- +# + +- name : Merge provided configuration with device configuration + nxos_lldp_interfaces: + config: + - name : Ethernet1/4 + receive: false + transmit: true + tlv_set: + management_address: 192.168.122.64 + vlan: 12 + state: merged + +# After state: +# ------------- +# +# interface Ethernet1/4 +# no lldp receive +# lldp tlv-set management-address 192.168.122.64 +# lldp tlv-set vlan 12 + + +# Using replaced + +# Before state: +# ------------ +# +# interface Ethernet1/4 +# no lldp receive +# lldp tlv-set management-address 192.168.122.64 +# interface Ethernet1/5 +# no lldp transmit +# lldp tlv-set vlan 10 + +- name: Replace LLDP configuration on interfaces with given configuration + nxos_lldp_interfaces: + config: + - name: Ethernet1/4 + transmit: no + tlv_set: + vlan: 2 + state: replaced + + +# After state: +# ----------- +# +# interface Ethernet1/4 +# no lldp transmit +# lldp tlv_set vlan 2 +# interface Ethernet1/5 +# no lldp transmit +# lldp tlv-set vlan 10 + + +# Using overridden + +# Before state: +# ------------ +# +# interface Ethernet1/4 +# no lldp receive +# lldp tlv-set management-address 192.168.122.64 +# interface Ethernet1/5 +# no lldp transmit +# lldp tlv-set vlan 10 + +- name: Override LLDP configuration on all interfaces with given configuration + nxos_lldp_interfaces: + config: + - name: Ethernet1/7 + receive: no + tlv_set: + vlan: 12 + state: overridden + + +# After state: +# ----------- +# +# interface Ethernet1/7 +# no lldp receive +# lldp tlv_set vlan 12 + + +# Using deleted + +# Before state: +# ------------ +# +# interface Ethernet1/4 +# lldp tlv-set management vlan 24 +# no lldp transmit +# interface mgmt0 +# no lldp receive + +- name: Delete LLDP interfaces configuration + nxos_lldp_interfaces: + state: deleted + +# After state: +# ------------ +# + + +""" +RETURN = """ +before: + description: The configuration prior to the model invocation. + returned: always + type: list + sample: > + The configuration returned will always be in the same format + of the parameters above. +after: + description: The resulting configuration model invocation. + returned: when changed + type: list + sample: > + The configuration returned will always be in the same format + of the parameters above. +commands: + description: The set of commands pushed to the remote device. + returned: always + type: list + sample: ['interface Ethernet1/2', 'lldp receive', 'lldp tlv-set vlan 12'] +""" + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network.nxos.argspec.lldp_interfaces.lldp_interfaces import Lldp_interfacesArgs +from ansible.module_utils.network.nxos.config.lldp_interfaces.lldp_interfaces import Lldp_interfaces + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule(argument_spec=Lldp_interfacesArgs.argument_spec, + supports_check_mode=True) + + result = Lldp_interfaces(module).execute_module() + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/nxos_lldp_interfaces/defaults/main.yaml b/test/integration/targets/nxos_lldp_interfaces/defaults/main.yaml new file mode 100644 index 00000000000..5f709c5aac1 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/defaults/main.yaml @@ -0,0 +1,2 @@ +--- +testcase: "*" diff --git a/test/integration/targets/nxos_lldp_interfaces/meta/main.yml b/test/integration/targets/nxos_lldp_interfaces/meta/main.yml new file mode 100644 index 00000000000..ae741cbdc71 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - prepare_nxos_tests diff --git a/test/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml b/test/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml new file mode 100644 index 00000000000..b1d3f35f7b8 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tasks/cli.yaml @@ -0,0 +1,20 @@ +--- +- name: collect common test cases + find: + paths: "{{ role_path }}/tests/cli" + patterns: "{{ testcase }}.yml" + connection: local + register: test_cases + +- set_fact: + test_cases: + files: "{{ test_cases.files }}" + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test cases (connection=network_cli) + include: "{{ test_case_to_run }} ansible_connection=network_cli connection={{ cli }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/nxos_lldp_interfaces/tasks/main.yaml b/test/integration/targets/nxos_lldp_interfaces/tasks/main.yaml new file mode 100644 index 00000000000..415c99d8b12 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml b/test/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml new file mode 100644 index 00000000000..04c99602e6b --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tasks/nxapi.yaml @@ -0,0 +1,33 @@ +--- +- name: collect common test cases + find: + paths: "{{ role_path }}/tests/common" + patterns: "{{ testcase }}.yaml" + connection: local + register: test_cases + +- name: collect nxapi test cases + find: + paths: "{{ role_path }}/tests/nxapi" + patterns: "{{ testcase }}.yaml" + connection: local + register: nxapi_cases + +- set_fact: + test_cases: + files: "{{ test_cases.files }} + {{ nxapi_cases.files }}" + +- name: set test_items + set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}" + +- name: run test cases (connection=httpapi) + include: "{{ test_case_to_run }} ansible_connection=httpapi connection={{ nxapi }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run + +- name: run test cases (connection=local) + include: "{{ test_case_to_run }} ansible_connection=local connection={{ nxapi }}" + with_items: "{{ test_items }}" + loop_control: + loop_var: test_case_to_run diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/deleted.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/deleted.yml new file mode 100644 index 00000000000..4fb88558bdc --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/deleted.yml @@ -0,0 +1,73 @@ +--- +- debug: + msg: "Start nxos_lldp_interfaces deleted integration tests connection = {{ ansible_connection }}" + +- name: Enable LLDP feature + nxos_feature: + feature: lldp + state: enabled + +- block: + - name: Setup + cli_config: + config: | + interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12 + interface Ethernet1/3 + lldp tlv-set management-address 192.0.2.12 + + - name: Delete on single interface + nxos_lldp_interfaces: + config: + - name: Ethernet1/2 + state: deleted + register: result + + - assert: + that: + - "result.changed == true" + - "'interface Ethernet1/2' in result.commands" + - "'lldp receive' in result.commands" + - "'no lldp tlv-set vlan 12' in result.commands" + - "result.commands | length == 3" + + - name: Gather lldp_interfaces facts + nxos_facts: &facts + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Deleted + nxos_lldp_interfaces: &deleted + state: deleted + register: result + + - assert: + that: + - "ansible_facts.network_resources.lldp_interfaces == result.before" + - "'interface Ethernet1/1' in result.commands" + - "'lldp transmit' in result.commands" + - "'interface Ethernet1/3' in result.commands" + - "'no lldp tlv-set management-address 192.0.2.12' in result.commands" + - "result.changed == true " + - "result.commands | length == 4" + + - name: Idempotence - deleted + nxos_lldp_interfaces: *deleted + register: result + + - assert: + that: + - "result.changed == false" + - "result.commands|length == 0" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/gathered.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/gathered.yml new file mode 100644 index 00000000000..032084ead54 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/gathered.yml @@ -0,0 +1,52 @@ +--- +- debug: + msg: Start nxos_lldp_interfaces gathered integration tests connection={{ansible_connection}}" + +- name: Enable LLDP feature + nxos_feature: + feature: lldp + state: enabled + +- block: + - name: Setup + cli_config: + config: | + interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12 + interface Ethernet1/3 + lldp tlv-set management-address 192.0.2.12 + + - name: Gather lldp interfaces facts + nxos_facts: &facts + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Gathered + nxos_lldp_interfaces: &gathered + state: gathered + register: result + + - assert: + that: + - "result.changed == false" + - "ansible_facts.network_resources.lldp_interfaces == result.gathered" + + - name: Idempotence - Gathered + nxos_lldp_interfaces: *gathered + register: result + + - assert: + that: + - "result.changed == false" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/merged.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/merged.yml new file mode 100644 index 00000000000..38bf374ee51 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/merged.yml @@ -0,0 +1,60 @@ +--- + - debug: + msg: "Start nxos_lldp_interfaces merged integration tests connection={{ansible_connection}}" + + - name: Enable lldp + nxos_feature: + feature: lldp + + - block: + - name: Merged + nxos_lldp_interfaces: &merged + config: + - name: Ethernet 1/1 + receive: false + tlv_set: + vlan: 123 + + - name: Ethernet1/2 + transmit: false + tlv_set: + management_address: 10.0.0.1 + state: merged + register: result + + - assert: + that: + - "result.changed == true" + - "'interface Ethernet1/1' in result.commands" + - "'no lldp receive' in result.commands" + - "'lldp tlv-set vlan 123' in result.commands" + - "'interface Ethernet1/2' in result.commands" + - "'no lldp transmit' in result.commands" + - "'lldp tlv-set management-address 10.0.0.1' in result.commands" + - "result.commands | length == 6" + + - name: Gather lldp_interfaces facts + nxos_facts: + gather_subset: + - '!all' + - '!min' + gather_network_resources: lldp_interfaces + + - assert: + that: + - "ansible_facts.network_resources.lldp_interfaces == result.after" + + - name: Idempotence - Merged + nxos_lldp_interfaces: *merged + register: result + + - assert: + that: + - "result.changed == false" + - "result.commands | length == 0" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled \ No newline at end of file diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/overridden.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/overridden.yml new file mode 100644 index 00000000000..f3b231ccb3e --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/overridden.yml @@ -0,0 +1,66 @@ +--- + - debug: + msg: "Start nxos_lldp_interfaces overridden tests connection={{ ansible_connection }}" + + - name: Enable LLDP feature + nxos_feature: + feature: lldp + state: enabled + + - block: + - name: Setup + cli_config: + config: | + interface Ethernet1/1 + no lldp receive + lldp tlv-set management-address 12.12.12.12 + + - name: Gather lldp_interfaces facts + nxos_facts: &facts + gather_subset: + - '!all' + - '!min' + gather_network_resources: lldp_interfaces + + - name: Overridden + nxos_lldp_interfaces: &overridden + config: + - name: Ethernet1/2 + receive: no + tlv_set: + vlan: 12 + state: overridden + register: result + + - assert: + that: + - "ansible_facts.network_resources.lldp_interfaces == result.before" + - "'interface Ethernet1/1' in result.commands" + - "'lldp receive' in result.commands" + - "'no lldp tlv-set management-address 12.12.12.12' in result.commands" + - "'interface Ethernet1/2' in result.commands" + - "'no lldp receive' in result.commands" + - "'lldp tlv-set vlan 12' in result.commands" + - "result.commands | length == 6" + + - name: Gather lldp_interfaces post facts + nxos_facts: *facts + + - assert: + that: + - "ansible_facts.network_resources.lldp_interfaces == result.after" + + - name: Idempotence - overridden + nxos_lldp_interfaces: *overridden + register: result + + - assert: + that: + - "result.changed == false" + - "result.commands|length == 0" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/parsed.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/parsed.yml new file mode 100644 index 00000000000..bbb96092915 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/parsed.yml @@ -0,0 +1,47 @@ +--- +- debug: + msg: Start nxos_lldp_interfaces parsed integration tests connection={{ansible_connection}}" + +- name: Enable lldp + nxos_feature: + feature: lldp + +- block: + - name: Gather lldp interfaces facts + nxos_facts: &facts + gather_subset: + - "!all" + - "!min" + gather_network_resources: lldp_interfaces + + - name: Parsed + nxos_lldp_interfaces: &parsed + running_config: | + interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12 + interface Ethernet1/3 + lldp tlv-set management-address 192.0.2.12 + state: parsed + register: result + + - assert: + that: + - "result.changed == false" + - "result.parsed == parsed" + + - name: Idempotence - Parsed + nxos_lldp_interfaces: *parsed + register: result + + - assert: + that: "result.changed == false" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/remove_config.yaml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/remove_config.yaml new file mode 100644 index 00000000000..955325eac20 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/remove_config.yaml @@ -0,0 +1,8 @@ +--- +- cli_config: + config: | + no interface port-channel1 + no interface port-channel2 + no interface port-channel12 + ignore_errors: yes +#this is just for RTT to remove spill overs from other modules and pass in ZUUL diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/rendered.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/rendered.yml new file mode 100644 index 00000000000..2105b073837 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/rendered.yml @@ -0,0 +1,42 @@ +--- +- debug: + msg: "Start nxos_lldp_interfaces rendered tests connection={{ ansible_connection }}" + +- name: Rendered + nxos_lldp_interfaces: &rendered + config: + - name: Ethernet1/1 + receive: true + transmit: false + + - name: Ethernet1/2 + receive: false + tlv_set: + vlan: 12 + + - name: Ethernet1/3 + tlv_set: + management_address: 192.0.2.12 + state: rendered + register: result + +- assert: + that: + - "result.changed == false" + - "'interface Ethernet1/1' in result.rendered" + - "'lldp receive' in result.rendered" + - "'no lldp transmit' in result.rendered" + - "'interface Ethernet1/2' in result.rendered" + - "'no lldp receive' in result.rendered" + - "'lldp tlv-set vlan 12' in result.rendered" + - "'interface Ethernet1/3' in result.rendered" + - "'lldp tlv-set management-address 192.0.2.12' in result.rendered" + - "result.rendered | length == 8" + +- name: Idempotence - Rendered + nxos_lldp_interfaces: *rendered + register: result + +- assert: + that: + - "result.changed == false" diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/replaced.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/replaced.yml new file mode 100644 index 00000000000..f3866bf19a4 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/replaced.yml @@ -0,0 +1,62 @@ +--- + - debug: + msg: "Start nxos_lldp_interfaces replaced integration tests connection = {{ansible_connection}}" + + - name: Enable lldp feature + nxos_feature: + feature: lldp + state: enabled + + - block: + - name: Setup + cli_config: + config: | + interface Ethernet1/2 + no lldp receive + lldp tlv-set management-address 192.168.122.64 + + - name: Replaced + nxos_lldp_interfaces: &replaced + config: + - name: Ethernet1/2 + transmit: false + tlv_set: + vlan: 2 + state: replaced + register: result + + - assert: + that: + - "result.changed == true" + - "'interface Ethernet1/2' in result.commands" + - "'lldp receive' in result.commands" + - "'no lldp tlv-set management-address 192.168.122.64' in result.commands" + - "'no lldp transmit' in result.commands" + - "'lldp tlv-set vlan 2' in result.commands" + - "result.commands|length == 5" + + - name: Gather lldp_interfaces post facts + nxos_facts: + gather_subset: + - '!all' + - '!min' + gather_network_resources: lldp_interfaces + + - assert: + that: + - "ansible_facts.network_resources.lldp_interfaces == result.after" + + - name: Idempotence - Replaced + nxos_lldp_interfaces: *replaced + register: result + + - assert: + that: + - "result.changed == false" + - "result.commands|length == 0" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled diff --git a/test/integration/targets/nxos_lldp_interfaces/tests/cli/rtt.yml b/test/integration/targets/nxos_lldp_interfaces/tests/cli/rtt.yml new file mode 100644 index 00000000000..ed8e9765879 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/tests/cli/rtt.yml @@ -0,0 +1,70 @@ +--- +- debug: + msg: "Start nxos_lldp_interfaces round trip integration tests on connection={{ ansible_connection }}" + +- name: Enable lldp + nxos_feature: + feature: lldp + +- include_tasks: remove_config.yaml + +- block: + - name: RTT - Apply the provided configuration (base config) + nxos_lldp_interfaces: + config: + - name: Ethernet1/1 + transmit: false + tlv_set: + vlan: 5 + state: merged + register: base_config + + - name: Gather interfaces facts + nxos_facts: + gather_subset: + - "!all" + - "!min" + gather_network_resources: + - lldp_interfaces + + - name: Apply provided configuration (this will be reverted) + nxos_lldp_interfaces: + config: + - name: Ethernet1/1 + transmit: false + + - name: Ethernet1/2 + transmit: true + tlv_set: + vlan: 12 + management_address: 10.1.1.2 + state: overridden + register: result + + - name: Assert that changes were applied + assert: + that: + - "result.changed == true" + - "'interface Ethernet1/1' in result.commands" + - "'no lldp tlv-set vlan 5' in result.commands" + - "'interface Ethernet1/2' in result.commands" + - "'lldp transmit' in result.commands" + - "'lldp tlv-set vlan 12' in result.commands" + - "'lldp tlv-set management-address 10.1.1.2' in result.commands" + - "result.commands | length == 6" + + - name: Revert back to base configuration + nxos_lldp_interfaces: + config: "{{ ansible_facts['network_resources']['lldp_interfaces'] }}" + state: overridden + register: revert + + - name: Assert that config was reverted + assert: + that: "{{ base_config['after'] | symmetric_difference(revert['after']) |length == 0 }}" + + always: + - name: teardown + nxos_feature: + feature: lldp + state: disabled diff --git a/test/integration/targets/nxos_lldp_interfaces/vars/main.yml b/test/integration/targets/nxos_lldp_interfaces/vars/main.yml new file mode 100644 index 00000000000..123ef31cf20 --- /dev/null +++ b/test/integration/targets/nxos_lldp_interfaces/vars/main.yml @@ -0,0 +1,14 @@ +--- +parsed: + - name: Ethernet1/1 + receive: true + transmit: false + + - name: Ethernet1/2 + receive: false + tlv_set: + vlan: 12 + + - name: Ethernet1/3 + tlv_set: + management_address: 192.0.2.12 diff --git a/test/units/modules/network/nxos/test_nxos_lldp_interfaces.py b/test/units/modules/network/nxos/test_nxos_lldp_interfaces.py new file mode 100644 index 00000000000..fb70ed2e1c6 --- /dev/null +++ b/test/units/modules/network/nxos/test_nxos_lldp_interfaces.py @@ -0,0 +1,236 @@ +# +# (c) 2019, Ansible by Red Hat, inc +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +# + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.modules.network.nxos import nxos_lldp_interfaces +from units.compat.mock import patch, MagicMock +from units.modules.utils import set_module_args +from .nxos_module import TestNxosModule, load_fixture + + +class TestNxosLldpInterfacesModule(TestNxosModule): + + module = nxos_lldp_interfaces + + def setUp(self): + super(TestNxosLldpInterfacesModule, self).setUp() + + self.mock_get_config = patch( + 'ansible.module_utils.network.common.network.Config.get_config') + self.get_config = self.mock_get_config.start() + + self.mock_load_config = patch( + 'ansible.module_utils.network.common.network.Config.load_config') + self.load_config = self.mock_load_config.start() + + self.mock_get_resource_connection_config = patch( + 'ansible.module_utils.network.common.cfg.base.get_resource_connection' + ) + self.get_resource_connection_config = self.mock_get_resource_connection_config.start( + ) + + self.mock_get_resource_connection_facts = patch( + 'ansible.module_utils.network.common.facts.facts.get_resource_connection' + ) + self.get_resource_connection_facts = self.mock_get_resource_connection_facts.start() + + self.mock_edit_config = patch( + 'ansible.module_utils.network.nxos.config.lldp_interfaces.lldp_interfaces.Lldp_interfaces.edit_config' + ) + self.edit_config = self.mock_edit_config.start() + + self.mock_execute_show_command = patch( + 'ansible.module_utils.network.nxos.facts.lldp_interfaces.lldp_interfaces.Lldp_interfacesFacts.get_device_data' + ) + self.execute_show_command = self.mock_execute_show_command.start() + + def tearDown(self): + super(TestNxosLldpInterfacesModule, self).tearDown() + self.mock_get_resource_connection_config.stop() + self.mock_get_resource_connection_facts.stop() + self.mock_edit_config.stop() + self.mock_get_config.stop() + self.mock_load_config.stop() + self.mock_execute_show_command.stop() + + def load_fixtures(self, commands=None, device=''): + def load_from_file(*args, **kwargs): + output = '''interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12''' + return output + + self.execute_show_command.side_effect = load_from_file + + def test_nxos_lldp_interfaces_merged(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/3", + receive=False, + tlv_set=dict( + vlan=123 + ) + ) + ], state="merged")) + commands = ['interface Ethernet1/3', + 'no lldp receive', + 'lldp tlv-set vlan 123'] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_merged_idempotent(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/2", + receive=False, + tlv_set=dict( + vlan=12 + ) + ), + dict(name="Ethernet1/1", + receive=True, + transmit=False) + ], state="merged")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_lldp_interfaces_replaced(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/2", + receive=True, + transmit=False, + tlv_set=dict( + management_address='192.0.2.123' + ) + ) + ], state="replaced")) + commands = ['interface Ethernet1/2', + 'lldp receive', + 'no lldp transmit', + 'no lldp tlv-set vlan 12', + 'lldp tlv-set management-address 192.0.2.123'] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_replaced_idempotent(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/2", + receive=False, + tlv_set=dict( + vlan=12 + ) + ), + dict(name="Ethernet1/1", + receive=True, + transmit=False) + ], state="replaced")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_lldp_interfaces_overridden(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/4", + receive=True, + transmit=False + ) + ], state="overridden")) + commands = ['interface Ethernet1/4', + 'lldp receive', + 'no lldp transmit', + 'interface Ethernet1/1', + 'lldp receive', + 'lldp transmit', + 'interface Ethernet1/2', + 'lldp receive', + 'no lldp tlv-set vlan 12'] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_overridden_idempotent(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/2", + receive=False, + tlv_set=dict( + vlan=12 + ) + ), + dict(name="Ethernet1/1", + receive=True, + transmit=False) + ], state="overridden")) + self.execute_module(changed=False, commands=[]) + + def test_nxos_lldp_interfaces_deleted_intf(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/2") + ], state="deleted")) + commands = ['interface Ethernet1/2', + 'lldp receive', + 'no lldp tlv-set vlan 12'] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_deleted_all(self): + set_module_args( + dict(state="deleted")) + commands = ['interface Ethernet1/2', + 'lldp receive', + 'no lldp tlv-set vlan 12', + 'interface Ethernet1/1', + 'lldp receive', + 'lldp transmit'] + self.execute_module(changed=True, commands=commands) + + def test_nxos_lldp_interfaces_rendered(self): + set_module_args( + dict(config=[ + dict(name="Ethernet1/2", + receive=False, + tlv_set=dict( + vlan=12 + ) + ), + dict(name="Ethernet1/1", + receive=True, + transmit=False) + ], state="rendered")) + commands = ['interface Ethernet1/1', + 'lldp receive', + 'no lldp transmit', + 'interface Ethernet1/2', + 'no lldp receive', + 'lldp tlv-set vlan 12'] + result = self.execute_module(changed=False) + self.assertEqual(sorted(result['rendered']), sorted( + commands), result['rendered']) + + def test_nxos_lldp_interfaces_parsed(self): + set_module_args(dict(running_config='''interface Ethernet1/1 + lldp receive + no lldp transmit + interface Ethernet1/2 + no lldp receive + lldp tlv-set vlan 12''', state="parsed")) + result = self.execute_module(changed=False) + compare_list = [{'name': 'Ethernet1/1', 'receive': True, 'transmit': False}, + {'name': 'Ethernet1/2', 'receive': False, 'tlv_set': { + 'vlan': 12 + }}] + self.assertEqual(result['parsed'], + compare_list, result['parsed']) + + def test_nxos_lldp_interfaces_gathered(self): + set_module_args(dict(state="gathered")) + result = self.execute_module(changed=False) + compare_list = [{'name': 'Ethernet1/1', 'receive': True, 'transmit': False}, + {'name': 'Ethernet1/2', 'receive': False, 'tlv_set': { + 'vlan': 12 + }}] + self.assertEqual(result['gathered'], + compare_list, result['gathered'])