diff --git a/changelogs/fragments/T8512-isort-fix.yml b/changelogs/fragments/T8512-isort-fix.yml new file mode 100644 index 00000000..5209017c --- /dev/null +++ b/changelogs/fragments/T8512-isort-fix.yml @@ -0,0 +1,3 @@ +--- +trivial: + - Fix isort import ordering violations across module_utils to satisfy pre-commit checks. diff --git a/plugins/module_utils/network/vyos/facts/bgp_address_family/bgp_address_family.py b/plugins/module_utils/network/vyos/facts/bgp_address_family/bgp_address_family.py index 3386bd66..31839c5d 100644 --- a/plugins/module_utils/network/vyos/facts/bgp_address_family/bgp_address_family.py +++ b/plugins/module_utils/network/vyos/facts/bgp_address_family/bgp_address_family.py @@ -1,99 +1,99 @@ # -*- coding: utf-8 -*- # Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type """ The vyos bgp_address_family 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. """ import re from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.bgp_address_family.bgp_address_family import ( Bgp_address_familyArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.bgp_address_family import ( Bgp_address_familyTemplate, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.bgp_address_family_14 import ( Bgp_address_familyTemplate14, ) - +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import ( + LooseVersion, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import LooseVersion - class Bgp_address_familyFacts(object): """The vyos bgp_address_family facts class""" def __init__(self, module, subspec="config", options="options"): self._module = module self.argument_spec = Bgp_address_familyArgs.argument_spec def get_device_data(self, connection): return connection.get('show configuration commands | match "set protocols bgp"') def populate_facts(self, connection, ansible_facts, data=None): """Populate the facts for Bgp_address_family network resource :param connection: the device connection :param ansible_facts: Facts dictionary :param data: previously collected conf :rtype: dictionary :returns: facts """ facts = {} objs = [] config_lines = [] if not data: data = self.get_device_data(connection) for resource in data.splitlines(): if "address-family" in resource or "system-as" in resource: config_lines.append(re.sub("'", "", resource)) # parse native config using the Bgp_address_family template based on version if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"): bgp_address_family_parser = Bgp_address_familyTemplate14(lines=config_lines) else: bgp_address_family_parser = Bgp_address_familyTemplate(lines=config_lines) objs = bgp_address_family_parser.parse() if objs: if "address_family" in objs: objs["address_family"] = list(objs["address_family"].values()) for af in objs["address_family"]: if "networks" in af: af["networks"] = sorted(af["networks"], key=lambda k: k["prefix"]) if "aggregate_address" in af: af["aggregate_address"] = sorted( af["aggregate_address"], key=lambda k: k["prefix"], ) if "neighbors" in objs: objs["neighbors"] = list(objs["neighbors"].values()) objs["neighbors"] = sorted(objs["neighbors"], key=lambda k: k["neighbor_address"]) for neigh in objs["neighbors"]: if "address_family" in neigh: neigh["address_family"] = list(neigh["address_family"].values()) ansible_facts["ansible_network_resources"].pop("bgp_address_family", None) params = utils.remove_empties(utils.validate_config(self.argument_spec, {"config": objs})) facts["bgp_address_family"] = params.get("config", []) ansible_facts["ansible_network_resources"].update(facts) return ansible_facts diff --git a/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py b/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py index dd793681..2883cc2d 100644 --- a/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py +++ b/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py @@ -1,93 +1,92 @@ # -*- coding: utf-8 -*- # Copyright 2021 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type """ The vyos bgp_global 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. """ import re from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.bgp_global.bgp_global import ( Bgp_globalArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.bgp_global import ( Bgp_globalTemplate, ) - from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.bgp_global_14 import ( Bgp_globalTemplate14, ) - +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import ( + LooseVersion, +) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.vyos import get_os_version -from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.version import LooseVersion - class Bgp_globalFacts(object): """The vyos bgp_global facts class""" def __init__(self, module, subspec="config", options="options"): self._module = module self.argument_spec = Bgp_globalArgs.argument_spec def get_device_data(self, connection): return connection.get('show configuration commands | match "set protocols bgp"') def populate_facts(self, connection, ansible_facts, data=None): """Populate the facts for Bgp_global network resource :param connection: the device connection :param ansible_facts: Facts dictionary :param data: previously collected conf :rtype: dictionary :returns: facts """ facts = {} objs = {} config_lines = [] if not data: data = self.get_device_data(connection) for resource in data.splitlines(): if "address-family" not in resource: config_lines.append(re.sub("'", "", resource)) if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"): bgp_global_parser = Bgp_globalTemplate14(lines=config_lines, module=self._module) else: bgp_global_parser = Bgp_globalTemplate(lines=config_lines, module=self._module) objs = bgp_global_parser.parse() if "neighbor" in objs: objs["neighbor"] = list(objs["neighbor"].values()) objs["neighbor"] = sorted(objs["neighbor"], key=lambda k: k["address"]) if "network" in objs: objs["network"] = sorted(objs["network"], key=lambda k: k["address"]) if "aggregate_address" in objs: objs["aggregate_address"] = sorted(objs["aggregate_address"], key=lambda k: k["prefix"]) ansible_facts["ansible_network_resources"].pop("bgp_global", None) params = utils.remove_empties( bgp_global_parser.validate_config(self.argument_spec, {"config": objs}, redact=True), ) facts["bgp_global"] = params.get("config", []) ansible_facts["ansible_network_resources"].update(facts) return ansible_facts diff --git a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces_14.py b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces_14.py index 43fae1e9..0d3aa5a7 100644 --- a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces_14.py +++ b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces_14.py @@ -1,650 +1,651 @@ # -*- coding: utf-8 -*- # Copyright 2020 Red Hat # GNU General Public License v3.0+ # (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function + __metaclass__ = type """ The Ospf_interfaces parser templates file. This contains a list of parser definitions and associated functions that facilitates both facts gathering and native command generation for the given network resource. """ import re from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) def _get_parameters(data): if data["afi"] == "ipv6": val = ["ospfv3", "ipv6"] else: val = ["ospf", "ip"] return val def _tmplt_ospf_int_delete(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) ) return command def _tmplt_ospf_int_cost(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " cost {cost}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_auth_password(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " authentication plaintext-password {plaintext_password}".format( **config_data["address_family"]["authentication"] ) ) return command def _tmplt_ospf_int_auth_md5(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " authentication md5 key-id {key_id} ".format( **config_data["address_family"]["authentication"]["md5_key"] ) + "md5-key {key}".format(**config_data["address_family"]["authentication"]["md5_key"]) ) return command def _tmplt_ospf_int_auth_md5_delete(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " authentication" ) return command def _tmplt_ospf_int_bw(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " bandwidth {bandwidth}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_hello_interval(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " hello-interval {hello_interval}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_dead_interval(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " dead-interval {dead_interval}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_mtu_ignore(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " mtu-ignore" ) return command def _tmplt_ospf_int_network(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " network {network}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_priority(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " priority {priority}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_retransmit_interval(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " retransmit-interval {retransmit_interval}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_transmit_delay(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " transmit-delay {transmit_delay}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_ifmtu(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " ifmtu {ifmtu}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_instance(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " instance-id {instance}".format(**config_data["address_family"]) ) return command def _tmplt_ospf_int_passive(config_data): params = _get_parameters(config_data["address_family"]) command = ( "protocols " + params[0] + " interface {name}".format(**config_data) + " passive" ) return command class Ospf_interfacesTemplate14(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} super(Ospf_interfacesTemplate14, self).__init__( lines=lines, tmplt=self, prefix=prefix, module=module ) # fmt: off PARSERS = [ { "name": "ip_ospf", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) *$""", re.VERBOSE, ), "remval": _tmplt_ospf_int_delete, "compval": "address_family", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', } } } }, { "name": "authentication_password", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+authentication \s+plaintext-password \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_auth_password, "compval": "address_family.authentication", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "authentication": { "plaintext_password": "{{ text }}" } } } } }, { "name": "authentication_md5", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+authentication \s+md5 \s+key-id \s+(?P\d+) \s+md5-key \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_auth_md5, "remval": _tmplt_ospf_int_auth_md5_delete, "compval": "address_family.authentication", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "authentication": { "md5_key": { "key_id": "{{ id }}", "key": "{{ text }}" } } } } } }, { "name": "bandwidth", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+bandwidth \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_bw, "compval": "address_family.bandwidth", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "bandwidth": "{{ bw }}" } } } }, { "name": "cost", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+cost \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_cost, "compval": "address_family.cost", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "cost": "{{ val }}" } } } }, { "name": "hello_interval", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+hello-interval \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_hello_interval, "compval": "address_family.hello_interval", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "hello_interval": "{{ val }}" } } } }, { "name": "dead_interval", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+dead-interval \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_dead_interval, "compval": "address_family.dead_interval", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "dead_interval": "{{ val }}" } } } }, { "name": "mtu_ignore", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+(?Pmtu-ignore) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_mtu_ignore, "compval": "address_family.mtu_ignore", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "mtu_ignore": "{{ True if mtu is defined }}" } } } }, { "name": "network", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+network \s+(?P\S+) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_network, "compval": "address_family.network", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "network": "{{ val }}" } } } }, { "name": "priority", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+priority \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_priority, "compval": "address_family.priority", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "priority": "{{ val }}" } } } }, { "name": "retransmit_interval", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+retransmit-interval \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_retransmit_interval, "compval": "address_family.retransmit_interval", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "retransmit_interval": "{{ val }}" } } } }, { "name": "transmit_delay", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+transmit-delay \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_transmit_delay, "compval": "address_family.transmit_delay", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "transmit_delay": "{{ val }}" } } } }, { "name": "ifmtu", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+ifmtu \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_ifmtu, "compval": "address_family.ifmtu", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "ifmtu": "{{ val }}" } } } }, { "name": "instance", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+instance-id \s+(?P\'\d+\') *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_instance, "compval": "address_family.instance", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "instance": "{{ val }}" } } } }, { "name": "passive", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) \s+(?Ppassive) *$""", re.VERBOSE, ), "setval": _tmplt_ospf_int_passive, "compval": "address_family.passive", "result": { "name": "{{ name }}", "address_family": { '{{ "ipv4" if proto == "ospf" else "ipv6" }}': { "afi": '{{ "ipv4" if proto == "ospf" else "ipv6" }}', "passive": "{{ True if pass is defined }}" } } } }, { "name": "interface_name", "getval": re.compile( r""" ^set \s+protocols \s+(?Pospf|ospfv3) \s+interface \s+(?P\S+) .*$""", re.VERBOSE, ), "setval": "set protocols {{ proto }} interface {{ name }}", "result": { "name": "{{ name }}", } }, ] # fmt: on diff --git a/plugins/module_utils/network/vyos/utils/version.py b/plugins/module_utils/network/vyos/utils/version.py index cc3028c3..6d84ef1c 100644 --- a/plugins/module_utils/network/vyos/utils/version.py +++ b/plugins/module_utils/network/vyos/utils/version.py @@ -1,13 +1,15 @@ # -*- coding: utf-8 -*- # Copyright (c) 2021, Felix Fontein # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt) # SPDX-License-Identifier: GPL-3.0-or-later """Provide version object to compare version numbers.""" from __future__ import absolute_import, division, print_function + + __metaclass__ = type from ansible.module_utils.compat.version import LooseVersion # pylint: disable=unused-import