exos_lldp_interfaces resource module (#62108)

* exos_lldp_interfaces resource module

* Fix exos_lldp_interfaces and add integration tests

* Fix deleted testcase for integration test
This commit is contained in:
JayalakshmiV 2019-10-17 13:40:17 -04:00 committed by Nathaniel Case
parent f5e0995cae
commit 1a384a61fb
18 changed files with 1407 additions and 0 deletions

View file

@ -0,0 +1,49 @@
#
# -*- 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 exos_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 exos_lldp_interfaces module
"""
def __init__(self, **kwargs):
pass
argument_spec = {
'config': {
'elements': 'dict',
'options': {
'enabled': {'type': 'bool'},
'name': {'required': True, 'type': 'str'}},
'type': 'list'},
'state': {
'choices': ['merged', 'replaced', 'overridden', 'deleted'],
'default': 'merged',
'type': 'str'}} # pylint: disable=C0301

View file

@ -0,0 +1,243 @@
#
# -*- 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 exos_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
import json
from copy import deepcopy
from ansible.module_utils.network.common.cfg.base import ConfigBase
from ansible.module_utils.network.common.utils import to_list, dict_diff
from ansible.module_utils.network.exos.facts.facts import Facts
from ansible.module_utils.network.exos.exos import send_requests
class Lldp_interfaces(ConfigBase):
"""
The exos_lldp_interfaces class
"""
gather_subset = [
'!all',
'!min',
]
gather_network_resources = [
'lldp_interfaces',
]
LLDP_INTERFACE = {
"data": {
"openconfig-lldp:config": {
"name": None,
"enabled": True
}
},
"method": "PATCH",
"path": None
}
LLDP_PATH = "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface="
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()
requests = list()
existing_lldp_interfaces_facts = self.get_lldp_interfaces_facts()
requests.extend(self.set_config(existing_lldp_interfaces_facts))
if requests:
if not self._module.check_mode:
send_requests(self._module, requests=requests)
result['changed'] = True
result['requests'] = requests
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 requests 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 requests necessary to migrate the current configuration
to the desired configuration
"""
state = self._module.params['state']
if state == 'overridden':
requests = self._state_overridden(want, have)
elif state == 'deleted':
requests = self._state_deleted(want, have)
elif state == 'merged':
requests = self._state_merged(want, have)
elif state == 'replaced':
requests = self._state_replaced(want, have)
return requests
def _state_replaced(self, want, have):
""" The request generator when state is replaced
:rtype: A list
:returns: the requests necessary to migrate the current configuration
to the desired configuration
"""
requests = []
for w in want:
for h in have:
if w['name'] == h['name']:
lldp_request = self._update_patch_request(w, h)
if lldp_request["path"]:
lldp_request["data"] = json.dumps(lldp_request["data"])
requests.append(lldp_request)
return requests
def _state_overridden(self, want, have):
""" The request generator when state is overridden
:rtype: A list
:returns: the requests necessary to migrate the current configuration
to the desired configuration
"""
requests = []
have_copy = []
for w in want:
for h in have:
if w['name'] == h['name']:
lldp_request = self._update_patch_request(w, h)
if lldp_request["path"]:
lldp_request["data"] = json.dumps(lldp_request["data"])
requests.append(lldp_request)
have_copy.append(h)
for h in have:
if h not in have_copy:
if not h['enabled']:
lldp_delete = self._update_delete_request(h)
if lldp_delete["path"]:
lldp_delete["data"] = json.dumps(lldp_delete["data"])
requests.append(lldp_delete)
return requests
def _state_merged(self, want, have):
""" The request generator when state is merged
:rtype: A list
:returns: the requests necessary to merge the provided into
the current configuration
"""
requests = []
for w in want:
for h in have:
if w['name'] == h['name']:
lldp_request = self._update_patch_request(w, h)
if lldp_request["path"]:
lldp_request["data"] = json.dumps(lldp_request["data"])
requests.append(lldp_request)
return requests
def _state_deleted(self, want, have):
""" The request generator when state is deleted
:rtype: A list
:returns: the requests necessary to remove the current configuration
of the provided objects
"""
requests = []
if want:
for w in want:
for h in have:
if w['name'] == h['name']:
if not h['enabled']:
lldp_delete = self._update_delete_request(h)
if lldp_delete["path"]:
lldp_delete["data"] = json.dumps(
lldp_delete["data"])
requests.append(lldp_delete)
else:
for h in have:
if not h['enabled']:
lldp_delete = self._update_delete_request(h)
if lldp_delete["path"]:
lldp_delete["data"] = json.dumps(lldp_delete["data"])
requests.append(lldp_delete)
return requests
def _update_patch_request(self, want, have):
lldp_request = deepcopy(self.LLDP_INTERFACE)
if have['enabled'] != want['enabled']:
lldp_request["data"]["openconfig-lldp:config"]["name"] = want[
'name']
lldp_request["data"]["openconfig-lldp:config"]["enabled"] = want[
'enabled']
lldp_request["path"] = self.LLDP_PATH + str(
want['name']) + "/config"
return lldp_request
def _update_delete_request(self, have):
lldp_delete = deepcopy(self.LLDP_INTERFACE)
lldp_delete["data"]["openconfig-lldp:config"]["name"] = have['name']
lldp_delete["data"]["openconfig-lldp:config"]["enabled"] = True
lldp_delete["path"] = self.LLDP_PATH + str(have['name']) + "/config"
return lldp_delete

View file

@ -16,6 +16,8 @@ from ansible.module_utils.network.common.facts.facts import FactsBase
from ansible.module_utils.network.exos.facts.lldp_global.lldp_global import Lldp_globalFacts from ansible.module_utils.network.exos.facts.lldp_global.lldp_global import Lldp_globalFacts
from ansible.module_utils.network.exos.facts.vlans.vlans import VlansFacts from ansible.module_utils.network.exos.facts.vlans.vlans import VlansFacts
from ansible.module_utils.network.exos.facts.legacy.base import Default, Hardware, Interfaces, Config from ansible.module_utils.network.exos.facts.legacy.base import Default, Hardware, Interfaces, Config
from ansible.module_utils.network.exos.facts.lldp_interfaces.lldp_interfaces import Lldp_interfacesFacts
FACT_LEGACY_SUBSETS = dict( FACT_LEGACY_SUBSETS = dict(
default=Default, default=Default,
@ -26,6 +28,7 @@ FACT_LEGACY_SUBSETS = dict(
FACT_RESOURCE_SUBSETS = dict( FACT_RESOURCE_SUBSETS = dict(
lldp_global=Lldp_globalFacts, lldp_global=Lldp_globalFacts,
vlans=VlansFacts, vlans=VlansFacts,
lldp_interfaces=Lldp_interfacesFacts,
) )

View file

@ -0,0 +1,88 @@
#
# -*- 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 exos 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.exos.argspec.lldp_interfaces.lldp_interfaces import Lldp_interfacesArgs
from ansible.module_utils.network.exos.exos import send_requests
class Lldp_interfacesFacts(object):
""" The exos 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:
request = [{
"path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4",
"method": "GET"
}]
data = send_requests(self._module, requests=request)
objs = []
if data:
for d in data[0]["openconfig-lldp:interfaces"]["interface"]:
obj = self.render_config(self.generated_spec, d["config"])
if obj:
objs.append(obj)
ansible_facts['ansible_network_resources'].pop('lldp_interfaces', None)
facts = {}
if objs:
params = utils.validate_config(self.argument_spec, {'config': objs})
facts['lldp_interfaces'] = params['config']
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)
config["name"] = conf["name"]
config["enabled"] = bool(conf["enabled"])
return utils.remove_empties(config)

View file

@ -0,0 +1,680 @@
#!/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 exos_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: exos_lldp_interfaces
version_added: "2.10"
short_description: Manage link layer discovery protocol (LLDP) attributes of interfaces on EXOS platforms.
description:
- This module manages link layer discovery protocol (LLDP) attributes of interfaces on Extreme Networks EXOS platforms.
author: Jayalakshmi Viswanathan (@JayalakshmiV)
options:
config:
description: The list of link layer discovery protocol interface attribute configurations
type: list
elements: dict
suboptions:
name:
description:
- Name of the interface LLDP needs to be configured on.
type: str
required: True
enabled:
description:
- This is a boolean value to control disabling of LLDP on the interface C(name)
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:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": true,
# "name": "1"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "2"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "3"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "4"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "5"
# }
# }
# ]
# }
# }
- name: Merge provided configuration with device configuration
exos_lldp_interfaces:
config:
- name: '2'
enabled: false
- name: '5'
enabled: true
state: merged
# Module Execution Results:
# -------------------------
#
# "before":
# - name: '1'
# enabled: True
# - name: '2'
# enabled: True
# - name: '3'
# enabled: False
# - name: '4'
# enabled: True
# - name: '5'
# enabled: False
#
# "requests": [
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": false,
# "name": "2"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=2/config"
# },
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": true,
# "name": "5"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=5/config"
# }
# ]
#
# "after":
# - name: '1'
# enabled: True
# - name: '2'
# enabled: False
# - name: '3'
# enabled: False
# - name: '4'
# enabled: True
# - name: '5'
# enabled: True
# After state:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": true,
# "name": "1"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "2"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "3"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "4"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "5"
# }
# }
# ]
# }
# }
# Using replaced
# Before state:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": true,
# "name": "1"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "2"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "3"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "4"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "5"
# }
# }
# ]
# }
# }
- name: Replaces device configuration of listed lldp_interfaces with provided configuration
exos_lldp_interfaces:
config:
- name: '1'
enabled: false
- name: '3'
enabled: true
state: merged
# Module Execution Results:
# -------------------------
#
# "before":
# - name: '1'
# enabled: True
# - name: '2'
# enabled: True
# - name: '3'
# enabled: False
# - name: '4'
# enabled: True
# - name: '5'
# enabled: False
#
# "requests": [
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": false,
# "name": "1"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=1/config"
# },
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": true,
# "name": "3"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=3/config"
# }
# ]
#
# "after":
# - name: '1'
# enabled: False
# - name: '2'
# enabled: True
# - name: '3'
# enabled: True
# - name: '4'
# enabled: True
# - name: '5'
# enabled: False
# After state:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": false,
# "name": "1"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "2"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "3"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "4"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "5"
# }
# }
# ]
# }
# }
# Using deleted
# Before state:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": false,
# "name": "1"
# },
# },
# {
# "config": {
# "enabled": false,
# "name": "2"
# },
# },
# {
# "config": {
# "enabled": false,
# "name": "3"
# },
# }
# ]
# }
# }
- name: Delete lldp interface configuration (this will not delete other lldp configuration)
exos_lldp_interfaces:
config:
- name: '1'
- name: '3'
state: deleted
# Module Execution Results:
# -------------------------
#
# "before":
# - name: '1'
# enabled: False
# - name: '2'
# enabled: False
# - name: '3'
# enabled: False
#
# "requests": [
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": true,
# "name": "1"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=1/config"
# },
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": true,
# "name": "3"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=3/config"
# }
# ]
#
# "after":
# - name: '1'
# enabled: True
# - name: '2'
# enabled: False
# - name: '3'
# enabled: True
#
# After state:
# -------------
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": true,
# "name": "1"
# },
# },
# {
# "config": {
# "enabled": false,
# "name": "2"
# },
# },
# {
# "config": {
# "enabled": true,
# "name": "3"
# },
# }
# ]
# }
# }
# Using overridden
# Before state:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": true,
# "name": "1"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "2"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "3"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "4"
# }
# },
# {
# "config": {
# "enabled": false,
# "name": "5"
# }
# }
# ]
# }
# }
- name: Override device configuration of all lldp_interfaces with provided configuration
exos_lldp_interfaces:
config:
- name: '3'
enabled: true
state: overridden
# Module Execution Results:
# -------------------------
#
# "before":
# - name: '1'
# enabled: True
# - name: '2'
# enabled: True
# - name: '3'
# enabled: False
# - name: '4'
# enabled: True
# - name: '5'
# enabled: False
#
# "requests": [
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": true,
# "name": "5"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=5/config"
# },
# {
# "data": |
# {
# "openconfig-lldp:config": {
# "enabled": true,
# "name": "3"
# }
# }
# "method": "PATCH",
# "path": "/rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=3/config"
# }
# ]
#
# "after":
# - name: '1'
# enabled: True
# - name: '2'
# enabled: True
# - name: '3'
# enabled: True
# - name: '4'
# enabled: True
# - name: '5'
# enabled: True
# After state:
# -------------
#
# path: /rest/restconf/data/openconfig-lldp:lldp/interfaces?depth=4
# method: GET
# data:
# {
# "openconfig-lldp:interfaces": {
# "interface": [
# {
# "config": {
# "enabled": true,
# "name": "1"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "2"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "3"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "4"
# }
# },
# {
# "config": {
# "enabled": true,
# "name": "5"
# }
# }
# ]
# }
# }
"""
RETURN = """
before:
description: The configuration prior to the model invocation.
returned: always
sample: >
The configuration returned will always be in the same format
of the parameters above.
type: list
after:
description: The resulting configuration model invocation.
returned: when changed
sample: >
The configuration returned will always be in the same format
of the parameters above.
type: list
requests:
description: The set of requests pushed to the remote device.
returned: always
type: list
sample: [{"data": "...", "method": "...", "path": "..."}, {"data": "...", "method": "...", "path": "..."}, {"data": "...", "method": "...", "path": "..."}]
"""
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.network.exos.argspec.lldp_interfaces.lldp_interfaces import Lldp_interfacesArgs
from ansible.module_utils.network.exos.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', ))]
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()

View file

@ -0,0 +1,3 @@
---
testcase: "[^_].*"
test_items: []

View file

@ -0,0 +1,19 @@
---
- name: Collect all httpapi test cases
find:
paths: "{{ role_path }}/tests/httpapi"
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 }}"
- name: Run test case (connection=httpapi)
include: "{{ test_case_to_run }}"
vars:
ansible_connection: httpapi
with_items: "{{ test_items }}"
loop_control:
loop_var: test_case_to_run

View file

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

View file

@ -0,0 +1,5 @@
---
- name: Populate config
exos_config:
lines:
- disable lldp ports 2-5

View file

@ -0,0 +1,5 @@
---
- name: Restore initial config
exos_config:
lines:
- enable lldp ports all

View file

@ -0,0 +1,91 @@
---
- debug:
msg: "Start exos_lldp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}"
- include_tasks: _reset_config.yaml
- include_tasks: _populate_config.yaml
- set_fact:
config:
- enabled: true
name: '2'
- enabled: true
name: '3'
config_all:
- enabled: true
name: '4'
- enabled: true
name: '5'
- exos_facts:
gather_network_resources: lldp_interfaces
- block:
- name: Delete LLDP interface configuration
exos_lldp_interfaces: &deleted
config:
- name: '2'
- name: '3'
state: deleted
register: result
- name: Assert that correct set of results were generated
assert:
that:
- "deleted['requests_1']|symmetric_difference(result['requests']) == []"
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that after dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.after) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"
- name: Delete LLDP interface configuration
exos_lldp_interfaces:
config:
state: deleted
register: result
- name: Assert that correct set of results were generated
assert:
that:
- "deleted['requests_2']|symmetric_difference(result['requests']) == []"
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that after dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.after) == []"
- "config_all|difference(ansible_facts.network_resources.lldp_interfaces) == []"
- name: Delete attributes of all configured interfaces (IDEMPOTENT)
exos_lldp_interfaces: *deleted
register: result
- name: Assert that the previous task was idempotent
assert:
that:
- "result.changed == false"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that the before dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- set_fact:
expected_config: "{{ config }} + {{ config_all }}"
- assert:
that:
- "expected_config|difference(ansible_facts.network_resources.lldp_interfaces) == []"

View file

@ -0,0 +1,57 @@
---
- debug:
msg: "START exos_lldp_interfaces merged integration tests on connection={{ ansible_connection }}"
- include_tasks: _reset_config.yaml
- include_tasks: _populate_config.yaml
- set_fact:
config:
- enabled: false
name: '1'
- enabled: true
name: '2'
- exos_facts:
gather_network_resources: lldp_interfaces
- block:
- name: Merge the provided configuration with the existing running configuration
exos_lldp_interfaces: &merged
config: "{{ config }}"
state: merged
register: result
- name: Assert that correct set of results were generated
assert:
that:
- "merged['requests']|symmetric_difference(result['requests']) == []"
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that after dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.after) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"
- name: Merge the provided configuration with the existing running configuration (IDEMPOTENT)
exos_lldp_interfaces: *merged
register: result
- name: Assert that the previous task was idempotent
assert:
that:
- "result['changed'] == false"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that the before dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"

View file

@ -0,0 +1,56 @@
---
- debug:
msg: "Start exos_lldp_interfaces overridden integration tests ansible_connection={{ ansible_connection }}"
- include_tasks: _reset_config.yaml
- include_tasks: _populate_config.yaml
- set_fact:
config:
- enabled: true
name: '5'
- enabled: false
name: '6'
- exos_facts:
gather_network_resources: lldp_interfaces
- block:
- name: Override device LLDP interface configuration with provided configurations
exos_lldp_interfaces: &overridden
config: "{{ config }}"
state: overridden
register: result
- name: Assert that correct set of results were generated
assert:
that:
- "overridden['requests']|symmetric_difference(result['requests']) == []"
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that after dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.after) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"
- name: Override device LLDP interface configuration with provided configurations (IDEMPOTENT)
exos_lldp_interfaces: *overridden
register: result
- name: Assert that task was idempotent
assert:
that:
- "result['changed'] == false"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that the before dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"

View file

@ -0,0 +1,57 @@
---
- debug:
msg: "START exos_lldp_interfaces replaced integration tests on connection={{ ansible_connection }}"
- include_tasks: _reset_config.yaml
- include_tasks: _populate_config.yaml
- set_fact:
config:
- enabled: true
name: '3'
- enabled: false
name: '4'
- exos_facts:
gather_network_resources: lldp_interfaces
- block:
- name: Replace LLDP interface configuration with provided configuration
exos_lldp_interfaces: &replaced
config: "{{ config }}"
state: replaced
register: result
- name: Assert that correct set of results were generated
assert:
that:
- "replaced['requests']|symmetric_difference(result['requests']) == []"
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that after dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.after) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"
- name: Replace LLDP interface configuration with provided configuration (IDEMPOTENT)
exos_lldp_interfaces: *replaced
register: result
- name: Assert that task was idempotent
assert:
that:
- "result['changed'] == false"
- exos_facts:
gather_network_resources: lldp_interfaces
- name: Assert that the before dicts were correctly generated
assert:
that:
- "ansible_facts.network_resources.lldp_interfaces|symmetric_difference(result.before) == []"
- "config|difference(ansible_facts.network_resources.lldp_interfaces) == []"

View file

@ -0,0 +1,49 @@
---
merged:
requests:
- data: '{"openconfig-lldp:config": {"enabled": false, "name": "1"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=1/config
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "2"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=2/config
replaced:
requests:
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "3"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=3/config
overridden:
requests:
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "5"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=5/config
- data: '{"openconfig-lldp:config": {"enabled": false, "name": "6"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=6/config
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "2"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=2/config
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "3"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=3/config
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "4"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=4/config
deleted:
requests_1:
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "2"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=2/config
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "3"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=3/config
requests_2:
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "4"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=4/config
- data: '{"openconfig-lldp:config": {"enabled": true, "name": "5"}}'
method: PATCH
path: /rest/restconf/data/openconfig-lldp:lldp/interfaces/interface=5/config