summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNilashish Chakraborty <nilashishchakraborty8@gmail.com>2019-08-08 00:13:06 +0530
committerGitHub <noreply@github.com>2019-08-08 00:13:06 +0530
commit7b90e8aec4ad26e5e40c5c266c0bb6ae616c2e2a (patch)
tree19ec54ec228c14e8d3f291883768d35400e3c827
parent47796af64f822d5d94c0cb2024ce4dd2a55195e0 (diff)
downloadansible-7b90e8aec4ad26e5e40c5c266c0bb6ae616c2e2a.tar.gz
Add iosxr_lacp_resource module (#59724)
Signed-off-by: NilashishC <nilashishchakraborty8@gmail.com>
-rw-r--r--lib/ansible/module_utils/network/iosxr/argspec/facts/facts.py5
-rw-r--r--lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/__init__.py0
-rw-r--r--lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/lacp_interfaces.py79
-rw-r--r--lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/__init__.py0
-rw-r--r--lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/lacp_interfaces.py261
-rw-r--r--lib/ansible/module_utils/network/iosxr/facts/facts.py2
-rw-r--r--lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/__init__.py0
-rw-r--r--lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/lacp_interfaces.py104
-rw-r--r--lib/ansible/module_utils/network/iosxr/utils/utils.py31
-rw-r--r--lib/ansible/modules/network/iosxr/iosxr_facts.py10
-rw-r--r--lib/ansible/modules/network/iosxr/iosxr_lacp_interfaces.py533
-rw-r--r--test/integration/targets/iosxr_interface/tests/cli/basic.yaml4
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml3
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml20
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml2
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml26
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml32
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml46
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml54
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml54
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml52
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml60
-rw-r--r--test/integration/targets/iosxr_lacp_interfaces/vars/main.yaml137
23 files changed, 1509 insertions, 6 deletions
diff --git a/lib/ansible/module_utils/network/iosxr/argspec/facts/facts.py b/lib/ansible/module_utils/network/iosxr/argspec/facts/facts.py
index 600360db35..93959291de 100644
--- a/lib/ansible/module_utils/network/iosxr/argspec/facts/facts.py
+++ b/lib/ansible/module_utils/network/iosxr/argspec/facts/facts.py
@@ -20,7 +20,10 @@ class FactsArgs(object): # pylint: disable=R0903
choices = [
'all',
- 'lacp'
+ 'lacp',
+ '!lacp',
+ 'lacp_interfaces',
+ '!lacp_interfaces'
]
argument_spec = {
diff --git a/lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/__init__.py b/lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/__init__.py
diff --git a/lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/lacp_interfaces.py b/lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/lacp_interfaces.py
new file mode 100644
index 0000000000..f8a0070a5d
--- /dev/null
+++ b/lib/ansible/module_utils/network/iosxr/argspec/lacp_interfaces/lacp_interfaces.py
@@ -0,0 +1,79 @@
+#
+# -*- 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_lacp_interfaces module
+"""
+
+
+from __future__ import absolute_import, division, print_function
+__metaclass__ = type
+
+
+class Lacp_interfacesArgs(object): # pylint: disable=R0903
+ """The arg spec for the iosxr_lacp_interfaces module
+ """
+
+ def __init__(self, **kwargs):
+ pass
+
+ argument_spec = {
+ 'config': {
+ 'elements': 'dict',
+ 'options': {
+ 'churn_logging': {
+ 'choices': ['actor', 'partner', 'both'],
+ 'type': 'str'
+ },
+ 'collector_max_delay': {
+ 'type': 'int'
+ },
+ 'name': {
+ 'type': 'str'
+ },
+ 'period': {
+ 'type': 'int'
+ },
+ 'switchover_suppress_flaps': {
+ 'type': 'int'
+ },
+ 'system': {
+ 'options': {
+ 'mac': {
+ 'type': 'str'
+ },
+ 'priority': {
+ 'type': 'int'
+ }
+ },
+ 'type': 'dict'
+ }
+ },
+ 'type': 'list'
+ },
+ 'state': {
+ 'choices': ['merged', 'replaced', 'overridden', 'deleted'],
+ 'default': 'merged',
+ 'type': 'str'
+ }
+ } # pylint: disable=C0301
diff --git a/lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/__init__.py b/lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/__init__.py
diff --git a/lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/lacp_interfaces.py b/lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/lacp_interfaces.py
new file mode 100644
index 0000000000..8967d62f58
--- /dev/null
+++ b/lib/ansible/module_utils/network/iosxr/config/lacp_interfaces/lacp_interfaces.py
@@ -0,0 +1,261 @@
+#
+# -*- 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_lacp_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
+from ansible.module_utils.network.iosxr.facts.facts import Facts
+from ansible.module_utils.network.common.utils import dict_diff, remove_empties
+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 Lacp_interfaces(ConfigBase):
+ """
+ The iosxr_lacp_interfaces class
+ """
+
+ gather_subset = [
+ '!all',
+ '!min',
+ ]
+
+ gather_network_resources = [
+ 'lacp_interfaces',
+ ]
+
+ def __init__(self, module):
+ super(Lacp_interfaces, self).__init__(module)
+
+ def get_lacp_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)
+ lacp_interfaces_facts = facts['ansible_network_resources'].get('lacp_interfaces')
+ if not lacp_interfaces_facts:
+ return []
+ return lacp_interfaces_facts
+
+ def execute_module(self):
+ """ Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ result = {'changed': False}
+ commands = list()
+ warnings = list()
+
+ existing_lacp_interfaces_facts = self.get_lacp_interfaces_facts()
+ commands.extend(self.set_config(existing_lacp_interfaces_facts))
+ if commands:
+ if not self._module.check_mode:
+ self._connection.edit_config(commands)
+ result['changed'] = True
+ result['commands'] = commands
+
+ changed_lacp_interfaces_facts = self.get_lacp_interfaces_facts()
+
+ result['before'] = existing_lacp_interfaces_facts
+ if result['changed']:
+ result['after'] = changed_lacp_interfaces_facts
+
+ result['warnings'] = warnings
+ return result
+
+ def set_config(self, existing_lacp_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_lacp_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.extend(
+ Lacp_interfaces._state_overridden(
+ want, have
+ )
+ )
+
+ elif state == 'deleted':
+ if not want:
+ for intf in have:
+ commands.extend(
+ Lacp_interfaces._state_deleted(
+ {'name': intf['name']},
+ intf
+ )
+ )
+ else:
+ for item in want:
+ obj_in_have = search_obj_in_list(item['name'], have)
+ commands.extend(
+ Lacp_interfaces._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(
+ Lacp_interfaces._state_merged(
+ item, obj_in_have
+ )
+ )
+
+ elif state == 'replaced':
+ commands.extend(
+ Lacp_interfaces._state_replaced(
+ item, obj_in_have
+ )
+ )
+
+ return commands
+
+ @staticmethod
+ def _state_replaced(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 = Lacp_interfaces._state_deleted(want, have)
+
+ merged_commands = Lacp_interfaces._state_merged(want, have)
+
+ if merged_commands and replaced_commands:
+ del merged_commands[0]
+
+ commands.extend(replaced_commands)
+ commands.extend(merged_commands)
+
+ return commands
+
+ @staticmethod
+ def _state_overridden(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(Lacp_interfaces._state_deleted({'name': intf['name']}, intf))
+
+ for intf in want:
+ intf_in_have = search_obj_in_list(intf['name'], have)
+ commands.extend(Lacp_interfaces._state_replaced(intf, intf_in_have))
+
+ return commands
+
+ @staticmethod
+ def _state_merged(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(Lacp_interfaces._compute_commands(key, value))
+
+ if commands:
+ pad_commands(commands, want['name'])
+
+ return commands
+
+ @staticmethod
+ def _state_deleted(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(Lacp_interfaces._compute_commands(key, value, remove=True))
+
+ if commands:
+ pad_commands(commands, have['name'])
+
+ return commands
+
+ @staticmethod
+ def _compute_commands(key, value, remove=False):
+ if key == "churn_logging":
+ cmd = "lacp churn logging {0}".format(value)
+
+ elif key == "collector_max_delay":
+ cmd = "lacp collector-max-delay {0}".format(value)
+
+ elif key == "period":
+ cmd = "lacp period {0}".format(value)
+
+ elif key == "switchover_suppress_flaps":
+ cmd = "lacp switchover suppress-flaps {0}".format(value)
+
+ elif key == 'mac':
+ cmd = "lacp system mac {0}".format(value)
+
+ elif key == 'priority':
+ cmd = "lacp system priority {0}".format(value)
+
+ if remove:
+ cmd = "no " + cmd
+
+ return cmd
diff --git a/lib/ansible/module_utils/network/iosxr/facts/facts.py b/lib/ansible/module_utils/network/iosxr/facts/facts.py
index fad4f617fb..7ace062e35 100644
--- a/lib/ansible/module_utils/network/iosxr/facts/facts.py
+++ b/lib/ansible/module_utils/network/iosxr/facts/facts.py
@@ -16,6 +16,7 @@ __metaclass__ = type
from ansible.module_utils.network.iosxr.argspec.facts.facts import FactsArgs
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_interfaces.lacp_interfaces import Lacp_interfacesFacts
from ansible.module_utils.network.iosxr.facts.legacy.\
base import Default, Hardware, Interfaces, Config
@@ -28,6 +29,7 @@ FACT_LEGACY_SUBSETS = dict(
)
FACT_RESOURCE_SUBSETS = dict(
lacp=LacpFacts,
+ lacp_interfaces=Lacp_interfacesFacts
)
diff --git a/lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/__init__.py b/lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/__init__.py
diff --git a/lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/lacp_interfaces.py b/lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/lacp_interfaces.py
new file mode 100644
index 0000000000..d7744c6ad2
--- /dev/null
+++ b/lib/ansible/module_utils/network/iosxr/facts/lacp_interfaces/lacp_interfaces.py
@@ -0,0 +1,104 @@
+#
+# -*- 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 lacp_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.lacp_interfaces.lacp_interfaces import Lacp_interfacesArgs
+from ansible.module_utils.six import iteritems
+
+
+class Lacp_interfacesFacts(object):
+ """ The iosxr lacp_interfaces fact class
+ """
+
+ def __init__(self, module, subspec='config', options='options'):
+ self._module = module
+ self.argument_spec = Lacp_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 lacp_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('lacp_interfaces', None)
+ facts = {}
+ if objs:
+ facts['lacp_interfaces'] = []
+ params = utils.validate_config(self.argument_spec, {'config': objs})
+ for cfg in params['config']:
+ facts['lacp_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)
+
+ temp = {
+ 'churn_logging': 'lacp churn logging',
+ 'switchover_suppress_flaps': 'lacp switchover suppress-flaps',
+ 'collector_max_delay': 'lacp collector-max-delay',
+ 'period': 'lacp period'
+ }
+
+ for key, value in iteritems(temp):
+ config[key] = utils.parse_conf_arg(
+ conf, value)
+
+ for key in config['system'].keys():
+ config['system'][key] = utils.parse_conf_arg(
+ conf, 'lacp system {0}'.format(key))
+
+ return utils.remove_empties(config)
diff --git a/lib/ansible/module_utils/network/iosxr/utils/utils.py b/lib/ansible/module_utils/network/iosxr/utils/utils.py
index 5f132784f9..89a85d3a7a 100644
--- a/lib/ansible/module_utils/network/iosxr/utils/utils.py
+++ b/lib/ansible/module_utils/network/iosxr/utils/utils.py
@@ -30,3 +30,34 @@ def flatten_dict(x):
result[key] = value
return result
+
+
+def dict_delete(base, comparable):
+ """
+
+ This function generates a dict containing key, value pairs for keys
+ that are present in the `base` dict but not present in the `comparable`
+ dict.
+
+ :param base: dict object to base the diff on
+ :param comparable: dict object to compare against base
+
+ :returns: new dict object with key, value pairs that needs to be deleted.
+
+ """
+ to_delete = dict()
+
+ for key in base:
+ if isinstance(base[key], dict):
+ sub_diff = dict_delete(base[key], comparable.get(key, {}))
+ if sub_diff:
+ to_delete[key] = sub_diff
+ else:
+ if key not in comparable:
+ to_delete[key] = base[key]
+
+ return to_delete
+
+
+def pad_commands(commands, interface):
+ commands.insert(0, 'interface {0}'.format(interface))
diff --git a/lib/ansible/modules/network/iosxr/iosxr_facts.py b/lib/ansible/modules/network/iosxr/iosxr_facts.py
index 190e7cb1fd..7a701f82a3 100644
--- a/lib/ansible/modules/network/iosxr/iosxr_facts.py
+++ b/lib/ansible/modules/network/iosxr/iosxr_facts.py
@@ -51,7 +51,7 @@ options:
can also be used with an initial C(M(!)) to specify that a
specific subset should not be collected.
required: false
- choices: ['all', 'lacp']
+ choices: ['all', 'lacp', '!lacp', 'lacp_interfaces', '!lacp_interfaces']
version_added: "2.9"
"""
@@ -71,7 +71,7 @@ EXAMPLES = """
gather_subset:
- "!hardware"
-# Collect only the lag_interfaces facts
+# Collect only the lacp facts
- iosxr_facts:
gather_subset:
- "!all"
@@ -79,12 +79,12 @@ EXAMPLES = """
gather_network_resources:
- lacp
-# Do not collect lag_interfaces facts
+# Do not collect lacp_interfaces facts
- iosxr_facts:
gather_network_resources:
- - "!lacp"
+ - "!lacp_interfaces"
-# Collect lag_interfaces and minimal default facts
+# Collect lacp and minimal default facts
- iosxr_facts:
gather_subset: min
gather_network_resources: lacp
diff --git a/lib/ansible/modules/network/iosxr/iosxr_lacp_interfaces.py b/lib/ansible/modules/network/iosxr/iosxr_lacp_interfaces.py
new file mode 100644
index 0000000000..3e47bbc2b8
--- /dev/null
+++ b/lib/ansible/modules/network/iosxr/iosxr_lacp_interfaces.py
@@ -0,0 +1,533 @@
+#!/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_lacp_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_lacp_interfaces
+version_added: 2.9
+short_description: Manage Link Aggregation Control Protocol (LACP) attributes of interfaces on IOS-XR devices.
+description:
+ - This module manages Link Aggregation Control Protocol (LACP) attributes of interfaces on IOS-XR devices.
+author: Nilashish Chakraborty (@nilashishc)
+options:
+ config:
+ description: A dictionary of LACP interfaces options.
+ type: list
+ suboptions:
+ name:
+ description:
+ - Name/Identifier of the interface or Ether-Bundle.
+ type: str
+ churn_logging:
+ description:
+ - Specifies the parameter for logging of LACP churn events.
+ - Valid only for ether-bundles.
+ - Mode 'actor' logs actor churn events only.
+ - Mode 'partner' logs partner churn events only.
+ - Mode 'both' logs actor and partner churn events only.
+ type: str
+ choices: ['actor', 'partner', 'both']
+ collector_max_delay:
+ description:
+ - Specifies the collector max delay to be signaled to the LACP partner.
+ - Valid only for ether-bundles.
+ - Refer to vendor documentation for valid values.
+ type: int
+ period:
+ description:
+ - Specifies the rate at which packets are sent or received.
+ - For ether-bundles, this specifies the period to be used
+ by its member links.
+ - Refer to vendor documentation for valid values.
+ type: int
+ switchover_suppress_flaps:
+ description:
+ - Specifies the time for which to suppress flaps during
+ a LACP switchover.
+ - Valid only for ether-bundles.
+ - Refer to vendor documentation for valid values.
+ type: int
+ system:
+ description:
+ - This dict object contains configurable options related to LACP
+ system parameters for ether-bundles.
+ type: dict
+ suboptions:
+ priority:
+ description:
+ - Specifies the system priority to use in LACP negotiations for
+ the bundle.
+ - Refer to vendor documentation for valid values.
+ type: int
+ mac:
+ description:
+ - Specifies the system ID to use in LACP negotiations for
+ the bundle, encoded as a MAC address.
+ type: str
+ 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/0/CPU0:an-iosxr#sh running-config interface
+# Sun Jul 21 18:01:35.079 UTC
+# interface Bundle-Ether10
+# !
+# interface Bundle-Ether11
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1'
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+#
+
+ - name: Merge provided configuration with device configuration
+ iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/1
+ period: 200
+ state: merged
+
+#
+#
+# -----------
+# After state
+# -----------
+#
+#
+# RP/0/0/CPU0:an-iosxr#sh run int
+# Sun Jul 21 18:24:52.413 UTC
+# interface Bundle-Ether10
+# lacp churn logging actor
+# lacp switchover suppress-flaps 500
+# lacp collector-max-delay 100
+# !
+# interface Bundle-Ether11
+# lacp system mac 00c2.4c00.bd15
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# lacp period 200
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+
+
+# Using replaced
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# RP/0/0/CPU0:an-iosxr#sh run int
+# Sun Jul 21 18:24:52.413 UTC
+# interface Bundle-Ether10
+# lacp churn logging actor
+# lacp switchover suppress-flaps 500
+# lacp collector-max-delay 100
+# !
+# interface Bundle-Ether11
+# lacp system mac 00c2.4c00.bd15
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# lacp period 200
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+
+ - name: Replace LACP configuration of listed interfaces with provided configuration
+ iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: GigabitEthernet0/0/0/2
+ period: 300
+ state: replaced
+
+#
+#
+# -----------
+# After state
+# -----------
+#
+#
+# RP/0/0/CPU0:an-iosxr#sh run int
+# Sun Jul 21 18:50:21.929 UTC
+# interface Bundle-Ether10
+# lacp churn logging partner
+# !
+# interface Bundle-Ether11
+# lacp system mac 00c2.4c00.bd15
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# lacp period 200
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# lacp period 300
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+#
+
+
+# Using overridden
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# RP/0/0/CPU0:an-iosxr#sh run int
+# Sun Jul 21 18:24:52.413 UTC
+# interface Bundle-Ether10
+# lacp churn logging actor
+# lacp switchover suppress-flaps 500
+# lacp collector-max-delay 100
+# !
+# interface Bundle-Ether11
+# lacp system mac 00c2.4c00.bd15
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# lacp period 200
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# lacp period 200
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+#
+
+ - name: Overridde all interface LACP configuration with provided configuration
+ iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether12
+ churn_logging: both
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+ state: overridden
+
+#
+#
+# -----------
+# After state
+# -----------
+#
+#
+# RP/0/0/CPU0:an-iosxr(config-if)#do sh run int
+# Sun Jul 21 19:32:36.115 UTC
+# interface Bundle-Ether10
+# !
+# interface Bundle-Ether11
+# !
+# interface Bundle-Ether12
+# lacp churn logging both
+# lacp switchover suppress-flaps 500
+# lacp collector-max-delay 100
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# lacp period 300
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+
+
+# Using deleted
+#
+#
+# ------------
+# Before state
+# ------------
+#
+#
+# RP/0/0/CPU0:an-iosxr#sh run int
+# Sun Jul 21 18:24:52.413 UTC
+# interface Bundle-Ether10
+# lacp churn logging actor
+# lacp switchover suppress-flaps 500
+# lacp collector-max-delay 100
+# !
+# interface Bundle-Ether11
+# lacp non-revertive
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# lacp period 200
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# lacp period 300
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+
+ - name: Deleted LACP configurations of provided interfaces (Note - This won't delete the interface itself)
+ iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ - name: Bundle-Ether11
+ - name: GigabitEthernet0/0/0/1
+ - name: GigabitEthernet0/0/0/2
+ state: deleted
+
+#
+#
+# -----------
+# After state
+# -----------
+#
+#
+# RP/0/0/CPU0:an-iosxr#sh run int
+# Sun Jul 21 19:51:03.499 UTC
+# interface Bundle-Ether10
+# !
+# interface Bundle-Ether11
+# !
+# interface Bundle-Ether12
+# !
+# interface Loopback888
+# description test for ansible
+# shutdown
+# !
+# interface MgmtEth0/0/CPU0/0
+# ipv4 address 192.0.2.11 255.255.255.0
+# !
+# interface GigabitEthernet0/0/0/1
+# description 'GigabitEthernet - 1"
+# !
+# interface GigabitEthernet0/0/0/2
+# description "GigabitEthernet - 2"
+# !
+# interface GigabitEthernet0/0/0/3
+# description "GigabitEthernet - 3"
+# !
+# interface GigabitEthernet0/0/0/4
+# description "GigabitEthernet - 4"
+# !
+#
+
+
+"""
+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 Bundle-Ether10', 'lacp churn logging partner', 'lacp period 150']
+"""
+
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.network.iosxr.argspec.lacp_interfaces.lacp_interfaces import Lacp_interfacesArgs
+from ansible.module_utils.network.iosxr.config.lacp_interfaces.lacp_interfaces import Lacp_interfaces
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(argument_spec=Lacp_interfacesArgs.argument_spec,
+ supports_check_mode=True)
+
+ result = Lacp_interfaces(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/integration/targets/iosxr_interface/tests/cli/basic.yaml b/test/integration/targets/iosxr_interface/tests/cli/basic.yaml
index 05ca4f2980..403893d81f 100644
--- a/test/integration/targets/iosxr_interface/tests/cli/basic.yaml
+++ b/test/integration/targets/iosxr_interface/tests/cli/basic.yaml
@@ -231,6 +231,8 @@
- name: Delete interface aggregate
iosxr_interface:
aggregate:
+ - name: GigabitEthernet0/0/0/2
+ - name: GigabitEthernet0/0/0/3
- name: GigabitEthernet0/0/0/4
- name: GigabitEthernet0/0/0/5
state: absent
@@ -246,6 +248,8 @@
- name: Delete interface aggregate (idempotent)
iosxr_interface:
aggregate:
+ - name: GigabitEthernet0/0/0/2
+ - name: GigabitEthernet0/0/0/3
- name: GigabitEthernet0/0/0/4
- name: GigabitEthernet0/0/0/5
state: absent
diff --git a/test/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml b/test/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml
new file mode 100644
index 0000000000..164afead28
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: "[^_].*"
+test_items: []
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml b/test/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml
new file mode 100644
index 0000000000..337e34133b
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tasks/cli.yaml
@@ -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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml b/test/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml
new file mode 100644
index 0000000000..415c99d8b1
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tasks/main.yaml
@@ -0,0 +1,2 @@
+---
+- { include: cli.yaml, tags: ['cli'] }
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml
new file mode 100644
index 0000000000..630828d6d1
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/_populate.yaml
@@ -0,0 +1,26 @@
+---
+- name: Setup Bundle-Ether10
+ iosxr_config:
+ lines:
+ - lacp churn logging actor
+ - lacp switchover suppress-flaps 500
+ - lacp collector-max-delay 100
+ parents: interface Bundle-Ether10
+
+- name: Setup Bundle-Ether11
+ iosxr_config:
+ lines:
+ - lacp system mac 00c2.4c00.bd15
+ parents: interface Bundle-Ether11
+
+- name: Setup GigE0
+ iosxr_config:
+ lines:
+ - lacp period 100
+ parents: interface GigabitEthernet0/0/0/0
+
+- name: Setup GigE1
+ iosxr_config:
+ lines:
+ - lacp period 200
+ parents: interface GigabitEthernet0/0/0/1
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml
new file mode 100644
index 0000000000..bf6e6afca3
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/_remove_config.yaml
@@ -0,0 +1,32 @@
+---
+- name: Remove Bundles
+ cli_config:
+ config: "{{ lines }}"
+ vars:
+ lines: |
+ no interface Bundle-Ether10
+ no interface Bundle-Ether11
+ no interface Bundle-Ether12
+
+- name: Remove LACP interface config
+ iosxr_config:
+ lines:
+ - no lacp period
+ - shutdown
+ parents: "interface GigabitEthernet{{ item }}"
+ loop:
+ - 0/0/0/0
+ - 0/0/0/1
+
+# 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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml
new file mode 100644
index 0000000000..a2aa5e1dbc
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/deleted.yaml
@@ -0,0 +1,46 @@
+---
+- debug:
+ msg: "Start iosxr_lacp_interfaces deleted integration tests ansible_connection={{ ansible_connection }}"
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Delete LACP attributes of all interfaces
+ iosxr_lacp_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_lacp_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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml
new file mode 100644
index 0000000000..be5134091b
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/merged.yaml
@@ -0,0 +1,54 @@
+---
+- debug:
+ msg: "START iosxr_lacp_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_lacp_interfaces: &merged
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/1
+ period: 100
+ 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_lacp_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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml
new file mode 100644
index 0000000000..0ad9ac47a4
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/overridden.yaml
@@ -0,0 +1,54 @@
+---
+- debug:
+ msg: "START iosxr_lacp_interfaces overridden integration tests on connection={{ ansible_connection }}"
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+ - name: Overridde all interface LACP configuration with provided configuration
+ iosxr_lacp_interfaces: &overridden
+ config:
+ - name: Bundle-Ether12
+ churn_logging: both
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+ 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_lacp_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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml
new file mode 100644
index 0000000000..0dcb8505e0
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/replaced.yaml
@@ -0,0 +1,52 @@
+---
+- debug:
+ msg: "START iosxr_lacp_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_lacp_interfaces: &replaced
+ config:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+ 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_lacp_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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml
new file mode 100644
index 0000000000..a73965c545
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/tests/cli/rtt.yaml
@@ -0,0 +1,60 @@
+---
+- debug:
+ msg: "START isoxr_lacp_interfaces round trip integration tests on connection={{ ansible_connection }}"
+
+- block:
+ - include_tasks: _remove_config.yaml
+
+ - name: Apply the provided configuration (base config)
+ iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ collector_max_delay: 200
+
+ - name: Bundle-Ether11
+ period: 100
+
+ - name: GigabitEthernet0/0/0/0
+ period: 200
+ state: merged
+ register: base_config
+
+ - name: Gather interfaces facts
+ iosxr_facts:
+ gather_subset:
+ - "!all"
+ - "!min"
+ gather_network_resources:
+ - lacp_interfaces
+
+ - name: Apply the provided configuration (config to be reverted)
+ iosxr_lacp_interfaces:
+ config:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: Bundle-Ether11
+ period: 200
+
+ - name: GigabitEthernet0/0/0/0
+ period: 300
+ 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_lacp_interfaces:
+ config: "{{ ansible_facts['network_resources']['lacp_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
diff --git a/test/integration/targets/iosxr_lacp_interfaces/vars/main.yaml b/test/integration/targets/iosxr_lacp_interfaces/vars/main.yaml
new file mode 100644
index 0000000000..ffe921bd54
--- /dev/null
+++ b/test/integration/targets/iosxr_lacp_interfaces/vars/main.yaml
@@ -0,0 +1,137 @@
+---
+merged:
+ before:
+ - name: GigabitEthernet0/0/0/0
+
+ - name: GigabitEthernet0/0/0/1
+
+ commands:
+ - "interface Bundle-Ether10"
+ - "lacp churn logging actor"
+ - "lacp switchover suppress-flaps 500"
+ - "lacp collector-max-delay 100"
+ - "interface Bundle-Ether11"
+ - "lacp system mac 00c2.4c00.bd15"
+ - "interface GigabitEthernet0/0/0/1"
+ - "lacp period 100"
+
+ after:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ switchover_suppress_flaps: 500
+ collector_max_delay: 100
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/0
+
+ - name: GigabitEthernet0/0/0/1
+ period: 100
+
+populate:
+ - name: Bundle-Ether10
+ churn_logging: actor
+ switchover_suppress_flaps: 500
+ collector_max_delay: 100
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/0
+ period: 100
+
+ - name: GigabitEthernet0/0/0/1
+ period: 200
+
+replaced:
+ commands:
+ - "interface Bundle-Ether10"
+ - "no lacp switchover suppress-flaps 500"
+ - "no lacp collector-max-delay 100"
+ - "lacp churn logging partner"
+ - "interface GigabitEthernet0/0/0/1"
+ - "lacp period 300"
+
+ after:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: Bundle-Ether11
+ system:
+ mac: 00c2.4c00.bd15
+
+ - name: GigabitEthernet0/0/0/0
+ period: 100
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+
+overridden:
+ commands:
+ - "interface Bundle-Ether10"
+ - "no lacp switchover suppress-flaps 500"
+ - "no lacp collector-max-delay 100"
+ - "no lacp churn logging actor"
+ - "interface Bundle-Ether11"
+ - "no lacp system mac 00c2.4c00.bd15"
+ - "interface GigabitEthernet0/0/0/0"
+ - "no lacp period 100"
+ - "interface Bundle-Ether12"
+ - "lacp churn logging both"
+ - "lacp collector-max-delay 100"
+ - "lacp switchover suppress-flaps 500"
+ - "interface GigabitEthernet0/0/0/1"
+ - "lacp period 300"
+
+ after:
+ - name: Bundle-Ether10
+
+ - name: Bundle-Ether11
+
+ - name: Bundle-Ether12
+ churn_logging: both
+ collector_max_delay: 100
+ switchover_suppress_flaps: 500
+
+ - name: GigabitEthernet0/0/0/0
+
+ - name: GigabitEthernet0/0/0/1
+ period: 300
+
+deleted:
+ commands:
+ - "interface Bundle-Ether10"
+ - "no lacp switchover suppress-flaps 500"
+ - "no lacp collector-max-delay 100"
+ - "no lacp churn logging actor"
+ - "interface Bundle-Ether11"
+ - "no lacp system mac 00c2.4c00.bd15"
+ - "interface GigabitEthernet0/0/0/0"
+ - "no lacp period 100"
+ - "interface GigabitEthernet0/0/0/1"
+ - "no lacp period 200"
+
+ after:
+ - name: Bundle-Ether10
+
+ - name: Bundle-Ether11
+
+ - name: GigabitEthernet0/0/0/0
+
+ - name: GigabitEthernet0/0/0/1
+
+round_trip:
+ after:
+ - name: Bundle-Ether10
+ churn_logging: partner
+
+ - name: Bundle-Ether11
+ period: 200
+
+ - name: GigabitEthernet0/0/0/0
+ period: 300
+
+ - name: GigabitEthernet0/0/0/1