From 2c432f8bc78ca492a5c4bf8cfd4a3b8e6442fa03 Mon Sep 17 00:00:00 2001 From: Nilashish Chakraborty Date: Tue, 6 Aug 2019 19:30:58 +0530 Subject: [PATCH] Add vyos_l3_interfaces resource module (#59929) Signed-off-by: NilashishC --- .../rst/porting_guides/porting_guide_2.9.rst | 2 + .../network/vyos/argspec/facts/facts.py | 4 +- .../vyos/argspec/l3_interfaces/__init__.py | 0 .../argspec/l3_interfaces/l3_interfaces.py | 101 +++++ .../vyos/config/l3_interfaces/__init__.py | 0 .../config/l3_interfaces/l3_interfaces.py | 274 +++++++++++++ .../module_utils/network/vyos/facts/facts.py | 2 + .../vyos/facts/l3_interfaces/__init__.py | 0 .../vyos/facts/l3_interfaces/l3_interfaces.py | 130 ++++++ .../module_utils/network/vyos/utils/utils.py | 13 + ..._l3_interface.py => _vyos_l3_interface.py} | 6 +- .../modules/network/vyos/vyos_facts.py | 2 +- .../network/vyos/vyos_l3_interfaces.py | 372 ++++++++++++++++++ .../vyos_l3_interfaces/defaults/main.yaml | 3 + .../targets/vyos_l3_interfaces/meta/main.yml | 2 + .../targets/vyos_l3_interfaces/tasks/cli.yaml | 20 + .../vyos_l3_interfaces/tasks/main.yaml | 2 + .../tests/cli/_populate.yaml | 11 + .../tests/cli/_remove_config.yaml | 13 + .../vyos_l3_interfaces/tests/cli/deleted.yaml | 48 +++ .../vyos_l3_interfaces/tests/cli/merged.yaml | 58 +++ .../tests/cli/overridden.yaml | 52 +++ .../tests/cli/replaced.yaml | 52 +++ .../targets/vyos_l3_interfaces/vars/main.yaml | 114 ++++++ test/sanity/ignore.txt | 16 +- 25 files changed, 1286 insertions(+), 11 deletions(-) create mode 100644 lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/__init__.py create mode 100644 lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py create mode 100644 lib/ansible/module_utils/network/vyos/config/l3_interfaces/__init__.py create mode 100644 lib/ansible/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py create mode 100644 lib/ansible/module_utils/network/vyos/facts/l3_interfaces/__init__.py create mode 100644 lib/ansible/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py rename lib/ansible/modules/network/vyos/{vyos_l3_interface.py => _vyos_l3_interface.py} (98%) create mode 100644 lib/ansible/modules/network/vyos/vyos_l3_interfaces.py create mode 100644 test/integration/targets/vyos_l3_interfaces/defaults/main.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/meta/main.yml create mode 100644 test/integration/targets/vyos_l3_interfaces/tasks/cli.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tasks/main.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml create mode 100644 test/integration/targets/vyos_l3_interfaces/vars/main.yaml diff --git a/docs/docsite/rst/porting_guides/porting_guide_2.9.rst b/docs/docsite/rst/porting_guides/porting_guide_2.9.rst index 3b8f883a221..33952dd414f 100644 --- a/docs/docsite/rst/porting_guides/porting_guide_2.9.rst +++ b/docs/docsite/rst/porting_guides/porting_guide_2.9.rst @@ -65,6 +65,8 @@ The following modules will be removed in Ansible 2.13. Please update update your * nxos_linkagg use :ref:`nxos_lag_interfaces ` instead. * vyos_interface use :ref:`vyos_interfaces ` instead. + +* vyos_l3_interface use :ref:`vyos_l3_interfaces ` instead. The following functionality will be removed in Ansible 2.12. Please update update your playbooks accordingly. diff --git a/lib/ansible/module_utils/network/vyos/argspec/facts/facts.py b/lib/ansible/module_utils/network/vyos/argspec/facts/facts.py index 0ad41a094c4..456c8bd1e2f 100644 --- a/lib/ansible/module_utils/network/vyos/argspec/facts/facts.py +++ b/lib/ansible/module_utils/network/vyos/argspec/facts/facts.py @@ -20,7 +20,9 @@ class FactsArgs(object): # pylint: disable=R0903 choices = [ 'all', 'interfaces', - '!interfaces' + '!interfaces', + 'l3_interfaces', + '!l3_interfaces' ] argument_spec = { diff --git a/lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/__init__.py b/lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py b/lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py new file mode 100644 index 00000000000..e5785a8308e --- /dev/null +++ b/lib/ansible/module_utils/network/vyos/argspec/l3_interfaces/l3_interfaces.py @@ -0,0 +1,101 @@ +# +# -*- 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 vyos_l3_interfaces module +""" + + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +class L3_interfacesArgs(object): # pylint: disable=R0903 + """The arg spec for the vyos_l3_interfaces module + """ + + def __init__(self, **kwargs): + pass + + argument_spec = { + 'config': { + 'elements': 'dict', + 'options': { + 'ipv4': { + 'elements': 'dict', + 'options': { + 'address': { + 'type': 'str' + } + }, + 'type': 'list' + }, + 'ipv6': { + 'elements': 'dict', + 'options': { + 'address': { + 'type': 'str' + } + }, + 'type': 'list' + }, + 'name': { + 'required': True, + 'type': 'str' + }, + 'vifs': { + 'elements': 'dict', + 'options': { + 'ipv4': { + 'elements': 'dict', + 'options': { + 'address': { + 'type': 'str' + } + }, + 'type': 'list' + }, + 'ipv6': { + 'elements': 'dict', + 'options': { + 'address': { + 'type': 'str' + } + }, + 'type': 'list' + }, + 'vlan_id': { + 'type': 'int' + } + }, + 'type': 'list' + } + }, + 'type': 'list' + }, + 'state': { + 'choices': ['merged', 'replaced', 'overridden', 'deleted'], + 'default': 'merged', + 'type': 'str' + } + } # pylint: disable=C0301 diff --git a/lib/ansible/module_utils/network/vyos/config/l3_interfaces/__init__.py b/lib/ansible/module_utils/network/vyos/config/l3_interfaces/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/ansible/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py b/lib/ansible/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py new file mode 100644 index 00000000000..43ea03397af --- /dev/null +++ b/lib/ansible/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py @@ -0,0 +1,274 @@ +# +# -*- 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 vyos_l3_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 copy import deepcopy +from ansible.module_utils.network.common.cfg.base import ConfigBase +from ansible.module_utils.network.common.utils import to_list, remove_empties +from ansible.module_utils.six import iteritems +from ansible.module_utils.network.vyos.facts.facts import Facts +from ansible.module_utils.network. \ + vyos.utils.utils import search_obj_in_list, get_interface_type, diff_list_of_dicts + + +class L3_interfaces(ConfigBase): + """ + The vyos_l3_interfaces class + """ + + gather_subset = [ + '!all', + '!min', + ] + + gather_network_resources = [ + 'l3_interfaces', + ] + + def __init__(self, module): + super(L3_interfaces, self).__init__(module) + + def get_l3_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) + l3_interfaces_facts = facts['ansible_network_resources'].get('l3_interfaces') + if not l3_interfaces_facts: + return [] + return l3_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_l3_interfaces_facts = self.get_l3_interfaces_facts() + commands.extend(self.set_config(existing_l3_interfaces_facts)) + if commands: + if self._module.check_mode: + resp = self._connection.edit_config(commands, commit=False) + else: + resp = self._connection.edit_config(commands) + result['changed'] = True + + result['commands'] = commands + + if self._module._diff: + result['diff'] = resp['diff'] if result['changed'] else None + + changed_l3_interfaces_facts = self.get_l3_interfaces_facts() + + result['before'] = existing_l3_interfaces_facts + if result['changed']: + result['after'] = changed_l3_interfaces_facts + + result['warnings'] = warnings + return result + + def set_config(self, existing_l3_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_l3_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(self._state_overridden(want=want, have=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 not obj_in_have: + obj_in_have = {'name': item['name']} + + 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 = [] + if have: + commands.extend(self._state_deleted(want, have)) + + commands.extend(self._state_merged(want, have)) + + 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 = [] + want_copy = deepcopy(remove_empties(want)) + have_copy = deepcopy(remove_empties(have)) + + want_vifs = want_copy.pop('vifs', []) + have_vifs = have_copy.pop('vifs', []) + + for update in self._get_updates(want_copy, have_copy): + for key, value in iteritems(update): + commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'])) + + if want_vifs: + for want_vif in want_vifs: + have_vif = search_obj_in_list(want_vif['vlan_id'], have_vifs, key='vlan_id') + if not have_vif: + have_vif = {} + + for update in self._get_updates(want_vif, have_vif): + for key, value in iteritems(update): + commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'], vif=want_vif['vlan_id'])) + + 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 = [] + want_copy = deepcopy(remove_empties(want)) + have_copy = deepcopy(have) + + want_vifs = want_copy.pop('vifs', []) + have_vifs = have_copy.pop('vifs', []) + + for update in self._get_updates(have_copy, want_copy): + for key, value in iteritems(update): + commands.append(self._compute_commands(key=key, value=value, interface=want_copy['name'], remove=True)) + + if have_vifs: + for have_vif in have_vifs: + want_vif = search_obj_in_list(have_vif['vlan_id'], want_vifs, key='vlan_id') + if not want_vif: + want_vif = {'vlan_id': have_vif['vlan_id']} + + for update in self._get_updates(have_vif, want_vif): + for key, value in iteritems(update): + commands.append(self._compute_commands(key=key, interface=want_copy['name'], value=value, vif=want_vif['vlan_id'], remove=True)) + + return commands + + def _compute_commands(self, interface, key, vif=None, value=None, remove=False): + intf_context = 'interfaces {0} {1}'.format(get_interface_type(interface), interface) + set_cmd = 'set {0}'.format(intf_context) + del_cmd = 'delete {0}'.format(intf_context) + + if vif: + set_cmd = set_cmd + (' vif {0}'.format(vif)) + del_cmd = del_cmd + (' vif {0}'.format(vif)) + + if remove: + command = "{0} {1} '{2}'".format(del_cmd, key, value) + else: + command = "{0} {1} '{2}'".format(set_cmd, key, value) + + return command + + def _get_updates(self, want, have): + updates = [] + + updates = diff_list_of_dicts(want.get('ipv4', []), have.get('ipv4', [])) + updates.extend(diff_list_of_dicts(want.get('ipv6', []), have.get('ipv6', []))) + + return updates diff --git a/lib/ansible/module_utils/network/vyos/facts/facts.py b/lib/ansible/module_utils/network/vyos/facts/facts.py index 080b5cca90b..adfa0180cc1 100644 --- a/lib/ansible/module_utils/network/vyos/facts/facts.py +++ b/lib/ansible/module_utils/network/vyos/facts/facts.py @@ -14,6 +14,7 @@ __metaclass__ = type from ansible.module_utils.network.vyos.argspec.facts.facts import FactsArgs from ansible.module_utils.network.common.facts.facts import FactsBase from ansible.module_utils.network.vyos.facts.interfaces.interfaces import InterfacesFacts +from ansible.module_utils.network.vyos.facts.l3_interfaces.l3_interfaces import L3_interfacesFacts from ansible.module_utils.network.vyos.facts.legacy.base import Default, Neighbors, Config from ansible.module_utils. \ network.vyos.vyos import run_commands, get_capabilities @@ -26,6 +27,7 @@ FACT_LEGACY_SUBSETS = dict( ) FACT_RESOURCE_SUBSETS = dict( interfaces=InterfacesFacts, + l3_interfaces=L3_interfacesFacts ) diff --git a/lib/ansible/module_utils/network/vyos/facts/l3_interfaces/__init__.py b/lib/ansible/module_utils/network/vyos/facts/l3_interfaces/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/lib/ansible/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py b/lib/ansible/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py new file mode 100644 index 00000000000..7a33f814910 --- /dev/null +++ b/lib/ansible/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py @@ -0,0 +1,130 @@ +# +# -*- 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 vyos l3_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.six import iteritems +from ansible.module_utils.compat import ipaddress +from ansible.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import L3_interfacesArgs + + +class L3_interfacesFacts(object): + """ The vyos l3_interfaces fact class + """ + + def __init__(self, module, subspec='config', options='options'): + self._module = module + self.argument_spec = L3_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 l3_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() + + # operate on a collection of resource x + objs = [] + interface_names = re.findall(r'set interfaces (?:ethernet|bonding|vti|vxlan) (?:\'*)(\S+)(?:\'*)', data, re.M) + if interface_names: + for interface in set(interface_names): + intf_regex = r' %s .+$' % interface + cfg = re.findall(intf_regex, data, re.M) + obj = self.render_config(cfg) + obj['name'] = interface.strip("'") + if obj: + objs.append(obj) + + ansible_facts['ansible_network_resources'].pop('l3_interfaces', None) + facts = {} + if objs: + facts['l3_interfaces'] = [] + params = utils.validate_config(self.argument_spec, {'config': objs}) + for cfg in params['config']: + facts['l3_interfaces'].append(utils.remove_empties(cfg)) + + ansible_facts['ansible_network_resources'].update(facts) + return ansible_facts + + def render_config(self, 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 + """ + vif_conf = '\n'.join(filter(lambda x: ('vif' in x), conf)) + eth_conf = '\n'.join(filter(lambda x: ('vif' not in x), conf)) + config = self.parse_attribs(eth_conf) + config['vifs'] = self.parse_vifs(vif_conf) + + return utils.remove_empties(config) + + def parse_vifs(self, conf): + vif_names = re.findall(r'vif (\d+)', conf, re.M) + vifs_list = None + if vif_names: + vifs_list = [] + for vif in set(vif_names): + vif_regex = r' %s .+$' % vif + cfg = '\n'.join(re.findall(vif_regex, conf, re.M)) + obj = self.parse_attribs(cfg) + obj['vlan_id'] = vif + if obj: + vifs_list.append(obj) + + return vifs_list + + def parse_attribs(self, conf): + config = {} + ipaddrs = re.findall(r'address (\S+)', conf, re.M) + config['ipv4'] = [] + config['ipv6'] = [] + + for item in ipaddrs: + item = item.strip("'") + if item == 'dhcp': + config['ipv4'].append({'address': item}) + elif item == 'dhcpv6': + config['ipv6'].append({'address': item}) + else: + ip_version = ipaddress.ip_address(item.split("/")[0]).version + if ip_version == 4: + config['ipv4'].append({'address': item}) + else: + config['ipv6'].append({'address': item}) + + for key, value in iteritems(config): + if value == []: + config[key] = None + + return utils.remove_empties(config) diff --git a/lib/ansible/module_utils/network/vyos/utils/utils.py b/lib/ansible/module_utils/network/vyos/utils/utils.py index dbfe4227a07..f59c24ffe70 100644 --- a/lib/ansible/module_utils/network/vyos/utils/utils.py +++ b/lib/ansible/module_utils/network/vyos/utils/utils.py @@ -53,3 +53,16 @@ def dict_delete(base, comparable): to_delete[key] = base[key] return to_delete + + +def diff_list_of_dicts(want, have): + diff = [] + + set_w = set(tuple(d.items()) for d in want) + set_h = set(tuple(d.items()) for d in have) + difference = set_w.difference(set_h) + + for element in difference: + diff.append(dict((x, y) for x, y in element)) + + return diff diff --git a/lib/ansible/modules/network/vyos/vyos_l3_interface.py b/lib/ansible/modules/network/vyos/_vyos_l3_interface.py similarity index 98% rename from lib/ansible/modules/network/vyos/vyos_l3_interface.py rename to lib/ansible/modules/network/vyos/_vyos_l3_interface.py index 4d432e9267b..95b45103a80 100644 --- a/lib/ansible/modules/network/vyos/vyos_l3_interface.py +++ b/lib/ansible/modules/network/vyos/_vyos_l3_interface.py @@ -20,7 +20,7 @@ # ANSIBLE_METADATA = {'metadata_version': '1.1', - 'status': ['preview'], + 'status': ['deprecated'], 'supported_by': 'network'} @@ -33,6 +33,10 @@ short_description: Manage L3 interfaces on VyOS network devices description: - This module provides declarative management of L3 interfaces on VyOS network devices. +deprecated: + removed_in: '2.13' + alternative: vyos_l3_interfaces + why: Updated modules released with more functionality. notes: - Tested against VYOS 1.1.7 options: diff --git a/lib/ansible/modules/network/vyos/vyos_facts.py b/lib/ansible/modules/network/vyos/vyos_facts.py index ef2682bec35..23137204682 100644 --- a/lib/ansible/modules/network/vyos/vyos_facts.py +++ b/lib/ansible/modules/network/vyos/vyos_facts.py @@ -51,7 +51,7 @@ options: specific subset should not be collected. required: false version_added: "2.9" - choices: ['all', 'interfaces', '!interfaces'] + choices: ['all', 'interfaces', '!interfaces', 'l3_interfaces', '!l3_interfaces'] """ EXAMPLES = """ diff --git a/lib/ansible/modules/network/vyos/vyos_l3_interfaces.py b/lib/ansible/modules/network/vyos/vyos_l3_interfaces.py new file mode 100644 index 00000000000..d2f4c2ae135 --- /dev/null +++ b/lib/ansible/modules/network/vyos/vyos_l3_interfaces.py @@ -0,0 +1,372 @@ +#!/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 vyos_l3_interfaces +""" + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +ANSIBLE_METADATA = { + 'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'network' +} + +DOCUMENTATION = """ +--- +module: vyos_l3_interfaces +version_added: 2.9 +short_description: Manages L3 interface attributes of VyOS network devices. +description: This module manages the L3 interface attributes on VyOS network devices. +author: Nilashish Chakraborty (@NilashishC) +options: + config: + description: The provided L3 interfaces configuration. + type: list + elements: dict + suboptions: + name: + description: + - Full name of the interface, e.g. eth0, eth1. + type: str + required: True + ipv4: + description: + - List of IPv4 addresses of the interface. + type: list + elements: dict + suboptions: + address: + description: + - IPv4 address of the interface. + type: str + ipv6: + description: + - List of IPv6 addresses of the interface. + type: list + elements: dict + suboptions: + address: + description: + - IPv6 address of the interface. + type: str + vifs: + description: + - Virtual sub-interfaces L3 configurations. + elements: dict + type: list + suboptions: + vlan_id: + description: + - Identifier for the virtual sub-interface. + type: int + ipv4: + description: + - List of IPv4 addresses of the virtual interface. + type: list + elements: dict + suboptions: + address: + description: + - IPv4 address of the virtual interface. + type: str + ipv6: + description: + - List of IPv6 addresses of the virual interface. + type: list + elements: dict + suboptions: + address: + description: + - IPv6 address of the virtual interface. + 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: +# ------------- +# +# vyos:~$ show configuration commands | grep -e eth[2,3] +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 vif 101 +# set interfaces ethernet eth3 vif 102 + +- name: Merge provided configuration with device configuration + vyos_l3_interfaces: + config: + - name: eth2 + ipv4: + - address: 192.0.2.10/28 + - address: 198.51.100.40/27 + ipv6: + - address: 2001:db8:100::2/32 + - address: 2001:db8:400::10/32 + + - name: eth3 + ipv4: + - address: 203.0.113.65/26 + vifs: + - vlan_id: 101 + ipv4: + - address: 192.0.2.71/28 + - address: 198.51.100.131/25 + - vlan_id: 102 + ipv6: + - address: 2001:db8:1000::5/38 + - address: 2001:db8:1400::3/38 + state: merged + +# After state: +# ------------- +# +# vyos:~$ show configuration commands | grep -e eth[2,3] +# set interfaces ethernet eth2 address '192.0.2.10/28' +# set interfaces ethernet eth2 address '198.51.100.40/27' +# set interfaces ethernet eth2 address '2001:db8:100::2/32' +# set interfaces ethernet eth2 address '2001:db8:400::10/32' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 address '203.0.113.65/26' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 vif 101 address '192.0.2.71/28' +# set interfaces ethernet eth3 vif 101 address '198.51.100.131/25' +# set interfaces ethernet eth3 vif 102 address '2001:db8:1000::5/38' +# set interfaces ethernet eth3 vif 102 address '2001:db8:1400::3/38' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::2/34' + + +# Using replaced +# +# Before state: +# ------------- +# +# vyos:~$ show configuration commands | grep eth +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' +# set interfaces ethernet eth0 smp-affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:EA:0F:B9' +# set interfaces ethernet eth1 address '192.0.2.14/24' +# set interfaces ethernet eth2 address '192.0.2.10/24' +# set interfaces ethernet eth2 address '192.0.2.11/24' +# set interfaces ethernet eth2 address '2001:db8::10/32' +# set interfaces ethernet eth2 address '2001:db8::11/32' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 address '198.51.100.10/24' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 vif 101 address '198.51.100.130/25' +# set interfaces ethernet eth3 vif 101 address '198.51.100.131/25' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::3/34' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::2/34' +# +- name: Replace device configurations of listed interfaces with provided configurations + vyos_l3_interfaces: + config: + - name: eth2 + ipv4: + - address: 192.0.2.10/24 + + - name: eth3 + ipv6: + - address: 2001:db8::11/32 + state: replaced + +# After state: +# ------------- +# +# vyos:~$ show configuration commands | grep eth +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' +# set interfaces ethernet eth0 smp-affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:EA:0F:B9' +# set interfaces ethernet eth1 address '192.0.2.14/24' +# set interfaces ethernet eth2 address '192.0.2.10/24' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 address '2001:db8::11/32' +# set interfaces ethernet eth3 vif 101 +# set interfaces ethernet eth3 vif 102 + + +# Using overridden +# +# Before state +# -------------- +# +# vyos@vyos-appliance:~$ show configuration commands | grep eth +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' +# set interfaces ethernet eth0 smp-affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:EA:0F:B9' +# set interfaces ethernet eth1 address '192.0.2.14/24' +# set interfaces ethernet eth2 address '192.0.2.10/24' +# set interfaces ethernet eth2 address '192.0.2.11/24' +# set interfaces ethernet eth2 address '2001:db8::10/32' +# set interfaces ethernet eth2 address '2001:db8::11/32' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 address '198.51.100.10/24' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 vif 101 address '198.51.100.130/25' +# set interfaces ethernet eth3 vif 101 address '198.51.100.131/25' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::3/34' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::2/34' + +- name: Overrides all device configuration with provided configuration + vyos_l3_interfaces: + config: + - name: eth0 + ipv4: + - address: dhcp + ipv6: + - address: dhcpv6 + state: overridden + +# After state +# ------------ +# +# vyos@vyos-appliance:~$ show configuration commands | grep eth +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 address 'dhcpv6' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' +# set interfaces ethernet eth0 smp-affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:EA:0F:B9' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 vif 101 +# set interfaces ethernet eth3 vif 102 + + +# Using deleted +# +# Before state +# ------------- +# vyos@vyos-appliance:~$ show configuration commands | grep eth +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' +# set interfaces ethernet eth0 smp-affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:EA:0F:B9' +# set interfaces ethernet eth1 address '192.0.2.14/24' +# set interfaces ethernet eth2 address '192.0.2.10/24' +# set interfaces ethernet eth2 address '192.0.2.11/24' +# set interfaces ethernet eth2 address '2001:db8::10/32' +# set interfaces ethernet eth2 address '2001:db8::11/32' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth3 address '198.51.100.10/24' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 vif 101 address '198.51.100.130/25' +# set interfaces ethernet eth3 vif 101 address '198.51.100.131/25' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::3/34' +# set interfaces ethernet eth3 vif 102 address '2001:db8:4000::2/34' + +- name: Delete L3 attributes of given interfaces (Note - This won't delete the interface itself) + vyos_l3_interfaces: + config: + - name: eth1 + - name: eth2 + - name: eth3 + state: deleted + +# After state +# ------------ +# vyos@vyos-appliance:~$ show configuration commands | grep eth +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:f3:6c:b5' +# set interfaces ethernet eth0 smp_affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:ad:ef:65' +# set interfaces ethernet eth1 smp_affinity 'auto' +# set interfaces ethernet eth2 hw-id '08:00:27:ab:4e:79' +# set interfaces ethernet eth2 smp_affinity 'auto' +# set interfaces ethernet eth3 hw-id '08:00:27:17:3c:85' +# set interfaces ethernet eth3 smp_affinity 'auto' + + +""" +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: ['set interfaces ethernet eth1 192.0.2.14/2', 'set interfaces ethernet eth3 vif 101 address 198.51.100.130/25'] +""" + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import L3_interfacesArgs +from ansible.module_utils.network.vyos.config.l3_interfaces.l3_interfaces import L3_interfaces + + +def main(): + """ + Main entry point for module execution + + :returns: the result form module invocation + """ + module = AnsibleModule(argument_spec=L3_interfacesArgs.argument_spec, + supports_check_mode=True) + + result = L3_interfaces(module).execute_module() + module.exit_json(**result) + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/vyos_l3_interfaces/defaults/main.yaml b/test/integration/targets/vyos_l3_interfaces/defaults/main.yaml new file mode 100644 index 00000000000..164afead284 --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/defaults/main.yaml @@ -0,0 +1,3 @@ +--- +testcase: "[^_].*" +test_items: [] diff --git a/test/integration/targets/vyos_l3_interfaces/meta/main.yml b/test/integration/targets/vyos_l3_interfaces/meta/main.yml new file mode 100644 index 00000000000..e380a13e01a --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - prepare_vyos_tests \ No newline at end of file diff --git a/test/integration/targets/vyos_l3_interfaces/tasks/cli.yaml b/test/integration/targets/vyos_l3_interfaces/tasks/cli.yaml new file mode 100644 index 00000000000..337e34133b0 --- /dev/null +++ b/test/integration/targets/vyos_l3_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/vyos_l3_interfaces/tasks/main.yaml b/test/integration/targets/vyos_l3_interfaces/tasks/main.yaml new file mode 100644 index 00000000000..415c99d8b12 --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tasks/main.yaml @@ -0,0 +1,2 @@ +--- +- { include: cli.yaml, tags: ['cli'] } diff --git a/test/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml b/test/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml new file mode 100644 index 00000000000..248a9bb819c --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tests/cli/_populate.yaml @@ -0,0 +1,11 @@ +--- +- name: Setup + cli_config: + config: "{{ lines }}" + vars: + lines: | + set interfaces ethernet eth1 address '192.0.2.14/24' + set interfaces ethernet eth2 address '192.0.2.10/24' + set interfaces ethernet eth2 address '192.0.2.11/24' + set interfaces ethernet eth2 address '2001:db8::10/32' + set interfaces ethernet eth2 address '2001:db8::12/32' \ No newline at end of file diff --git a/test/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml b/test/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml new file mode 100644 index 00000000000..31af5ba961c --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tests/cli/_remove_config.yaml @@ -0,0 +1,13 @@ +--- +- name: Remove Config + cli_config: + config: "{{ lines }}" + vars: + lines: | + delete interfaces ethernet "{{ intf }}" address + delete interfaces ethernet "{{ intf }}" vif + loop: + - eth1 + - eth2 + loop_control: + loop_var: intf diff --git a/test/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml b/test/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml new file mode 100644 index 00000000000..84e0d9cca8a --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tests/cli/deleted.yaml @@ -0,0 +1,48 @@ +--- +- debug: + msg: "Start vyos_interfaces deleted integration tests ansible_connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- block: + - include_tasks: _populate.yaml + + - name: Delete attributes of given interfaces + vyos_l3_interfaces: &deleted + config: + - name: eth1 + - name: eth2 + 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 attributes of given interfaces (IDEMPOTENT) + vyos_l3_interfaces: *deleted + register: result + + - name: Assert that the previous task was idempotent + assert: + that: + - "result.changed == false" + + - 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/vyos_l3_interfaces/tests/cli/merged.yaml b/test/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml new file mode 100644 index 00000000000..c9954aed546 --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tests/cli/merged.yaml @@ -0,0 +1,58 @@ +--- +- debug: + msg: "START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- block: + - name: Merge the provided configuration with the exisiting running configuration + vyos_l3_interfaces: &merged + config: + - name: eth1 + ipv4: + - address: 192.0.2.10/24 + ipv6: + - address: 2001:db8::10/32 + + - name: eth2 + ipv4: + - address: 198.51.100.10/24 + vifs: + - vlan_id: 101 + ipv4: + - address: 198.51.100.130/25 + ipv6: + - address: 2001:db8::20/32 + 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) + vyos_l3_interfaces: *merged + register: result + + - name: Assert that the previous task was idempotent + assert: + that: + - "result['changed'] == false" + + - 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/vyos_l3_interfaces/tests/cli/overridden.yaml b/test/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml new file mode 100644 index 00000000000..232bcb3f528 --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml @@ -0,0 +1,52 @@ +--- +- debug: + msg: "START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- block: + - include_tasks: _populate.yaml + + - name: Overrides all device configuration with provided configuration + vyos_l3_interfaces: &overridden + config: + - name: eth0 + ipv4: + - address: dhcp + - name: eth1 + ipv4: + - address: "192.0.2.15/24" + state: overridden + register: result + + - name: Assert that before dicts were correctly generated + assert: + that: + - "{{ populate | symmetric_difference(result['before']) |length == 0 }}" + + - name: Assert that correct commands were generated + assert: + that: + - "{{ overridden['commands'] | symmetric_difference(result['commands']) |length == 0 }}" + + - name: Assert that after dicts were correctly generated + assert: + that: + - "{{ overridden['after'] | symmetric_difference(result['after']) |length == 0 }}" + + - name: Overrides all device configuration with provided configurations (IDEMPOTENT) + vyos_l3_interfaces: *overridden + register: result + + - name: Assert that the previous task was idempotent + assert: + that: + - "result['changed'] == false" + + - name: Assert that before dicts were correctly generated + assert: + that: + - "{{ overridden['after'] | symmetric_difference(result['before']) |length == 0 }}" + + always: + - include_tasks: _remove_config.yaml diff --git a/test/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml b/test/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml new file mode 100644 index 00000000000..818a83b6f14 --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/tests/cli/replaced.yaml @@ -0,0 +1,52 @@ +--- +- debug: + msg: "START vyos_l3_interfaces replaced integration tests on connection={{ ansible_connection }}" + +- include_tasks: _remove_config.yaml + +- block: + - include_tasks: _populate.yaml + + - name: Replace device configurations of listed interfaces with provided configurations + vyos_l3_interfaces: &replaced + config: + - name: eth1 + ipv4: + - address: 192.0.2.19/24 + - name: eth2 + ipv6: + - address: 2001:db8::11/32 + 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) + vyos_l3_interfaces: *replaced + register: result + + - name: Assert that task was idempotent + assert: + that: + - "result['changed'] == false" + + - 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/vyos_l3_interfaces/vars/main.yaml b/test/integration/targets/vyos_l3_interfaces/vars/main.yaml new file mode 100644 index 00000000000..f908d2c8256 --- /dev/null +++ b/test/integration/targets/vyos_l3_interfaces/vars/main.yaml @@ -0,0 +1,114 @@ +--- +merged: + before: + - name: "eth0" + ipv4: + - address: "dhcp" + + - name: "eth1" + + - name: "eth2" + + commands: + - "set interfaces ethernet eth1 address '192.0.2.10/24'" + - "set interfaces ethernet eth1 address '2001:db8::10/32'" + - "set interfaces ethernet eth2 address '198.51.100.10/24'" + - "set interfaces ethernet eth2 vif 101 address '198.51.100.130/25'" + - "set interfaces ethernet eth2 vif 101 address '2001:db8::20/32'" + + after: + - name: "eth0" + ipv4: + - address: "dhcp" + + - name: "eth1" + ipv4: + - address: "192.0.2.10/24" + ipv6: + - address: "2001:db8::10/32" + + - name: "eth2" + ipv4: + - address: "198.51.100.10/24" + vifs: + - vlan_id: 101 + ipv4: + - address: "198.51.100.130/25" + ipv6: + - address: "2001:db8::20/32" + +populate: + - name: "eth1" + ipv4: + - address: "192.0.2.14/24" + + - name: "eth2" + ipv4: + - address: "192.0.2.10/24" + - address: "192.0.2.11/24" + ipv6: + - address: "2001:db8::10/32" + - address: "2001:db8::12/32" + + - name: "eth0" + ipv4: + - address: "dhcp" + +replaced: + commands: + - "delete interfaces ethernet eth2 address '192.0.2.10/24'" + - "delete interfaces ethernet eth2 address '192.0.2.11/24'" + - "delete interfaces ethernet eth2 address '2001:db8::10/32'" + - "delete interfaces ethernet eth2 address '2001:db8::12/32'" + - "set interfaces ethernet eth2 address '2001:db8::11/32'" + - "delete interfaces ethernet eth1 address '192.0.2.14/24'" + - "set interfaces ethernet eth1 address '192.0.2.19/24'" + + after: + - name: "eth2" + ipv6: + - address: "2001:db8::11/32" + + - name: "eth1" + ipv4: + - address: "192.0.2.19/24" + + - name: "eth0" + ipv4: + - address: "dhcp" + +overridden: + commands: + - delete interfaces ethernet eth1 address '192.0.2.14/24' + - set interfaces ethernet eth1 address '192.0.2.15/24' + - delete interfaces ethernet eth2 address '192.0.2.10/24' + - delete interfaces ethernet eth2 address '192.0.2.11/24' + - delete interfaces ethernet eth2 address '2001:db8::10/32' + - delete interfaces ethernet eth2 address '2001:db8::12/32' + + after: + - name: "eth0" + ipv4: + - address: "dhcp" + + - name: "eth1" + ipv4: + - address: "192.0.2.15/24" + + - name: "eth2" + +deleted: + commands: + - delete interfaces ethernet eth1 address '192.0.2.14/24' + - delete interfaces ethernet eth2 address '192.0.2.10/24' + - delete interfaces ethernet eth2 address '192.0.2.11/24' + - delete interfaces ethernet eth2 address '2001:db8::10/32' + - delete interfaces ethernet eth2 address '2001:db8::12/32' + after: + - name: "eth0" + ipv4: + - address: "dhcp" + + - name: "eth1" + + - name: "eth2" diff --git a/test/sanity/ignore.txt b/test/sanity/ignore.txt index 21b07da35bc..aa7d6fc569b 100644 --- a/test/sanity/ignore.txt +++ b/test/sanity/ignore.txt @@ -5742,14 +5742,14 @@ lib/ansible/modules/network/vyos/_vyos_interface.py validate-modules:E326 lib/ansible/modules/network/vyos/_vyos_interface.py validate-modules:E337 lib/ansible/modules/network/vyos/_vyos_interface.py validate-modules:E338 lib/ansible/modules/network/vyos/_vyos_interface.py validate-modules:E340 -lib/ansible/modules/network/vyos/vyos_l3_interface.py future-import-boilerplate -lib/ansible/modules/network/vyos/vyos_l3_interface.py metaclass-boilerplate -lib/ansible/modules/network/vyos/vyos_l3_interface.py validate-modules:E322 -lib/ansible/modules/network/vyos/vyos_l3_interface.py validate-modules:E324 -lib/ansible/modules/network/vyos/vyos_l3_interface.py validate-modules:E326 -lib/ansible/modules/network/vyos/vyos_l3_interface.py validate-modules:E337 -lib/ansible/modules/network/vyos/vyos_l3_interface.py validate-modules:E338 -lib/ansible/modules/network/vyos/vyos_l3_interface.py validate-modules:E340 +lib/ansible/modules/network/vyos/_vyos_l3_interface.py future-import-boilerplate +lib/ansible/modules/network/vyos/_vyos_l3_interface.py metaclass-boilerplate +lib/ansible/modules/network/vyos/_vyos_l3_interface.py validate-modules:E322 +lib/ansible/modules/network/vyos/_vyos_l3_interface.py validate-modules:E324 +lib/ansible/modules/network/vyos/_vyos_l3_interface.py validate-modules:E326 +lib/ansible/modules/network/vyos/_vyos_l3_interface.py validate-modules:E337 +lib/ansible/modules/network/vyos/_vyos_l3_interface.py validate-modules:E338 +lib/ansible/modules/network/vyos/_vyos_l3_interface.py validate-modules:E340 lib/ansible/modules/network/vyos/vyos_linkagg.py future-import-boilerplate lib/ansible/modules/network/vyos/vyos_linkagg.py metaclass-boilerplate lib/ansible/modules/network/vyos/vyos_linkagg.py validate-modules:E322