Add iosxr_lldp_interfaces resource module (#60411)

Signed-off-by: NilashishC <nilashishchakraborty8@gmail.com>
pull/60470/head
Nilashish Chakraborty 5 years ago committed by GitHub
parent a40baf22fa
commit 6110dcc789
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -25,7 +25,9 @@ class FactsArgs(object): # pylint: disable=R0903
'lacp_interfaces', 'lacp_interfaces',
'!lacp_interfaces', '!lacp_interfaces',
'lldp_global', 'lldp_global',
'!lldp_global' '!lldp_global',
'lldp_interfaces',
'!lldp_interfaces'
] ]
argument_spec = { argument_spec = {

@ -0,0 +1,70 @@
#
# -*- 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 iosxr_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 iosxr_lldp_interfaces module
"""
def __init__(self, **kwargs):
pass
argument_spec = {
'config': {
'elements': 'dict',
'options': {
'destination': {
'type': 'dict',
'options': {
'mac_address': {
'type': 'str',
'choices': ['ieee-nearest-bridge', 'ieee-nearest-non-tmpr-bridge'],
}
}
},
'name': {
'type': 'str'
},
'receive': {
'type': 'bool'
},
'transmit': {
'type': 'bool'
}
},
'type': 'list'
},
'state': {
'choices': ['merged', 'replaced', 'overridden', 'deleted'],
'default': 'merged',
'type': 'str'
}
} # pylint: disable=C0301

@ -0,0 +1,246 @@
#
# -*- 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 iosxr_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, dict_diff, remove_empties
from ansible.module_utils.network.iosxr.facts.facts import Facts
from ansible.module_utils.six import iteritems
from ansible.module_utils.network.iosxr. \
utils.utils import search_obj_in_list, dict_delete, pad_commands, flatten_dict
class Lldp_interfaces(ConfigBase):
"""
The iosxr_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):
""" 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)
lldp_interfaces_facts = facts['ansible_network_resources'].get('lldp_interfaces')
if not lldp_interfaces_facts:
return []
return lldp_interfaces_facts
def execute_module(self):
""" Execute the module
:rtype: A dictionary
:returns: The result from module execution
"""
result = {'changed': False}
warnings = list()
commands = list()
existing_lldp_interfaces_facts = self.get_lldp_interfaces_facts()
commands.extend(self.set_config(existing_lldp_interfaces_facts))
if commands:
if not self._module.check_mode:
self._connection.edit_config(commands)
result['changed'] = True
result['commands'] = commands
changed_lldp_interfaces_facts = self.get_lldp_interfaces_facts()
result['before'] = existing_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
"""
want = self._module.params['config']
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
"""
state = self._module.params['state']
commands = []
if state == 'overridden':
commands.extend(
self._state_overridden(
want, have
)
)
elif state == 'deleted':
if not want:
for intf in have:
commands.extend(
self._state_deleted(
{'name': intf['name']},
intf
)
)
else:
for item in want:
obj_in_have = search_obj_in_list(item['name'], have)
commands.extend(
self._state_deleted(
item, obj_in_have
)
)
else:
for item in want:
name = item['name']
obj_in_have = search_obj_in_list(name, have)
if state == 'merged':
commands.extend(
self._state_merged(
item, obj_in_have
)
)
elif state == 'replaced':
commands.extend(
self._state_replaced(
item, obj_in_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 = []
replaced_commands = []
merged_commands = []
if have:
replaced_commands = self._state_deleted(want, have)
merged_commands = self._state_merged(want, have)
if merged_commands and replaced_commands:
del merged_commands[0]
commands.extend(replaced_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 = []
for intf in have:
intf_in_want = search_obj_in_list(intf['name'], want)
if not intf_in_want:
commands.extend(self._state_deleted({'name': intf['name']}, intf))
for intf in want:
intf_in_have = search_obj_in_list(intf['name'], have)
commands.extend(self._state_replaced(intf, intf_in_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
"""
commands = []
if not have:
have = {'name': want['name']}
for key, value in iteritems(flatten_dict(remove_empties(dict_diff(have, want)))):
commands.append(self._compute_commands(key, value))
if commands:
pad_commands(commands, want['name'])
return commands
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 = []
for key, value in iteritems(flatten_dict(dict_delete(have, remove_empties(want)))):
commands.append(self._compute_commands(key, value, remove=True))
if commands:
pad_commands(commands, have['name'])
return commands
def _compute_commands(self, key, value=None, remove=False):
if key == 'mac_address':
cmd = 'lldp destination mac-address {0}'.format(value)
if remove:
return 'no {0}'.format(cmd)
else:
return cmd
else:
cmd = 'lldp {0} disable'.format(key)
if (not value and not remove):
return cmd
elif (value and not remove) or (not value and remove):
return 'no {0}'.format(cmd)

@ -18,6 +18,7 @@ from ansible.module_utils.network.common.facts.facts import FactsBase
from ansible.module_utils.network.iosxr.facts.lacp.lacp import LacpFacts from ansible.module_utils.network.iosxr.facts.lacp.lacp import LacpFacts
from ansible.module_utils.network.iosxr.facts.lacp_interfaces.lacp_interfaces import Lacp_interfacesFacts from ansible.module_utils.network.iosxr.facts.lacp_interfaces.lacp_interfaces import Lacp_interfacesFacts
from ansible.module_utils.network.iosxr.facts.lldp_global.lldp_global import Lldp_globalFacts from ansible.module_utils.network.iosxr.facts.lldp_global.lldp_global import Lldp_globalFacts
from ansible.module_utils.network.iosxr.facts.lldp_interfaces.lldp_interfaces import Lldp_interfacesFacts
from ansible.module_utils.network.iosxr.facts.legacy.\ from ansible.module_utils.network.iosxr.facts.legacy.\
base import Default, Hardware, Interfaces, Config base import Default, Hardware, Interfaces, Config
@ -31,7 +32,8 @@ FACT_LEGACY_SUBSETS = dict(
FACT_RESOURCE_SUBSETS = dict( FACT_RESOURCE_SUBSETS = dict(
lacp=LacpFacts, lacp=LacpFacts,
lacp_interfaces=Lacp_interfacesFacts, lacp_interfaces=Lacp_interfacesFacts,
lldp_global=Lldp_globalFacts lldp_global=Lldp_globalFacts,
lldp_interfaces=Lldp_interfacesFacts
) )

@ -0,0 +1,97 @@
#
# -*- 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 iosxr 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.iosxr.argspec.lldp_interfaces.lldp_interfaces import Lldp_interfacesArgs
from ansible.module_utils.six import iteritems
class Lldp_interfacesFacts(object):
""" The iosxr 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 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 = connection.get_config(flags='interface')
interfaces = data.split('interface ')
objs = []
for interface in interfaces:
obj = self.render_config(self.generated_spec, interface)
if obj:
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'(GigabitEthernet|Bundle-Ether|TenGigE|FortyGigE|HundredGigE)(\S+)', conf, re.M)
if match:
config['name'] = match.group(1) + match.group(2)
for key in ['receive', 'transmit']:
config[key] = False if ('{0} disable'.format(key)) in conf else None
for x in ['ieee-nearest-bridge', 'ieee-nearest-non-tmpr-bridge']:
if x in conf:
config['destination']['mac_address'] = x
return utils.remove_empties(config)

@ -25,6 +25,7 @@ description:
on devices running Cisco IOS-XR on devices running Cisco IOS-XR
notes: notes:
- Tested against Cisco IOS XR Software Version 6.1.3 - Tested against Cisco IOS XR Software Version 6.1.3
- This module works with connection C(network_cli).
options: options:
config: config:
description: description:

@ -526,7 +526,8 @@ def main():
:returns: the result form module invocation :returns: the result form module invocation
""" """
required_if = [('state', 'merged', ('config',)), required_if = [('state', 'merged', ('config',)),
('state', 'replaced', ('config',))] ('state', 'replaced', ('config',)),
('state', 'overridden', ('config',))]
module = AnsibleModule(argument_spec=Lacp_interfacesArgs.argument_spec, required_if=required_if, module = AnsibleModule(argument_spec=Lacp_interfacesArgs.argument_spec, required_if=required_if,
supports_check_mode=True) supports_check_mode=True)

@ -0,0 +1,588 @@
#!/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 iosxr_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: iosxr_lldp_interfaces
version_added: 2.9
short_description: Manage Link Layer Discovery Protocol (LLDP) attributes of interfaces on IOS-XR devices.
description:
- This module manages Link Layer Discovery Protocol (LLDP) attributes of interfaces on IOS-XR devices.
notes:
- Tested against IOS-XR 6.1.3.
- This module works with connection C(network_cli).
author: Nilashish Chakraborty (@nilashishc)
options:
config:
description: A dictionary of LLDP interfaces options.
type: list
elements: dict
suboptions:
name:
description:
- Name/Identifier of the interface or Ether-Bundle.
type: str
destination:
description:
- Specifies LLDP destination configuration on the interface.
suboptions:
mac_address:
description:
- Specifies the LLDP destination mac address on the interface.
type: str
choices: ['ieee-nearest-bridge', 'ieee-nearest-non-tmpr-bridge']
type: dict
receive:
description:
- Enable/disable LLDP RX on an interface.
type: bool
transmit:
description:
- Enable/disable LLDP TX on an interface.
type: bool
state:
description:
- The state the configuration should be left in.
type: str
choices:
- merged
- replaced
- overridden
- deleted
default: merged
"""
EXAMPLES = """
# Using merged
#
#
# ------------
# Before state
# ------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 12:40:23.104 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# !
# interface preconfigure GigabitEthernet0/0/0/2
# !
#
#
- name: Merge provided configuration with running configuration
iosxr_lldp_interfaces:
config:
- name: GigabitEthernet0/0/0/1
destination:
mac_address: ieee-nearest-non-tmpr-bridge
transmit: False
- name: GigabitEthernet0/0/0/2
destination:
mac_address: ieee-nearest-bridge
receive: False
state: merged
#
#
# ------------------------
# Module Execution Result
# ------------------------
#
#
# "before": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "name": "GigabitEthernet0/0/0/1"
# },
# {
# "name": "GigabitEthernet0/0/0/2"
# }
# ]
#
# "commands": [
# "interface GigabitEthernet0/0/0/2",
# "lldp destination mac-address ieee-nearest-non-tmpr-bridge",
# "lldp transmit disable",
# "interface GigabitEthernet0/0/0/1",
# "lldp receive disable",
# "lldp destination mac-address ieee-nearest-bridge"
# ]
#
# "after": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-bridge"
# },
# "name": "GigabitEthernet0/0/0/1",
# "receive": false
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-non-tmpr-bridge"
# },
# "name": "GigabitEthernet0/0/0/2",
# "transmit": false
# }
# ]
#
#
# ------------
# After state
# ------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 12:49:51.517 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# lldp
# receive disable
# destination mac-address
# ieee-nearest-bridge
# !
# !
# !
# interface preconfigure GigabitEthernet0/0/0/2
# lldp
# transmit disable
# destination mac-address
# ieee-nearest-non-tmpr-bridge
# !
# !
# !
#
#
# Using replaced
#
#
# -------------
# Before state
# -------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 12:49:51.517 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# lldp
# receive disable
# destination mac-address
# ieee-nearest-bridge
# !
# !
# !
# interface preconfigure GigabitEthernet0/0/0/2
# lldp
# transmit disable
# destination mac-address
# ieee-nearest-non-tmpr-bridge
# !
# !
# !
#
#
- name: Replace existing LLDP configurations of specified interfaces with provided configuration
iosxr_lldp_interfaces:
config:
- name: GigabitEthernet0/0/0/1
destination:
mac_address: ieee-nearest-non-tmpr-bridge
state: replaced
#
#
# ------------------------
# Module Execution Result
# ------------------------
#
# "before": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-bridge"
# },
# "name": "GigabitEthernet0/0/0/1",
# "receive": false
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-non-tmpr-bridge"
# },
# "name": "GigabitEthernet0/0/0/2",
# "transmit": false
# }
# ]
#
#
# "commands": [
# "interface GigabitEthernet0/0/0/1",
# "no lldp receive disable",
# "lldp destination mac-address ieee-nearest-non-tmpr-bridge"
# ]
#
#
# "after": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-non-tmpr-bridge"
# },
# "name": "GigabitEthernet0/0/0/1"
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-non-tmpr-bridge"
# },
# "name": "GigabitEthernet0/0/0/2",
# "transmit": false
# }
# ]
#
#
# ------------
# After state
# ------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 13:02:57.062 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# lldp
# destination mac-address
# ieee-nearest-non-tmpr-bridge
# !
# !
# !
# interface preconfigure GigabitEthernet0/0/0/2
# lldp
# transmit disable
# destination mac-address
# ieee-nearest-non-tmpr-bridge
# !
# !
# !
#
#
# Using overridden
#
#
# -------------
# Before state
# -------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 13:15:40.465 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# lldp
# receive disable
# destination mac-address
# ieee-nearest-bridge
# !
# !
# !
# interface preconfigure GigabitEthernet0/0/0/2
# lldp
# transmit disable
# destination mac-address
# ieee-nearest-non-tmpr-bridge
# !
# !
# !
#
#
- name: Override the LLDP configurations of all the interfaces with provided configurations
iosxr_lldp_interfaces:
config:
- name: GigabitEthernet0/0/0/1
transmit: False
state: overridden
#
#
# ------------------------
# Module Execution Result
# ------------------------
#
#
# "before": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-bridge"
# },
# "name": "GigabitEthernet0/0/0/1",
# "receive": false
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-non-tmpr-bridge"
# },
# "name": "GigabitEthernet0/0/0/2",
# "transmit": false
# }
# ]
#
# "commands": [
# "interface GigabitEthernet0/0/0/2",
# "no lldp destination mac-address ieee-nearest-non-tmpr-bridge",
# "no lldp transmit disable",
# "interface GigabitEthernet0/0/0/1",
# "no lldp destination mac-address ieee-nearest-bridge",
# "no lldp receive disable",
# "lldp transmit disable"
# ]
#
#
# "after": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "name": "GigabitEthernet0/0/0/1",
# "transmit": false
# },
# {
# "name": "GigabitEthernet0/0/0/2"
# }
# ]
#
#
# ------------
# After state
# ------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 13:22:25.604 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# lldp
# transmit disable
# !
# !
# interface preconfigure GigabitEthernet0/0/0/2
# !
#
#
# Using deleted
#
#
# -------------
# Before state
# -------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 13:26:21.498 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# lldp
# receive disable
# destination mac-address
# ieee-nearest-bridge
# !
# !
# !
# interface preconfigure GigabitEthernet0/0/0/2
# lldp
# transmit disable
# destination mac-address
# ieee-nearest-non-tmpr-bridge
# !
# !
# !
#
#
- name: Delete LLDP configurations of all interfaces (Note - This won't delete the interfaces themselves)
iosxr_lldp_interfaces:
state: deleted
#
#
#
# ------------------------
# Module Execution Result
# ------------------------
#
#
# "before": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-bridge"
# },
# "name": "GigabitEthernet0/0/0/1",
# "receive": false
# },
# {
# "destination": {
# "mac_address": "ieee-nearest-non-tmpr-bridge"
# },
# "name": "GigabitEthernet0/0/0/2",
# "transmit": false
# }
# ]
#
#
# "commands": [
# "interface GigabitEthernet0/0/0/1",
# "no lldp destination mac-address ieee-nearest-bridge",
# "no lldp receive disable",
# "interface GigabitEthernet0/0/0/2",
# "no lldp destination mac-address ieee-nearest-non-tmpr-bridge",
# "no lldp transmit disable"
# ]
#
#
# "after": [
# {
# "name": "TenGigE0/0/0/0"
# },
# {
# "name": "GigabitEthernet0/0/0/1"
# },
# {
# "name": "GigabitEthernet0/0/0/2"
# }
# ]
#
#
# ------------
# After state
# ------------
#
#
# RP/0/RP0/CPU0:ios#sh run int
# Mon Aug 12 13:30:14.618 UTC
# interface TenGigE0/0/0/0
# ipv4 address 192.0.2.11 255.255.255.192
# !
# interface preconfigure GigabitEthernet0/0/0/1
# !
# interface preconfigure GigabitEthernet0/0/0/2
# !
#
#
"""
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 GigabitEthernet0/0/0/1', 'lldp destination mac-address ieee-nearest-non-tmpr-bridge', 'no lldp transmit disable']
"""
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.iosxr.argspec.lldp_interfaces.lldp_interfaces import Lldp_interfacesArgs
from ansible.module_utils.network.iosxr.config.lldp_interfaces.lldp_interfaces import Lldp_interfaces
def main():
"""
Main entry point for module execution
:returns: the result form module invocation
"""
required_if = [('state', 'merged', ('config',)),
('state', 'replaced', ('config',)),
('state', 'overridden', ('config',))]
module = AnsibleModule(argument_spec=Lldp_interfacesArgs.argument_spec, required_if=required_if,
supports_check_mode=True)
result = Lldp_interfaces(module).execute_module()
module.exit_json(**result)
if __name__ == '__main__':
main()

@ -0,0 +1,20 @@
---
- name: Collect all cli test cases
find:
paths: "{{ role_path }}/tests/cli"
patterns: "{{ testcase }}.yaml"
use_regex: true
register: test_cases
delegate_to: localhost
- name: Set test_items
set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
delegate_to: localhost
- name: Run test case (connection=network_cli)
include: "{{ test_case_to_run }}"
vars:
ansible_connection: network_cli
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

@ -0,0 +1,2 @@
---
- { include: cli.yaml, tags: ['cli'] }

@ -0,0 +1,12 @@
---
- name: Setup GigE1
iosxr_config:
lines:
- lldp receive disable
parents: interface GigabitEthernet0/0/0/1
- name: Setup GigE0
iosxr_config:
lines:
- lldp transmit disable
parents: interface GigabitEthernet0/0/0/0

@ -0,0 +1,24 @@
---
- name: Remove LLDP interface config
iosxr_config:
lines:
- no lldp
- shutdown
parents: "interface GigabitEthernet{{ item }}"
loop:
- 0/0/0/0
- 0/0/0/1
ignore_errors: yes
# To make sure our assertions are not affected by
# spill overs from previous tests
- name: Remove unwanted interfaces from config
iosxr_config:
lines:
- "no interface GigabitEthernet{{ item }}"
loop:
- 0/0/0/2
- 0/0/0/3
- 0/0/0/4
- 0/0/0/5
ignore_errors: yes

@ -0,0 +1,46 @@
---
- debug:
msg: "Start iosxr_lldp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}"
- include_tasks: _remove_config.yaml
- include_tasks: _populate.yaml
- block:
- name: Delete LLDP attributes of all interfaces
iosxr_lldp_interfaces: &deleted
state: deleted
register: result
- name: Assert that the before dicts were correctly generated
assert:
that:
- "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
- name: Assert that the correct set of commands were generated
assert:
that:
- "{{ deleted['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
- name: Assert that the after dicts were correctly generated
assert:
that:
- "{{ deleted['after'] | symmetric_difference(result['after']) |length == 0 }}"
- name: Delete LACP attributes of all interfaces (IDEMPOTENT)
iosxr_lldp_interfaces: *deleted
register: result
- name: Assert that the previous task was idempotent
assert:
that:
- "result.changed == false"
- "result.commands|length == 0"
- name: Assert that the before dicts were correctly generated
assert:
that:
- "{{ deleted['after'] | symmetric_difference(result['before']) |length == 0 }}"
always:
- include_tasks: _remove_config.yaml

@ -0,0 +1,48 @@
---
- debug:
msg: "START iosxr_lldp_interfaces merged integration tests on connection={{ ansible_connection }}"
- include_tasks: _remove_config.yaml
- block:
- name: Merge the provided configuration with the exisiting running configuration
iosxr_lldp_interfaces: &merged
config:
- name: GigabitEthernet0/0/0/0
transmit: False
- name: GigabitEthernet0/0/0/1
receive: False
state: merged
register: result
- name: Assert that before dicts were correctly generated
assert:
that: "{{ merged['before'] | symmetric_difference(result['before']) |length == 0 }}"
- name: Assert that correct set of commands were generated
assert:
that:
- "{{ merged['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
- name: Assert that after dicts was correctly generated
assert:
that:
- "{{ merged['after'] | symmetric_difference(result['after']) |length == 0 }}"
- name: Merge the provided configuration with the existing running configuration (IDEMPOTENT)
iosxr_lldp_interfaces: *merged
register: result
- name: Assert that the previous task was idempotent
assert:
that:
- "result['changed'] == false"
- "result.commands|length == 0"
- name: Assert that before dicts were correctly generated
assert:
that:
- "{{ merged['after'] | symmetric_difference(result['before']) |length == 0 }}"
always:
- include_tasks: _remove_config.yaml

@ -0,0 +1,49 @@
---
- debug:
msg: "START iosxr_lldp_interfaces overridden integration tests on connection={{ ansible_connection }}"
- include_tasks: _remove_config.yaml
- include_tasks: _populate.yaml
- block:
- name: Overridde all interface LLDP configuration with provided configuration
iosxr_lldp_interfaces: &overridden
config:
- name: GigabitEthernet0/0/0/0
transmit: False
state: overridden
register: result
- name: Assert that correct set of commands were generated
assert:
that:
- "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
- name: Assert that before dicts are correctly generated
assert:
that:
- "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
- name: Assert that after dict is correctly generated
assert:
that:
- "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}"
- name: Overridde all interface LACP configuration with provided configuration (IDEMPOTENT)
iosxr_lldp_interfaces: *overridden
register: result
- name: Assert that task was idempotent
assert:
that:
- "result['changed'] == false"
- "result.commands|length == 0"
- name: Assert that before dict is correctly generated
assert:
that:
- "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}"
always:
- include_tasks: _remove_config.yaml

@ -0,0 +1,49 @@
---
- debug:
msg: "START iosxr_lldp_interfaces replaced integration tests on connection={{ ansible_connection }}"
- include_tasks: _remove_config.yaml
- include_tasks: _populate.yaml
- block:
- name: Replace device configurations of listed interfaces with provided configurations
iosxr_lldp_interfaces: &replaced
config:
- name: GigabitEthernet0/0/0/1
transmit: False
state: replaced
register: result
- name: Assert that correct set of commands were generated
assert:
that:
- "{{ replaced['commands'] | symmetric_difference(result['commands']) |length == 0 }}"
- name: Assert that before dicts are correctly generated
assert:
that:
- "{{ populate | symmetric_difference(result['before']) |length == 0 }}"
- name: Assert that after dict is correctly generated
assert:
that:
- "{{ replaced['after'] | symmetric_difference(result['after']) |length == 0 }}"
- name: Replace device configurations of listed interfaces with provided configurarions (IDEMPOTENT)
iosxr_lldp_interfaces: *replaced
register: result
- name: Assert that task was idempotent
assert:
that:
- "result['changed'] == false"
- "result.commands|length == 0"
- name: Assert that before dict is correctly generated
assert:
that:
- "{{ replaced['after'] | symmetric_difference(result['before']) |length == 0 }}"
always:
- include_tasks: _remove_config.yaml

@ -0,0 +1,50 @@
---
- debug:
msg: "START iosxr_lldp_interfaces round trip integration tests on connection={{ ansible_connection }}"
- block:
- include_tasks: _remove_config.yaml
- name: Apply the provided configuration (base config)
iosxr_lldp_interfaces:
config:
- name: GigabitEthernet0/0/0/0
transmit: False
state: merged
register: base_config
- name: Gather interfaces facts
iosxr_facts:
gather_subset:
- "!all"
- "!min"
gather_network_resources:
- lldp_interfaces
- name: Apply the provided configuration (config to be reverted)
iosxr_lldp_interfaces:
config:
- name: GigabitEthernet0/0/0/0
receive: False
- name: GigabitEthernet0/0/0/1
transmit: False
state: overridden
register: result
- name: Assert that changes were applied
assert:
that: "{{ round_trip['after'] | symmetric_difference(result['after']) |length == 0 }}"
- name: Revert back to base config using facts round trip
iosxr_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:
- include_tasks: _remove_config.yaml

@ -0,0 +1,70 @@
---
merged:
before:
- name: GigabitEthernet0/0/0/0
- name: GigabitEthernet0/0/0/1
commands:
- "interface GigabitEthernet0/0/0/0"
- "lldp transmit disable"
- "interface GigabitEthernet0/0/0/1"
- "lldp receive disable"
after:
- name: GigabitEthernet0/0/0/0
transmit: False
- name: GigabitEthernet0/0/0/1
receive: False
populate:
- name: GigabitEthernet0/0/0/0
transmit: False
- name: GigabitEthernet0/0/0/1
receive: False
replaced:
commands:
- "interface GigabitEthernet0/0/0/1"
- "no lldp receive disable"
- "lldp transmit disable"
after:
- name: GigabitEthernet0/0/0/0
transmit: False
- name: GigabitEthernet0/0/0/1
transmit: False
overridden:
commands:
- "interface GigabitEthernet0/0/0/1"
- "no lldp receive disable"
after:
- name: GigabitEthernet0/0/0/0
transmit: False
- name: GigabitEthernet0/0/0/1
deleted:
commands:
- "interface GigabitEthernet0/0/0/0"
- "no lldp transmit disable"
- "interface GigabitEthernet0/0/0/1"
- "no lldp receive disable"
after:
- name: GigabitEthernet0/0/0/0
- name: GigabitEthernet0/0/0/1
round_trip:
after:
- name: GigabitEthernet0/0/0/0
receive: False
- name: GigabitEthernet0/0/0/1
transmit: False
Loading…
Cancel
Save