summaryrefslogtreecommitdiff
path: root/plugins/module_utils/network
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/module_utils/network')
-rw-r--r--plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py2
-rw-r--r--plugins/module_utils/network/vyos/argspec/route_maps/route_maps.py20
-rw-r--r--plugins/module_utils/network/vyos/argspec/vrf/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/vrf/vrf.py131
-rw-r--r--plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py62
-rw-r--r--plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py23
-rw-r--r--plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py121
-rw-r--r--plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py27
-rw-r--r--plugins/module_utils/network/vyos/config/interfaces/interfaces.py5
-rw-r--r--plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py106
-rw-r--r--plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py4
-rw-r--r--plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py4
-rw-r--r--plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py5
-rw-r--r--plugins/module_utils/network/vyos/config/logging_global/logging_global.py19
-rw-r--r--plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py27
-rw-r--r--plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py36
-rw-r--r--plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py57
-rw-r--r--plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py9
-rw-r--r--plugins/module_utils/network/vyos/config/prefix_lists/prefix_lists.py17
-rw-r--r--plugins/module_utils/network/vyos/config/route_maps/route_maps.py40
-rw-r--r--plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py31
-rw-r--r--plugins/module_utils/network/vyos/config/static_routes/static_routes.py11
-rw-r--r--plugins/module_utils/network/vyos/config/vrf/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/config/vrf/vrf.py308
-rw-r--r--plugins/module_utils/network/vyos/facts/bgp_address_family/bgp_address_family.py6
-rw-r--r--plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py7
-rw-r--r--plugins/module_utils/network/vyos/facts/facts.py2
-rw-r--r--plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py4
-rw-r--r--plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py57
-rw-r--r--plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py3
-rw-r--r--plugins/module_utils/network/vyos/facts/logging_global/logging_global.py3
-rw-r--r--plugins/module_utils/network/vyos/facts/route_maps/route_maps.py16
-rw-r--r--plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py3
-rw-r--r--plugins/module_utils/network/vyos/facts/static_routes/static_routes.py7
-rw-r--r--plugins/module_utils/network/vyos/facts/vrf/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/facts/vrf/vrf.py227
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py49
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/bgp_address_family_14.py49
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/bgp_global.py102
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/bgp_global_14.py107
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py9
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/ospf_interfaces_14.py13
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/route_maps.py255
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/route_maps_14.py1364
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/snmp_server.py78
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/vrf.py249
-rw-r--r--plugins/module_utils/network/vyos/utils/utils.py27
-rw-r--r--plugins/module_utils/network/vyos/utils/version.py2
-rw-r--r--plugins/module_utils/network/vyos/vyos.py16
49 files changed, 3075 insertions, 645 deletions
diff --git a/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py b/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py
index 6ae17585..d1cf4fe8 100644
--- a/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py
+++ b/plugins/module_utils/network/vyos/argspec/firewall_rules/firewall_rules.py
@@ -83,6 +83,7 @@ class Firewall_rulesArgs(object): # pylint: disable=R0903
"continue",
"return",
"jump",
+ "offload",
"queue",
"synproxy",
],
@@ -210,6 +211,7 @@ class Firewall_rulesArgs(object): # pylint: disable=R0903
"required": True,
"type": "int",
},
+ "offload_target": {"type": "str"},
"outbound_interface": {
"options": {
"group": {"type": "str"},
diff --git a/plugins/module_utils/network/vyos/argspec/route_maps/route_maps.py b/plugins/module_utils/network/vyos/argspec/route_maps/route_maps.py
index 196db0c7..5b6d404d 100644
--- a/plugins/module_utils/network/vyos/argspec/route_maps/route_maps.py
+++ b/plugins/module_utils/network/vyos/argspec/route_maps/route_maps.py
@@ -74,6 +74,8 @@ class Route_mapsArgs(object): # pylint: disable=R0903
},
"extcommunity_rt": {"type": "str"},
"extcommunity_soo": {"type": "str"},
+ "extcommunity_bandwidth": {"type": "str"},
+ "extcommunity_bandwidth_non_transitive": {"type": "bool"},
"ip_next_hop": {"type": "str"},
"ipv6_next_hop": {
"type": "dict",
@@ -100,6 +102,7 @@ class Route_mapsArgs(object): # pylint: disable=R0903
"src": {"type": "str"},
"tag": {"type": "str"},
"weight": {"type": "str"},
+ "table": {"type": "str"},
},
},
"match": {
@@ -178,6 +181,23 @@ class Route_mapsArgs(object): # pylint: disable=R0903
"next_hop": {"type": "str"},
},
},
+ "protocol": {
+ "type": "str",
+ "choices": [
+ "babel",
+ "bgp",
+ "connected",
+ "isis",
+ "kernel",
+ "ospf",
+ "ospfv3",
+ "rip",
+ "ripng",
+ "static",
+ "table",
+ "vnc",
+ ],
+ },
"large_community_large_community_list": {
"type": "str",
},
diff --git a/plugins/module_utils/network/vyos/argspec/vrf/__init__.py b/plugins/module_utils/network/vyos/argspec/vrf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/vrf/__init__.py
diff --git a/plugins/module_utils/network/vyos/argspec/vrf/vrf.py b/plugins/module_utils/network/vyos/argspec/vrf/vrf.py
new file mode 100644
index 00000000..e24fd537
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/vrf/vrf.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+# Copyright 2024 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
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the
+# cli_rm_builder.
+#
+# Manually editing this file is not advised.
+#
+# To update the argspec make the desired changes
+# in the module docstring and re-run
+# cli_rm_builder.
+#
+#############################################
+
+"""
+The arg spec for the vyos_vrf module
+"""
+
+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.argspec.ospfv2.ospfv2 import (
+ Ospfv2Args,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.ospfv3.ospfv3 import (
+ Ospfv3Args,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.static_routes.static_routes import (
+ Static_routesArgs,
+)
+
+
+class VrfArgs(object): # pylint: disable=R0903
+ """The arg spec for the vyos_vrf module"""
+
+ bgp_argument_spec = Bgp_globalArgs.argument_spec["config"]
+ static_routes_argument_spec = Static_routesArgs.argument_spec["config"]
+ ospfv2_argument_spec = Ospfv2Args.argument_spec["config"]
+ ospfv3_argument_spec = Ospfv3Args.argument_spec["config"]
+
+ argument_spec = {
+ "config": {
+ "type": "dict",
+ "options": {
+ "bind_to_all": {"type": "bool", "default": False},
+ "instances": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "name": {"required": True, "type": "str"},
+ "description": {"type": "str"},
+ "disable": {
+ "aliases": ["disabled"],
+ "default": False,
+ "type": "bool",
+ },
+ "table_id": {"type": "int"},
+ "vni": {"type": "int"},
+ "address_family": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "afi": {
+ "type": "str",
+ "choices": ["ipv4", "ipv6"],
+ },
+ "disable_forwarding": {"type": "bool", "default": False},
+ "nht_no_resolve_via_default": {"type": "bool", "default": False},
+ "route_maps": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "rm_name": {"type": "str", "required": True},
+ "protocol": {
+ "type": "str",
+ "choices": [
+ "any",
+ "babel",
+ "bgp",
+ "eigrp",
+ "isis",
+ "ospf",
+ "rip",
+ "static",
+ ],
+ },
+ },
+ },
+ },
+ },
+ "protocols": {
+ # "type": "list", # sanity
+ # "elements": "dict",
+ "type": "dict",
+ "options": {
+ "bgp": bgp_argument_spec,
+ "ospf": ospfv2_argument_spec,
+ "ospfv3": ospfv3_argument_spec,
+ "static": static_routes_argument_spec,
+ },
+ },
+ },
+ },
+ },
+ },
+ "state": {
+ "type": "str",
+ "choices": [
+ "deleted",
+ "merged",
+ "replaced",
+ "overridden",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ "running_config": {"type": "str"},
+ } # pylint: disable=C0301
diff --git a/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py b/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py
index 0e6bec81..2d6481c2 100644
--- a/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py
+++ b/plugins/module_utils/network/vyos/config/bgp_address_family/bgp_address_family.py
@@ -20,7 +20,6 @@ created.
import re
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -32,15 +31,14 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts
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_family(ResourceModule):
"""
@@ -65,7 +63,7 @@ class Bgp_address_family(ResourceModule):
self._tmplt = Bgp_address_familyTemplate()
def parse(self):
- """ override parse to check template """
+ """override parse to check template"""
self._validate_template()
return super().parse()
@@ -93,9 +91,11 @@ class Bgp_address_family(ResourceModule):
wantd = {}
haved = {}
- if (self.want.get("as_number") == self.have.get("as_number") or
- not self.have or
- LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")):
+ if (
+ self.want.get("as_number") == self.have.get("as_number")
+ or not self.have
+ or LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")
+ ):
if self.want:
wantd = {self.want["as_number"]: self.want}
if self.have:
@@ -113,16 +113,16 @@ class Bgp_address_family(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
- for k, have in iteritems(haved):
+ for k, have in haved.items():
self._delete_af(wantd, have)
wantd = {}
if self.state == "overridden":
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
self._compare(want={}, have=have)
- for k, want in iteritems(wantd):
+ for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}))
def _compare(self, want, have):
@@ -149,23 +149,23 @@ class Bgp_address_family(ResourceModule):
def _compare_af(self, want, have):
waf = want.get("address_family", {})
haf = have.get("address_family", {})
- for name, entry in iteritems(waf):
+ for name, entry in waf.items():
self._compare_lists(
entry,
have=haf.get(name, {}),
as_number=want["as_number"],
afi=name,
)
- for name, entry in iteritems(haf):
+ for name, entry in haf.items():
if name not in waf.keys() and self.state == "replaced":
continue
self._compare_lists({}, entry, as_number=have["as_number"], afi=name)
def _delete_af(self, want, have):
- for as_num, entry in iteritems(want):
- for afi, af_entry in iteritems(entry.get("address_family", {})):
+ for as_num, entry in want.items():
+ for afi, af_entry in entry.get("address_family", {}).items():
if have.get("address_family"):
- for hafi, hentry in iteritems(have["address_family"]):
+ for hafi, hentry in have["address_family"].items():
if hafi == afi:
self.commands.append(
self._tmplt.render(
@@ -177,9 +177,9 @@ class Bgp_address_family(ResourceModule):
True,
),
)
- for neigh, neigh_entry in iteritems(entry.get("neighbors", {})):
+ for neigh, neigh_entry in entry.get("neighbors", {}).items():
if have.get("neighbors"):
- for hneigh, hnentry in iteritems(have["neighbors"]):
+ for hneigh, hnentry in have["neighbors"].items():
if hneigh == neigh:
if not neigh_entry.get("address_family"):
self.commands.append(
@@ -239,9 +239,9 @@ class Bgp_address_family(ResourceModule):
]
wneigh = want.get("neighbors", {})
hneigh = have.get("neighbors", {})
- for name, entry in iteritems(wneigh):
- for afi, af_entry in iteritems(entry.get("address_family")):
- for k, val in iteritems(af_entry):
+ for name, entry in wneigh.items():
+ for afi, af_entry in entry.get("address_family").items():
+ for k, val in af_entry.items():
w = {
"as_number": want["as_number"],
"neighbors": {
@@ -268,7 +268,7 @@ class Bgp_address_family(ResourceModule):
want=w,
have=h,
)
- for name, entry in iteritems(hneigh):
+ for name, entry in hneigh.items():
if name not in wneigh.keys():
# remove surplus config for overridden and replaced
if self.state != "replaced":
@@ -284,9 +284,9 @@ class Bgp_address_family(ResourceModule):
)
continue
- for hafi, haf_entry in iteritems(entry.get("address_family")):
+ for hafi, haf_entry in entry.get("address_family").items():
# remove surplus configs for given neighbor - replace and overridden
- for k, val in iteritems(haf_entry):
+ for k, val in haf_entry.items():
h = {
"as_number": have["as_number"],
"neighbors": {
@@ -317,7 +317,7 @@ class Bgp_address_family(ResourceModule):
for attrib in ["redistribute", "networks", "aggregate_address"]:
wdict = want.pop(attrib, {})
hdict = have.pop(attrib, {})
- for key, entry in iteritems(wdict):
+ for key, entry in wdict.items():
if entry != hdict.get(key, {}):
self.compare(
parsers=parsers,
@@ -348,7 +348,7 @@ class Bgp_address_family(ResourceModule):
+ attrib,
)
hdict = {}
- for key, entry in iteritems(hdict):
+ for key, entry in hdict.items():
self.compare(
parsers=parsers,
want={},
@@ -358,7 +358,7 @@ class Bgp_address_family(ResourceModule):
},
)
# de-duplicate child commands if parent command is present
- for val in (self.commands):
+ for val in self.commands:
for val2 in self.commands:
if val != val2 and val2.startswith(val):
self.commands.remove(val2)
@@ -366,13 +366,11 @@ class Bgp_address_family(ResourceModule):
def _compare_asn(self, want, have):
if want.get("as_number") and not have.get("as_number"):
self.commands.append(
- "set protocols bgp "
- + "system-as "
- + str(want.get("as_number")),
+ "set protocols bgp " + "system-as " + str(want.get("as_number")),
)
def _bgp_af_list_to_dict(self, entry):
- for name, proc in iteritems(entry):
+ for name, proc in entry.items():
if "address_family" in proc:
af_dict = {}
for entry in proc.get("address_family"):
diff --git a/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py b/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py
index 91a5af12..075c8fd2 100644
--- a/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py
+++ b/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py
@@ -18,7 +18,6 @@ necessary to bring the current configuration to its desired end-state is
created.
"""
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -118,10 +117,10 @@ class Bgp_global(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "purged":
h_del = {}
- for k, v in iteritems(haved):
+ for k, v in haved.items():
if k in wantd or not wantd:
h_del.update({k: v})
- for num, entry in iteritems(h_del):
+ for num, entry in h_del.items():
self.commands.append(self._tmplt.render({"as_number": num}, "router", True))
wantd = {}
@@ -129,7 +128,7 @@ class Bgp_global(ResourceModule):
self._compare(want={}, have=self.have)
wantd = {}
- for k, want in iteritems(wantd):
+ for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}))
def _compare(self, want, have):
@@ -144,7 +143,7 @@ class Bgp_global(ResourceModule):
parsers = ["maximum_paths", "timers"]
self._compare_neighbor(want, have)
self._compare_bgp_params(want, have)
- for name, entry in iteritems(want):
+ for name, entry in want.items():
if name != "as_number":
self.compare(
parsers=parsers,
@@ -154,7 +153,7 @@ class Bgp_global(ResourceModule):
name: have.pop(name, {}),
},
)
- for name, entry in iteritems(have):
+ for name, entry in have.items():
if name != "as_number":
self.compare(
parsers=parsers,
@@ -217,7 +216,7 @@ class Bgp_global(ResourceModule):
hneigh = have.pop("neighbor", {})
self._compare_neigh_lists(wneigh, hneigh)
- for name, entry in iteritems(wneigh):
+ for name, entry in wneigh.items():
for k, v in entry.items():
if k == "address":
continue
@@ -233,7 +232,7 @@ class Bgp_global(ResourceModule):
},
have={"as_number": want["as_number"], "neighbor": h},
)
- for name, entry in iteritems(hneigh):
+ for name, entry in hneigh.items():
if name not in wneigh.keys():
if self._check_af(name):
msg = "Use the _bgp_address_family module to delete the address_family under neighbor {0}, before replacing/deleting the neighbor.".format(
@@ -281,7 +280,7 @@ class Bgp_global(ResourceModule):
wbgp = want.pop("bgp_params", {})
hbgp = have.pop("bgp_params", {})
- for name, entry in iteritems(wbgp):
+ for name, entry in wbgp.items():
if name == "confederation":
if entry != hbgp.pop(name, {}):
self.addcmd(
@@ -325,7 +324,7 @@ class Bgp_global(ResourceModule):
if not wbgp and hbgp:
self.commands.append("delete protocols bgp" + self._asn_mod + " parameters")
hbgp = {}
- for name, entry in iteritems(hbgp):
+ for name, entry in hbgp.items():
if name == "confederation":
self.commands.append(
"delete protocols bgp" + self._asn_mod + " parameters confederation",
@@ -362,7 +361,7 @@ class Bgp_global(ResourceModule):
]:
wdict = want.pop(attrib, {})
hdict = have.pop(attrib, {})
- for key, entry in iteritems(wdict):
+ for key, entry in wdict.items():
if entry != hdict.pop(key, {}):
self.addcmd(entry, "neighbor.{0}".format(attrib), False)
# remove remaining items in have for replaced
@@ -370,7 +369,7 @@ class Bgp_global(ResourceModule):
self.addcmd(entry, "neighbor.{0}".format(attrib), True)
def _bgp_global_list_to_dict(self, entry):
- for name, proc in iteritems(entry):
+ for name, proc in entry.items():
if "neighbor" in proc:
neigh_dict = {}
for entry in proc.get("neighbor", []):
diff --git a/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py b/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py
index e2a25e32..d4e173c1 100644
--- a/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py
+++ b/plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py
@@ -17,7 +17,6 @@ __metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -28,13 +27,16 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.u
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import (
- list_diff_want_only,
in_target_not_none,
+ list_diff_want_only,
+)
+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,
+ load_config,
)
-
-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 Firewall_global(ConfigBase):
@@ -75,6 +77,13 @@ class Firewall_global(ConfigBase):
warnings = list()
commands = list()
+ try:
+ self._module.params["comment"]
+ except KeyError:
+ comment = []
+ else:
+ comment = self._module.params["comment"]
+
if self.state in self.ACTION_STATES:
existing_firewall_global_facts = self.get_firewall_global_facts()
else:
@@ -83,6 +92,12 @@ class Firewall_global(ConfigBase):
if self.state in self.ACTION_STATES or self.state == "rendered":
commands.extend(self.set_config(existing_firewall_global_facts))
+ if commands and self._module._diff:
+ commit = not self._module.check_mode
+ diff = load_config(self._module, commands, commit=commit, comment=comment)
+ if diff:
+ result["diff"] = {"prepared": str(diff)}
+
if commands and self.state in self.ACTION_STATES:
if not self._module.check_mode:
self._connection.edit_config(commands)
@@ -190,7 +205,7 @@ class Firewall_global(ConfigBase):
"twa_hazards_protection",
)
if want:
- for key, val in iteritems(want):
+ for key, val in want.items():
if val and key in b_set and not have:
commands.append(self._form_attr_cmd(attr=key, opr=False))
elif val and key in b_set and have and key in have and have[key] != val:
@@ -200,7 +215,7 @@ class Firewall_global(ConfigBase):
elif not want and have:
commands.append(self._compute_command(opr=False))
elif have:
- for key, val in iteritems(have):
+ for key, val in have.items():
if val and key in b_set:
commands.append(self._form_attr_cmd(attr=key, opr=False))
else:
@@ -247,7 +262,7 @@ class Firewall_global(ConfigBase):
"twa_hazards_protection",
)
if w_fg:
- for key, val in iteritems(w_fg):
+ for key, val in w_fg.items():
if opr and key in l_set and not (h and self._is_w_same(w_fg, h, key)):
commands.append(
self._form_attr_cmd(attr=key, val=self._bool_to_str(val), opr=opr),
@@ -258,11 +273,7 @@ class Firewall_global(ConfigBase):
self._form_attr_cmd(attr=key, key=self._bool_to_str(val), opr=opr),
)
continue
- if (
- key in l_set
- and not self._in_target(h, key)
- and not self._is_del(l_set, h)
- ):
+ if key in l_set and not self._in_target(h, key) and not self._is_del(l_set, h):
commands.append(
self._form_attr_cmd(attr=key, val=self._bool_to_str(val), opr=opr),
)
@@ -285,13 +296,13 @@ class Firewall_global(ConfigBase):
if h:
h_ping = h.get(attr) or {}
if self._is_root_del(w[attr], h_ping, attr):
- for item, value in iteritems(h[attr]):
+ for item, value in h[attr].items():
if not opr and item in l_set:
commands.append(self._form_attr_cmd(attr=item, opr=opr))
elif w[attr]:
if h and attr in h.keys():
h_ping = h.get(attr) or {}
- for item, value in iteritems(w[attr]):
+ for item, value in w[attr].items():
if (
opr
and item in l_set
@@ -355,7 +366,7 @@ class Firewall_global(ConfigBase):
cmd = self._compute_command(key="group", attr="ipv6-" + attr, opr=opr)
else:
cmd = self._compute_command(key="group", attr=attr, opr=opr)
- for key, val in iteritems(want):
+ for key, val in want.items():
if val:
if opr and key in l_set and not (h and self._is_w_same(want, h, key)):
if key == "name":
@@ -373,9 +384,17 @@ class Firewall_global(ConfigBase):
)
elif not opr and key in l_set:
if key == "name" and self._is_grp_del(h, want, key):
+ if len(commands) > 0 and commands[-1] == cmd + " " + want["name"] + " " + self._grp_type(
+ attr,
+ ):
+ commands.pop()
commands.append(cmd + " " + want["name"])
continue
- if not (h and in_target_not_none(h, key)) and not self._is_grp_del(h, want, "name"):
+ if not (h and in_target_not_none(h, key)) and not self._is_grp_del(
+ h,
+ want,
+ "name",
+ ):
commands.append(cmd + " " + want["name"] + " " + key)
elif key == "members":
commands.extend(
@@ -435,6 +454,10 @@ class Firewall_global(ConfigBase):
+ " "
+ member[self._get_mem_type(type)],
)
+ elif not opr and not have:
+ commands.append(
+ cmd + " " + name + " " + self._grp_type(type),
+ )
return commands
def _get_mem_type(self, group):
@@ -470,10 +493,12 @@ class Firewall_global(ConfigBase):
if want:
for w in want:
h = self.search_attrib_in_have(have, w, "connection_type")
- for key, val in iteritems(w):
+ for key, val in w.items():
if val and key != "connection_type":
if opr and key in l_set and not (h and self._is_w_same(w, h, key)):
- if key == "log" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
+ if key == "log" and LooseVersion(
+ get_os_version(self._module),
+ ) >= LooseVersion("1.4"):
commands.append(
self._form_attr_cmd(
key=attr + " " + w["connection_type"],
@@ -499,7 +524,9 @@ class Firewall_global(ConfigBase):
),
)
break # delete the whole thing and move on
- if (not self._in_target(h, key) or h[key] is None) and (self._in_target(w, key) and w[key]):
+ if (not self._in_target(h, key) or h[key] is None) and (
+ self._in_target(w, key) and w[key]
+ ):
# delete if not being replaced and value currently exists
commands.append(
self._form_attr_cmd(
@@ -531,23 +558,23 @@ class Firewall_global(ConfigBase):
if want:
for w in want:
h = self.search_attrib_in_have(have, w, "afi")
- if 'afi' in w:
- afi = w['afi']
+ if "afi" in w:
+ afi = w["afi"]
else:
- if h and 'afi' in h:
- afi = h['afi']
+ if h and "afi" in h:
+ afi = h["afi"]
else:
afi = None
afi = None
- for key, val in iteritems(w):
- if val and key != "afi":
+ for key, val in w.items():
+ if val is not None and key != "afi":
if opr and key in l_set and not (h and self._is_w_same(w, h, key)):
commands.append(
self._form_attr_cmd(
attr=key,
val=self._bool_to_str(val),
opr=opr,
- type=afi
+ type=afi,
),
)
elif not opr and key in l_set:
@@ -557,7 +584,7 @@ class Firewall_global(ConfigBase):
attr=key,
val=self._bool_to_str(val),
opr=opr,
- type=afi
+ type=afi,
),
)
continue
@@ -567,7 +594,7 @@ class Firewall_global(ConfigBase):
attr=key,
val=self._bool_to_str(val),
opr=opr,
- type=afi
+ type=afi,
),
)
elif key == "icmp_redirects":
@@ -587,20 +614,25 @@ class Firewall_global(ConfigBase):
commands = []
h_red = {}
l_set = ("send", "receive")
- if w and 'afi' in w:
- afi = w['afi']
+ if w and "afi" in w:
+ afi = w["afi"]
else:
- if h and 'afi' in h:
- afi = h['afi']
+ if h and "afi" in h:
+ afi = h["afi"]
else:
afi = None
if w[attr]:
if h and attr in h.keys():
h_red = h.get(attr) or {}
- for item, value in iteritems(w[attr]):
+ for item, value in w[attr].items():
if opr and item in l_set and not (h_red and self._is_w_same(w[attr], h_red, item)):
commands.append(
- self._form_attr_cmd(attr=item, val=self._bool_to_str(value), opr=opr, type=afi)
+ self._form_attr_cmd(
+ attr=item,
+ val=self._bool_to_str(value),
+ opr=opr,
+ type=afi,
+ ),
)
elif (
not opr
@@ -634,7 +666,12 @@ class Firewall_global(ConfigBase):
:param type: AF type of attribute.
:return: generated command.
"""
- command = self._compute_command(key=key, attr=self._map_attrib(attr, type=type), val=val, opr=opr)
+ command = self._compute_command(
+ key=key,
+ attr=self._map_attrib(attr, type=type),
+ val=val,
+ opr=opr,
+ )
return command
def _compute_command(self, key=None, attr=None, val=None, remove=False, opr=True):
@@ -651,14 +688,20 @@ class Firewall_global(ConfigBase):
cmd = "delete firewall "
else:
cmd = "set firewall "
- if attr and key != "group" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
+ if (
+ attr
+ and key != "group"
+ and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")
+ ):
cmd += "global-options "
if key:
cmd += key.replace("_", "-") + " "
if attr:
cmd += attr.replace("_", "-")
if val and opr:
- if key == "state_policy" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
+ if key == "state_policy" and LooseVersion(get_os_version(self._module)) >= LooseVersion(
+ "1.4",
+ ):
cmd += ""
else:
cmd += " '" + str(val) + "'"
diff --git a/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py b/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py
index bb6055b7..3c768e32 100644
--- a/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py
+++ b/plugins/module_utils/network/vyos/config/firewall_rules/firewall_rules.py
@@ -17,7 +17,6 @@ __metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -315,7 +314,7 @@ class Firewall_rules(ConfigBase):
h_rs = deepcopy(remove_empties(have))
h_rules = h_rs.pop("rules", None)
if w_rs:
- for key, val in iteritems(w_rs):
+ for key, val in w_rs.items():
if opr and key in l_set and not (h_rs and self._is_w_same(w_rs, h_rs, key)):
if key == "enable_default_log":
if val and (not h_rs or key not in h_rs or not h_rs[key]):
@@ -359,6 +358,7 @@ class Firewall_rules(ConfigBase):
"disable",
"description",
"jump_target",
+ "offload_target",
)
if w_rules:
for w in w_rules:
@@ -366,7 +366,7 @@ class Firewall_rules(ConfigBase):
h = self.search_rules_in_have_rs(h_rules, w["number"])
if w != h and self.state == "replaced":
h = {}
- for key, val in iteritems(w):
+ for key, val in w.items():
if val:
if opr and key in l_set and not (h and self._is_w_same(w, h, key)):
if key == "disable":
@@ -464,7 +464,7 @@ class Firewall_rules(ConfigBase):
if w[attr]:
if h and attr in h.keys():
h_state = h.get(attr) or {}
- for item, val in iteritems(w[attr]):
+ for item, val in w[attr].items():
if (
opr
and item in l_set
@@ -527,7 +527,7 @@ class Firewall_rules(ConfigBase):
if w[attr]:
if h and attr in h.keys():
h_recent = h.get(attr) or {}
- for item, val in iteritems(w[attr]):
+ for item, val in w[attr].items():
if (
opr
and item in l_set
@@ -555,7 +555,7 @@ class Firewall_rules(ConfigBase):
if w[attr]:
if h and attr in h.keys():
h_icmp = h.get(attr) or {}
- for item, val in iteritems(w[attr]):
+ for item, val in w[attr].items():
if (
opr
and item in l_set
@@ -598,7 +598,7 @@ class Firewall_rules(ConfigBase):
if w[attr]:
if h and attr in h.keys():
h_if = h.get(attr) or {}
- for item, val in iteritems(w[attr]):
+ for item, val in w[attr].items():
if opr and item in l_set and not (h_if and self._is_w_same(w[attr], h_if, item)):
commands.append(
cmd
@@ -633,7 +633,7 @@ class Firewall_rules(ConfigBase):
if w[attr]:
if h and attr in h.keys():
h_time = h.get(attr) or {}
- for item, val in iteritems(w[attr]):
+ for item, val in w[attr].items():
if (
opr
and item in l_set
@@ -862,7 +862,7 @@ class Firewall_rules(ConfigBase):
h_group = {}
if h and h.get(attr) and key in h[attr].keys():
h_group = h[attr].get(key)
- for item, val in iteritems(group):
+ for item, val in group.items():
if val:
if (
opr
@@ -1167,11 +1167,12 @@ class Firewall_rules(ConfigBase):
return True
elif isinstance(w, list) and isinstance(rs, list):
try:
+
def comparison(x):
- if 'name' in x:
- return x['name']
- if 'number' in x:
- return x['number']
+ if "name" in x:
+ return x["name"]
+ if "number" in x:
+ return x["number"]
return str(x)
sorted_list1 = sorted(w, key=comparison)
diff --git a/plugins/module_utils/network/vyos/config/interfaces/interfaces.py b/plugins/module_utils/network/vyos/config/interfaces/interfaces.py
index a9d9307c..0a55564e 100644
--- a/plugins/module_utils/network/vyos/config/interfaces/interfaces.py
+++ b/plugins/module_utils/network/vyos/config/interfaces/interfaces.py
@@ -16,7 +16,6 @@ __metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -227,7 +226,7 @@ class Interfaces(ConfigBase):
updates = dict_diff(have_copy, want_copy)
if updates:
- for key, value in iteritems(updates):
+ for key, value in updates.items():
commands.append(
self._compute_commands(key=key, value=value, interface=want_copy["name"]),
)
@@ -243,7 +242,7 @@ class Interfaces(ConfigBase):
vif_updates = dict_diff(have_vif, want_vif)
if vif_updates:
- for key, value in iteritems(vif_updates):
+ for key, value in vif_updates.items():
commands.append(
self._compute_commands(
key=key,
diff --git a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py
index 6e0c005f..a23494cd 100644
--- a/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py
+++ b/plugins/module_utils/network/vyos/config/l3_interfaces/l3_interfaces.py
@@ -19,7 +19,6 @@ __metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -80,7 +79,7 @@ class L3_interfaces(ConfigBase):
commands = list()
if self.state in self.ACTION_STATES:
- existing_l3_interfaces_facts = self.get_l3_interfaces_facts()
+ existing_l3_interfaces_facts = self.mutate_autoconfig(self.get_l3_interfaces_facts())
else:
existing_l3_interfaces_facts = []
@@ -96,16 +95,19 @@ class L3_interfaces(ConfigBase):
result["commands"] = commands
if self.state in self.ACTION_STATES or self.state == "gathered":
- changed_l3_interfaces_facts = self.get_l3_interfaces_facts()
+ changed_l3_interfaces_facts = self.mutate_autoconfig(self.get_l3_interfaces_facts())
elif self.state == "rendered":
result["rendered"] = commands
elif self.state == "parsed":
running_config = self._module.params["running_config"]
+
if not running_config:
self._module.fail_json(
msg="value of running_config parameter must not be empty for state parsed",
)
- result["parsed"] = self.get_l3_interfaces_facts(data=running_config)
+ result["parsed"] = self.mutate_autoconfig(
+ self.get_l3_interfaces_facts(data=running_config),
+ )
else:
changed_l3_interfaces_facts = []
@@ -129,6 +131,7 @@ class L3_interfaces(ConfigBase):
"""
want = self._module.params["config"]
have = existing_l3_interfaces_facts
+
resp = self.set_state(want, have)
return to_list(resp)
@@ -174,6 +177,7 @@ class L3_interfaces(ConfigBase):
elif state == "replaced":
commands.extend(self._state_replaced(item, obj_in_have))
+ commands = [command.replace("auto-config", "autoconf") for command in commands]
return commands
def _state_replaced(self, want, have):
@@ -226,7 +230,7 @@ class L3_interfaces(ConfigBase):
have_vifs = have_copy.pop("vifs", [])
for update in self._get_updates(want_copy, have_copy):
- for key, value in iteritems(update):
+ for key, value in update.items():
commands.append(
self._compute_commands(key=key, value=value, interface=want_copy["name"]),
)
@@ -238,7 +242,7 @@ class L3_interfaces(ConfigBase):
have_vif = {}
for update in self._get_updates(want_vif, have_vif):
- for key, value in iteritems(update):
+ for key, value in update.items():
commands.append(
self._compute_commands(
key=key,
@@ -247,7 +251,6 @@ class L3_interfaces(ConfigBase):
vif=want_vif["vlan_id"],
),
)
-
return commands
def _state_deleted(self, want, have):
@@ -261,51 +264,73 @@ class L3_interfaces(ConfigBase):
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):
+ if have_copy is not None:
+ if all(v in (None, {}, []) for k, v in want_copy.items() if k != "name"):
commands.append(
self._compute_commands(
- key=key,
- value=value,
+ key=None,
+ value=None,
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
+
+ want_vifs = want_copy.pop("vifs", [])
+ have_vifs = have_copy.pop("vifs", [])
+
+ 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 update.items():
+ commands.append(
+ self._compute_commands(
+ key=key,
+ interface=want_copy["name"],
+ value=value,
+ vif=want_vif["vlan_id"],
+ remove=True,
+ ),
+ )
+
+ for update in self._get_updates(have_copy, want_copy):
+ for key, value in update.items():
+ commands.append(
+ self._compute_commands(
+ key=key,
+ value=value,
+ interface=want_copy["name"],
+ 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)
+ if value == "auto-config" and vif is None:
+ intf_context = "interfaces {0} {1} ipv6".format(
+ get_interface_type(interface),
+ interface,
+ )
+ else:
+ 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))
+ suffix = " ipv6" if value == "auto-config" else ""
+ set_cmd += f" vif {vif}{suffix}"
+ del_cmd += f" vif {vif}{suffix}"
- if remove:
+ if remove and key and value:
command = "{0} {1} '{2}'".format(del_cmd, key, value)
+ elif remove and not (key and value):
+ command = "{0}".format(del_cmd)
else:
command = "{0} {1} '{2}'".format(set_cmd, key, value)
@@ -318,3 +343,12 @@ class L3_interfaces(ConfigBase):
updates.extend(diff_list_of_dicts(want.get("ipv6", []), have.get("ipv6", [])))
return updates
+
+ def mutate_autoconfig(self, obj):
+ if isinstance(obj, dict):
+ return dict(map(lambda kv: (kv[0], self.mutate_autoconfig(kv[1])), obj.items()))
+ if isinstance(obj, list):
+ return list(map(self.mutate_autoconfig, obj))
+ if isinstance(obj, str):
+ return obj.replace("autoconf", "auto-config")
+ return obj
diff --git a/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py b/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py
index 6890fe0c..62270503 100644
--- a/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py
+++ b/plugins/module_utils/network/vyos/config/lag_interfaces/lag_interfaces.py
@@ -12,7 +12,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
-from ansible.module_utils.six import iteritems
+
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -245,7 +245,7 @@ class Lag_interfaces(ConfigBase):
commands.extend(self._add_bond_members(want, have))
if updates:
- for key, value in iteritems(updates):
+ for key, value in updates.items():
if value:
if key == "arp_monitor":
commands.extend(self._add_arp_monitor(updates, key, want, have))
diff --git a/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py b/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py
index 1dfd25e4..39724f1b 100644
--- a/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py
+++ b/plugins/module_utils/network/vyos/config/lldp_global/lldp_global.py
@@ -12,7 +12,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
-from ansible.module_utils.six import iteritems
+
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -241,7 +241,7 @@ class Lldp_global(ConfigBase):
commands.extend(self._add_management_addresses(want, have))
if updates:
- for key, value in iteritems(updates):
+ for key, value in updates.items():
if value is not None:
if key == "enable":
if value is False:
diff --git a/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py b/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py
index 2fd6a548..97fcbce5 100644
--- a/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py
+++ b/plugins/module_utils/network/vyos/config/lldp_interfaces/lldp_interfaces.py
@@ -16,7 +16,6 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -285,7 +284,7 @@ class Lldp_interfaces(ConfigBase):
have_dict = have_location_type.get("coordinate_based") or {}
location_type = "coordinate-based"
updates = dict_diff(have_dict, want_dict)
- for key, value in iteritems(updates):
+ for key, value in updates.items():
if value:
commands.append(self._compute_command(set_cmd + location_type, key, str(value)))
@@ -319,7 +318,7 @@ class Lldp_interfaces(ConfigBase):
if is_dict_element_present(have_location_type, "coordinate_based"):
have_dict = have_location_type.get("coordinate_based") or {}
location_type = "coordinate-based"
- for key, value in iteritems(have_dict):
+ for key, value in have_dict.items():
only_in_have = key_value_in_dict(key, value, want_dict)
if not only_in_have:
commands.append(
diff --git a/plugins/module_utils/network/vyos/config/logging_global/logging_global.py b/plugins/module_utils/network/vyos/config/logging_global/logging_global.py
index f94c9195..35a2624a 100644
--- a/plugins/module_utils/network/vyos/config/logging_global/logging_global.py
+++ b/plugins/module_utils/network/vyos/config/logging_global/logging_global.py
@@ -20,7 +20,6 @@ created.
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -92,7 +91,7 @@ class Logging_global(ResourceModule):
if self.state in ["overridden", "replaced"]:
if wantd != haved:
wantx, havex = self.call_op(wantd, haved, "overridden")
- for k, have in iteritems(havex):
+ for k, have in havex.items():
if k not in wantx:
self._compare(want={}, have=have)
@@ -102,7 +101,7 @@ class Logging_global(ResourceModule):
if self.state == "merged":
wantd = dict_merge(haved, wantd)
- for k, want in iteritems(wantd):
+ for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}))
def _compare(self, want, have):
@@ -116,12 +115,12 @@ class Logging_global(ResourceModule):
def operation_rep(self, params):
op_val = dict()
- for k, val in iteritems(params):
+ for k, val in params.items():
if k in ["console", "global_params"]:
mod_val = deepcopy(val)
op_val.update(self.flatten_facility({k: mod_val}))
elif k in ["files", "hosts", "users"]:
- for m, n in iteritems(val):
+ for m, n in val.items():
mod_n = deepcopy(n)
if mod_n.get("archive"):
del mod_n["archive"]
@@ -160,18 +159,18 @@ class Logging_global(ResourceModule):
def flatten_facility(self, param):
temp_param = dict()
- for element, val in iteritems(param):
+ for element, val in param.items():
if element in ["console", "global_params", "syslog"]:
if element != "syslog" and val.get("facilities"):
- for k, v in iteritems(val.get("facilities")):
+ for k, v in val.get("facilities").items():
temp_param[k + element] = {element: {"facilities": v}}
del val["facilities"]
if val:
temp_param[element] = {element: val}
if element in ["files", "hosts", "users"]:
- for k, v in iteritems(val):
+ for k, v in val.items():
if v.get("facilities"):
- for pk, dat in iteritems(v.get("facilities")):
+ for pk, dat in v.get("facilities").items():
temp_param[pk + k] = {
element: {
"facilities": dat,
@@ -197,7 +196,7 @@ class Logging_global(ResourceModule):
"hosts": "hostname",
"users": "username",
}
- for element, val in iteritems(param):
+ for element, val in param.items():
if element == "facilities": # only with recursion call
_tem_par = {}
for par in val:
diff --git a/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py b/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py
index 5d294063..06ec1d6b 100644
--- a/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py
+++ b/plugins/module_utils/network/vyos/config/ntp_global/ntp_global.py
@@ -18,7 +18,6 @@ necessary to bring the current configuration to its desired end-state is
created.
"""
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -93,16 +92,16 @@ class Ntp_global(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
- haved = {k: v for k, v in iteritems(haved) if k in wantd or not wantd}
+ haved = {k: v for k, v in haved.items() if k in wantd or not wantd}
wantd = {}
commandlist = self._commandlist(haved)
servernames = self._servernames(haved)
# removing the servername and commandlist from the list after deleting it from haved
# iterate through the top-level items to delete
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
- for hk, hval in iteritems(have):
+ for hk, hval in have.items():
if hk == "allow_clients" and hk in commandlist:
self.commands.append(
self._tmplt.render({"": hk}, "allow_clients_delete", True),
@@ -130,7 +129,7 @@ class Ntp_global(ResourceModule):
commandlist = self._commandlist(haved)
servernames = self._servernames(haved)
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
if "server" not in have:
self._compareoverride(want={}, have=have)
@@ -139,7 +138,7 @@ class Ntp_global(ResourceModule):
self._compareoverride(want={}, have=have)
servernames.remove(have["server"])
- for k, want in iteritems(wantd):
+ for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}))
def _compare(self, want, have):
@@ -155,7 +154,7 @@ class Ntp_global(ResourceModule):
def _compareoverride(self, want, have):
# do not delete configuration with options level
- for i, val in iteritems(have):
+ for i, val in have.items():
if i == "options":
pass
else:
@@ -163,12 +162,12 @@ class Ntp_global(ResourceModule):
def _ntp_list_to_dict(self, entry):
servers_dict = {}
- for k, data in iteritems(entry):
+ for k, data in entry.items():
if k == "servers":
for value in data:
if "options" in value:
result = self._serveroptions_list_to_dict(value)
- for res, resvalue in iteritems(result):
+ for res, resvalue in result.items():
servers_dict.update({res: resvalue})
else:
servers_dict.update({value["server"]: value})
@@ -179,7 +178,7 @@ class Ntp_global(ResourceModule):
def _serveroptions_list_to_dict(self, entry):
serveroptions_dict = {}
- for Opk, Op in iteritems(entry):
+ for Opk, Op in entry.items():
if Opk == "options":
for val in Op:
dict = {}
@@ -190,16 +189,16 @@ class Ntp_global(ResourceModule):
def _commandlist(self, haved):
commandlist = []
- for k, have in iteritems(haved):
- for ck, cval in iteritems(have):
+ for k, have in haved.items():
+ for ck, cval in have.items():
if ck != "options" and ck not in commandlist:
commandlist.append(ck)
return commandlist
def _servernames(self, haved):
servernames = []
- for k, have in iteritems(haved):
- for sk, sval in iteritems(have):
+ for k, have in haved.items():
+ for sk, sval in have.items():
if sk != "options" and sval not in servernames:
servernames.append(sval)
return servernames
diff --git a/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py b/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py
index 51b47494..837a2ddf 100644
--- a/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py
+++ b/plugins/module_utils/network/vyos/config/ospf_interfaces/ospf_interfaces.py
@@ -17,7 +17,6 @@ necessary to bring the current configuration to its desired end-state is
created.
"""
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -27,17 +26,16 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.u
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ospf_interfaces import (
- Ospf_interfacesTemplate
+ Ospf_interfacesTemplate,
)
-
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.ospf_interfaces_14 import (
- Ospf_interfacesTemplate14
+ Ospf_interfacesTemplate14,
+)
+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 Ospf_interfaces(ResourceModule):
"""
@@ -77,7 +75,7 @@ class Ospf_interfaces(ResourceModule):
self._tmplt = Ospf_interfacesTemplate()
def parse(self):
- """ override parse to check template """
+ """override parse to check template"""
self._validate_template()
return super().parse()
@@ -119,12 +117,12 @@ class Ospf_interfaces(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
h_del = {}
- for k, v in iteritems(haved):
+ for k, v in haved.items():
if k in wantd or not wantd:
h_del.update({k: v})
haved = h_del
have_int = []
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k in wantd:
have_int.append(k)
self._remove_ospf_int(have)
@@ -132,7 +130,7 @@ class Ospf_interfaces(ResourceModule):
if self.state == "overridden":
have_int = []
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
have_int.append(k)
self._remove_ospf_int(have)
@@ -142,17 +140,17 @@ class Ospf_interfaces(ResourceModule):
# removing the interfaces from haved that are already negated
for interface in have_int:
haved.pop(interface)
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
self._compare(want={}, have=have)
- for k, want in iteritems(wantd):
+ for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}))
def _remove_ospf_int(self, entry):
int_name = entry.get("name", {})
int_addr = entry.get("address_family", {})
- for k, addr in iteritems(int_addr):
+ for k, addr in int_addr.items():
rem_entry = {"name": int_name, "address_family": {"afi": k}}
self.addcmd(rem_entry, "ip_ospf", True)
@@ -169,8 +167,8 @@ class Ospf_interfaces(ResourceModule):
hdict = have.get("address_family", {})
wname = want.get("name")
hname = have.get("name")
- for name, entry in iteritems(wdict):
- for key, param in iteritems(entry):
+ for name, entry in wdict.items():
+ for key, param in entry.items():
w_addr = {"afi": name, key: param}
h_addr = {}
if hdict.get(name):
@@ -178,8 +176,8 @@ class Ospf_interfaces(ResourceModule):
w = {"name": wname, "address_family": w_addr}
h = {"name": hname, "address_family": h_addr}
self.compare(parsers=self.parsers, want=w, have=h)
- for name, entry in iteritems(hdict):
- for key, param in iteritems(entry):
+ for name, entry in hdict.items():
+ for key, param in entry.items():
h_addr = {"afi": name, key: param}
w_addr = {}
w = {"name": wname, "address_family": w_addr}
@@ -187,7 +185,7 @@ class Ospf_interfaces(ResourceModule):
self.compare(parsers=self.parsers, want=w, have=h)
def _ospf_int_list_to_dict(self, entry):
- for name, family in iteritems(entry):
+ for name, family in entry.items():
if "address_family" in family:
addr_dict = {}
for entry in family.get("address_family", []):
diff --git a/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py b/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py
index ababc6f1..ed973179 100644
--- a/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py
+++ b/plugins/module_utils/network/vyos/config/ospfv2/ospfv2.py
@@ -17,7 +17,6 @@ __metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -33,10 +32,11 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils
_is_w_same,
list_diff_want_only,
)
+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 Ospfv2(ConfigBase):
"""
@@ -222,7 +222,7 @@ class Ospfv2(ConfigBase):
w = deepcopy(remove_empties(want))
leaf = ("default_metric", "log_adjacency_changes")
if w:
- for key, val in iteritems(w):
+ for key, val in w.items():
if opr and key in leaf and not _is_w_same(w, have, key):
commands.append(self._form_attr_cmd(attr=key, val=_bool_to_str(val), opr=opr))
elif not opr and key in leaf and not _in_target(have, key):
@@ -290,7 +290,7 @@ class Ospfv2(ConfigBase):
),
}
leaf = leaf_dict[attr]
- for item, value in iteritems(want[attr]):
+ for item, value in want[attr].items():
if opr and item in leaf and not _is_w_same(want[attr], h, item):
if item == "enabled":
item = "enable"
@@ -336,10 +336,22 @@ class Ospfv2(ConfigBase):
command = cmd + attr.replace("_", "-") + " "
if attr == "network":
command += member["address"]
- elif attr == "passive_interface" and member != "default" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
- command = command.replace("passive-interface", "interface") + member + " passive"
- elif attr == "passive_interface_exclude" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
- command = command.replace("passive-interface-exclude", "interface") + member + " passive disable"
+ elif (
+ attr == "passive_interface"
+ and member != "default"
+ and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")
+ ):
+ command = (
+ command.replace("passive-interface", "interface") + member + " passive"
+ )
+ elif attr == "passive_interface_exclude" and LooseVersion(
+ get_os_version(self._module),
+ ) >= LooseVersion("1.4"):
+ command = (
+ command.replace("passive-interface-exclude", "interface")
+ + member
+ + " passive disable"
+ )
else:
command += member
commands.append(command)
@@ -352,10 +364,21 @@ class Ospfv2(ConfigBase):
cmd + attr.replace("_", "-") + " " + member["address"],
)
elif member not in h:
- if attr == "passive_interface" and member != "default" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
+ if (
+ attr == "passive_interface"
+ and member != "default"
+ and LooseVersion(get_os_version(self._module))
+ >= LooseVersion("1.4")
+ ):
commands.append(cmd + "interface" + " " + member + " passive")
- elif attr == "passive_interface_exclude" and LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
- command = command.replace("passive-interface-exclude", "interface") + member + " passive disable"
+ elif attr == "passive_interface_exclude" and LooseVersion(
+ get_os_version(self._module),
+ ) >= LooseVersion("1.4"):
+ command = (
+ command.replace("passive-interface-exclude", "interface")
+ + member
+ + " passive disable"
+ )
else:
commands.append(cmd + attr.replace("_", "-") + " " + member)
else:
@@ -394,7 +417,7 @@ class Ospfv2(ConfigBase):
commands.append(cmd + attr.replace("_", "-"))
elif w:
for w_item in w:
- for key, val in iteritems(w_item):
+ for key, val in w_item.items():
if not cmd:
cmd = self._compute_command(opr=opr)
h_item = self.search_obj_in_have(h, w_item, name[attr])
@@ -502,7 +525,7 @@ class Ospfv2(ConfigBase):
commands.append(self._compute_command(attr=attr, opr=opr))
elif w:
for w_item in w:
- for key, val in iteritems(w_item):
+ for key, val in w_item.items():
if not cmd:
cmd = self._compute_command(opr=opr)
h_item = self.search_obj_in_have(h, w_item, name[attr])
@@ -599,7 +622,7 @@ class Ospfv2(ConfigBase):
leaf = leaf_dict[attr]
if h and key in h.keys():
h_attrib = h.get(key) or {}
- for item, val in iteritems(w[key]):
+ for item, val in w[key].items():
if opr and item in leaf and not _is_w_same(w[key], h_attrib, item):
if item in ("administrative", "always") and val:
commands.append(
@@ -660,7 +683,7 @@ class Ospfv2(ConfigBase):
self._form_attr_cmd(key="area", attr=w_area["area_id"], opr=opr),
)
else:
- for key, val in iteritems(w_area):
+ for key, val in w_area.items():
if opr and key in l_set and not _is_w_same(w_area, h_area, key):
if key == "area_id":
commands.append(
@@ -733,7 +756,7 @@ class Ospfv2(ConfigBase):
if w_area:
if h_type and key in h_type.keys():
h_area = h_type.get(key) or {}
- for item, val in iteritems(w_type[key]):
+ for item, val in w_type[key].items():
if (
opr
and item in a_type[key]
diff --git a/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py b/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py
index 2538a6f5..30d30571 100644
--- a/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py
+++ b/plugins/module_utils/network/vyos/config/ospfv3/ospfv3.py
@@ -17,7 +17,6 @@ __metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -204,7 +203,7 @@ class Ospfv3(ConfigBase):
commands = []
w = deepcopy(remove_empties(want))
if w:
- for key, val in iteritems(w):
+ for key, val in w.items():
commands.extend(self._render_child_param(w, have, key, opr))
return commands
@@ -245,7 +244,7 @@ class Ospfv3(ConfigBase):
elif want[attr]:
leaf_dict = {"parameters": "router_id"}
leaf = leaf_dict[attr]
- for item, value in iteritems(want[attr]):
+ for item, value in want[attr].items():
if opr and item in leaf and not _is_w_same(want[attr], h, item):
commands.append(self._form_attr_cmd(key=attr, attr=item, val=value, opr=opr))
elif not opr and item in leaf and not _in_target(h, item):
@@ -283,7 +282,7 @@ class Ospfv3(ConfigBase):
commands.append(self._compute_command(attr=attr, opr=opr))
elif w:
for w_item in w:
- for key, val in iteritems(w_item):
+ for key, val in w_item.items():
if not cmd:
cmd = self._compute_command(opr=opr)
h_item = search_obj_in_list(w_item[name[attr]], h, name[attr])
@@ -376,7 +375,7 @@ class Ospfv3(ConfigBase):
self._form_attr_cmd(key="area", attr=w_area["area_id"], opr=opr),
)
else:
- for key, val in iteritems(w_area):
+ for key, val in w_area.items():
if opr and key in l_set and not _is_w_same(w_area, h_area, key):
if key == "area_id":
commands.append(
diff --git a/plugins/module_utils/network/vyos/config/prefix_lists/prefix_lists.py b/plugins/module_utils/network/vyos/config/prefix_lists/prefix_lists.py
index 9da27c15..9b703399 100644
--- a/plugins/module_utils/network/vyos/config/prefix_lists/prefix_lists.py
+++ b/plugins/module_utils/network/vyos/config/prefix_lists/prefix_lists.py
@@ -19,7 +19,6 @@ created.
"""
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -86,23 +85,23 @@ class Prefix_lists(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
- haved = {k: v for k, v in iteritems(haved) if k in wantd or not wantd}
- for key, hvalue in iteritems(haved):
+ haved = {k: v for k, v in haved.items() if k in wantd or not wantd}
+ for key, hvalue in haved.items():
wvalue = wantd.pop(key, {})
if wvalue:
wplists = wvalue.get("prefix_lists", {})
hplists = hvalue.get("prefix_lists", {})
hvalue["prefix_lists"] = {
- k: v for k, v in iteritems(hplists) if k in wplists or not wplists
+ k: v for k, v in hplists.items() if k in wplists or not wplists
}
# remove superfluous config for overridden and deleted
if self.state in ["overridden", "deleted"]:
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
self._compare(want={}, have=have)
- for k, want in iteritems(wantd):
+ for k, want in wantd.items():
self._compare(want=want, have=haved.pop(k, {}))
def _compare(self, want, have):
@@ -127,7 +126,7 @@ class Prefix_lists(ResourceModule):
)
def _compare_plists(self, want, have):
- for wk, wentry in iteritems(want):
+ for wk, wentry in want.items():
hentry = have.pop(wk, {})
# parser list for name and descriptions
@@ -143,7 +142,7 @@ class Prefix_lists(ResourceModule):
self._compare_rules(want=wplrules, have=hplrules)
def _compare_rules(self, want, have):
- for wr, wrule in iteritems(want):
+ for wr, wrule in want.items():
hrule = have.pop(wr, {})
# parser list for entries
@@ -164,7 +163,7 @@ class Prefix_lists(ResourceModule):
)
def _prefix_list_list_to_dict(self, entry):
- for afi, value in iteritems(entry):
+ for afi, value in entry.items():
if "prefix_lists" in value:
for pl in value["prefix_lists"]:
pl.update({"afi": afi})
diff --git a/plugins/module_utils/network/vyos/config/route_maps/route_maps.py b/plugins/module_utils/network/vyos/config/route_maps/route_maps.py
index 9b6c3e9d..dca99d1c 100644
--- a/plugins/module_utils/network/vyos/config/route_maps/route_maps.py
+++ b/plugins/module_utils/network/vyos/config/route_maps/route_maps.py
@@ -19,7 +19,6 @@ created.
"""
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -31,6 +30,13 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.route_maps import (
Route_mapsTemplate,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.route_maps_14 import (
+ Route_mapsTemplate14,
+)
+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
class Route_maps(ResourceModule):
@@ -59,6 +65,8 @@ class Route_maps(ResourceModule):
"set_bgp_extcommunity_rt",
"set_extcommunity_rt",
"set_extcommunity_soo",
+ "set_extcommunity_bandwidth",
+ "set_extcommunity_bandwidth_non_transitive",
"set_ip_next_hop",
"set_ipv6_next_hop",
"set_large_community",
@@ -70,6 +78,7 @@ class Route_maps(ResourceModule):
"set_src",
"set_tag",
"set_weight",
+ "set_table",
"set_comm_list",
"set_comm_list_delete",
"set_community",
@@ -89,15 +98,34 @@ class Route_maps(ResourceModule):
"on_match_next",
"match_ipv6_address",
"match_ipv6_nexthop",
+ "match_protocol",
"match_rpki",
]
+ def _validate_template(self):
+ version = get_os_version(self._module)
+ if LooseVersion(version) >= LooseVersion("1.4"):
+ self._tmplt = Route_mapsTemplate14()
+ else:
+ self._tmplt = Route_mapsTemplate()
+
+ def parse(self):
+ """override parse to check template"""
+ self._validate_template()
+ return super().parse()
+
+ def get_parser(self, name):
+ """get_parsers"""
+ self._validate_template()
+ return super().get_parser(name)
+
def execute_module(self):
"""Execute the module
:rtype: A dictionary
:returns: The result from module execution
"""
+ self._validate_template()
if self.state not in ["parsed", "gathered"]:
self.generate_commands()
self.run_commands()
@@ -116,16 +144,16 @@ class Route_maps(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
- haved = {k: v for k, v in iteritems(haved) if k in wantd or not wantd}
+ haved = {k: v for k, v in haved.items() if k in wantd or not wantd}
wantd = {}
# remove superfluous config for overridden and deleted
if self.state in ["overridden", "deleted"]:
- for k, have in iteritems(haved):
+ for k, have in haved.items():
if k not in wantd:
self.commands.append(self._tmplt.render({"route_map": k}, "route_map", True))
- for wk, want in iteritems(wantd):
+ for wk, want in wantd.items():
self._compare(want=want, have=haved.pop(wk, {}))
def _compare(self, want, have):
@@ -139,13 +167,13 @@ class Route_maps(ResourceModule):
self._compare_entries(want=w_entries, have=h_entries)
def _compare_entries(self, want, have):
- for wk, wentry in iteritems(want):
+ for wk, wentry in want.items():
hentry = have.pop(wk, {})
self.compare(parsers=self.parsers, want=wentry, have=hentry)
def _route_maps_list_to_dict(self, entry):
entry = {x["route_map"]: x for x in entry}
- for rmap, data in iteritems(entry):
+ for rmap, data in entry.items():
if "entries" in data:
for x in data["entries"]:
x.update({"route_map": rmap})
diff --git a/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py b/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py
index 9497d7fa..4bc5ddc4 100644
--- a/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py
+++ b/plugins/module_utils/network/vyos/config/snmp_server/snmp_server.py
@@ -20,7 +20,6 @@ created.
import re
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
)
@@ -107,13 +106,13 @@ class Snmp_server(ResourceModule):
"""
self._compare_lists(want, have)
self._compare_snmp_v3(want, have)
- for key, value in iteritems(want):
+ for key, value in want.items():
self.compare(
parsers=self.parsers,
want={key: value},
have={key: have.pop(key, "")},
)
- for key, entry in iteritems(have):
+ for key, entry in have.items():
if entry:
self.compare(parsers=self.parsers, want={}, have={key: entry})
@@ -125,10 +124,10 @@ class Snmp_server(ResourceModule):
for attrib in parsers:
wdict = get_from_dict(want, attrib) or {}
hdict = get_from_dict(have, attrib) or {}
- for key, entry in iteritems(wdict):
+ for key, entry in wdict.items():
# self.addcmd(entry, attrib, False)
if attrib == "communities":
- for k, v in iteritems(entry):
+ for k, v in entry.items():
if k in ["clients", "networks"]:
v.sort()
h = {}
@@ -153,9 +152,9 @@ class Snmp_server(ResourceModule):
)
have.pop(attrib, {})
# remove remaining items in have for replaced
- for key, entry in iteritems(hdict):
+ for key, entry in hdict.items():
if attrib == "communities":
- for k, v in iteritems(entry):
+ for k, v in entry.items():
if k != "name":
self.compare(
parsers="communities",
@@ -188,9 +187,9 @@ class Snmp_server(ResourceModule):
for attrib in attribute_dict.keys():
wattrib = get_from_dict(wdict, attrib) or {}
hattrib = get_from_dict(hdict, attrib) or {}
- for key, entry in iteritems(wattrib):
+ for key, entry in wattrib.items():
self._compare_snmp_v3_auth_privacy(entry, hattrib.get(key, {}), attrib)
- for k, v in iteritems(entry):
+ for k, v in entry.items():
if k != attribute_dict[attrib]:
h = {}
if hattrib.get(key):
@@ -217,11 +216,11 @@ class Snmp_server(ResourceModule):
have=h,
)
# remove remaining items in have for replaced
- for key, entry in iteritems(hattrib):
+ for key, entry in hattrib.items():
self._compare_snmp_v3_auth_privacy({}, entry, attrib)
self.compare(parsers=parsers, want={}, have={"snmp_v3": {attrib: entry}})
hdict.pop(attrib, {})
- for key, entry in iteritems(wdict):
+ for key, entry in wdict.items():
# self.addcmd(entry, attrib, False)
self.compare(
parsers="snmp_v3.engine_id",
@@ -229,7 +228,7 @@ class Snmp_server(ResourceModule):
have={"snmp_v3": {key: hdict.pop(key, {})}},
)
# remove remaining items in have for replaced
- for key, entry in iteritems(hdict):
+ for key, entry in hdict.items():
self.compare(parsers=parsers, want={}, have={"snmp_v3": {key: entry}})
def _compare_snmp_v3_auth_privacy(self, wattrib, hattrib, attrib):
@@ -244,7 +243,7 @@ class Snmp_server(ResourceModule):
primary_key = "user"
else:
primary_key = "address"
- for key, entry in iteritems(wattrib):
+ for key, entry in wattrib.items():
if key != primary_key and key in ["authentication", "privacy"]:
self.compare(
parsers=parsers,
@@ -265,7 +264,7 @@ class Snmp_server(ResourceModule):
},
},
)
- for key, entry in iteritems(hattrib):
+ for key, entry in hattrib.items():
if key != primary_key and key in ["authentication", "privacy"]:
self.compare(
parsers=parsers,
@@ -291,13 +290,13 @@ class Snmp_server(ResourceModule):
"views": "view",
"trap_targets": "address",
}
- for k, v in iteritems(param_dict):
+ for k, v in param_dict.items():
if k in entry:
a_dict = {}
for el in entry[k]:
a_dict.update({el[v]: el})
entry[k] = a_dict
- for k, v in iteritems(v3_param_dict):
+ for k, v in v3_param_dict.items():
if entry.get("snmp_v3") and k in entry.get("snmp_v3"):
a_dict = {}
for el in entry["snmp_v3"][k]:
diff --git a/plugins/module_utils/network/vyos/config/static_routes/static_routes.py b/plugins/module_utils/network/vyos/config/static_routes/static_routes.py
index 8451e7da..da8f8e3d 100644
--- a/plugins/module_utils/network/vyos/config/static_routes/static_routes.py
+++ b/plugins/module_utils/network/vyos/config/static_routes/static_routes.py
@@ -17,7 +17,6 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
@@ -182,7 +181,7 @@ class Static_routes(ConfigBase):
"""
commands = []
if have:
- for key, value in iteritems(want):
+ for key, value in want.items():
if value:
if key == "next_hops":
commands.extend(self._update_next_hop(want, have))
@@ -257,7 +256,7 @@ class Static_routes(ConfigBase):
"""
commands = []
have = {}
- for key, value in iteritems(want):
+ for key, value in want.items():
if value:
if key == "dest":
commands.append(self._compute_command(dest=want["dest"]))
@@ -287,7 +286,7 @@ class Static_routes(ConfigBase):
updates = dict_delete(want_blackhole, have_blackhole)
if updates:
- for attrib, value in iteritems(updates):
+ for attrib, value in updates.items():
if value:
if attrib == "distance":
commands.append(
@@ -394,7 +393,7 @@ class Static_routes(ConfigBase):
have_blackhole = have_copy.get(key) or {}
updates = dict_delete(have_blackhole, want_blackhole)
if updates:
- for attrib, value in iteritems(updates):
+ for attrib, value in updates.items():
if value:
if attrib == "distance":
commands.append(
@@ -508,7 +507,7 @@ class Static_routes(ConfigBase):
commands.extend(self._add_next_hop(want, have, opr=opr))
if opr and updates:
- for key, value in iteritems(updates):
+ for key, value in updates.items():
if value:
if key == "blackhole_config":
commands.extend(self._add_blackhole(key, want, have))
diff --git a/plugins/module_utils/network/vyos/config/vrf/__init__.py b/plugins/module_utils/network/vyos/config/vrf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/vrf/__init__.py
diff --git a/plugins/module_utils/network/vyos/config/vrf/vrf.py b/plugins/module_utils/network/vyos/config/vrf/vrf.py
new file mode 100644
index 00000000..aa4329d9
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/vrf/vrf.py
@@ -0,0 +1,308 @@
+#
+# -*- 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_vrf config file.
+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 its desired end-state is
+created.
+"""
+
+from copy import deepcopy
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
+ ResourceModule,
+)
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global import (
+ Bgp_global,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv2.ospfv2 import (
+ Ospfv2,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.ospfv3.ospfv3 import (
+ Ospfv3,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.static_routes.static_routes import (
+ Static_routes,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrf import (
+ VrfTemplate,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import combine
+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
+
+
+class Vrf(ResourceModule):
+ """
+ The vyos_vrf config class
+ """
+
+ def __init__(self, module):
+ super(Vrf, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="vrf",
+ tmplt=VrfTemplate(),
+ )
+ self.parsers = [
+ "bind_to_all",
+ ]
+
+ def _validate_template(self):
+ version = get_os_version(self._module)
+ if LooseVersion(version) >= LooseVersion("1.4"):
+ self._tmplt = VrfTemplate()
+ else:
+ self._module.fail_json(msg="VRF is not supported in this version of VyOS")
+
+ def parse(self):
+ """override parse to check template"""
+ self._validate_template()
+ return super().parse()
+
+ def get_parser(self, name):
+ """get_parsers"""
+ self._validate_template()
+ return super().get_parser(name)
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+
+ return self.result
+
+ def generate_commands(self):
+ """Generate configuration commands to send based on
+ want, have and desired state.
+ """
+ wantd = {}
+ haved = {}
+ wantd = deepcopy(self.want)
+ haved = deepcopy(self.have)
+
+ # if state is merged, merge want onto have and then compare
+ if self.state in ["merged", "replaced"]:
+
+ wantd = combine(haved, wantd, recursive=True)
+
+ # if state is deleted, delete and empty out wantd
+ if self.state == "deleted":
+ w = deepcopy(wantd)
+ if w == {} and haved != {}:
+ self.commands = ["delete vrf"]
+ return
+ for k, want in w.items():
+ if not (k in haved and haved[k]):
+ del wantd[k]
+ else:
+ if isinstance(want, list):
+ for entry in want:
+ wname = entry.get("name")
+ haved["instances"] = [
+ i for i in haved.get("instances", []) if i.get("name") != wname
+ ]
+ self.commands.append("delete vrf name {}".format(wname))
+ else:
+ self.commands.append("delete vrf {}".format(k.replace("_", "-")))
+ del wantd[k]
+
+ if self.state == "overridden":
+ w = deepcopy(wantd)
+ h = deepcopy(haved)
+ for k, want in w.items():
+ if k in haved and haved[k] != want:
+ if isinstance(want, list):
+ for entry in want:
+ wname = entry.get("name")
+ hdict = next(
+ (inst for inst in haved["instances"] if inst["name"] == wname),
+ None,
+ )
+ wantc = self._canonicalise(entry)
+ havec = self._canonicalise(hdict or {})
+
+ if wantc != havec:
+ haved["instances"] = [
+ i for i in haved.get("instances", []) if i.get("name") != wname
+ ]
+ self.commands.append("delete vrf name {}".format(wname))
+ self.commands.append("commit")
+
+ for k, want in wantd.items():
+ if isinstance(want, list):
+ self._compare_instances(want=want, have=haved.pop(k, {}))
+ self.compare(
+ parsers=self.parsers,
+ want={k: want},
+ have={k: haved.pop(k, {})},
+ )
+
+ def _compare_instances(self, want, have):
+ """Compare the instances of the VRF"""
+ parsers = [
+ "table_id",
+ "vni",
+ "description",
+ "disable_vrf",
+ ]
+
+ for entry in want:
+ h = {}
+ wname = entry.get("name")
+ h = {
+ k: v
+ for vrf in have
+ if vrf.get("name") == wname
+ for k, v in vrf.items()
+ if k != "address_family"
+ }
+ self.compare(parsers=parsers, want=entry, have=h)
+
+ if "address_family" in entry:
+ wafi = {"name": wname, "address_family": entry.get("address_family", [])}
+ hdict = next((d for d in have if d.get("name") == wname), None)
+
+ hafi = {
+ "name": (hdict or {"name": wname})["name"],
+ "address_family": hdict.get("address_family", []) if hdict else [],
+ }
+
+ self._compare_addr_family(wafi, hafi)
+
+ if "protocols" in entry:
+ for protocol_name in entry["protocols"]:
+
+ w_p_dict = entry["protocols"][protocol_name]
+
+ h_p_dict = next(
+ (
+ v.get("protocols", {}).get(protocol_name, {})
+ for v in have
+ if v.get("name") == wname
+ ),
+ {},
+ )
+ if protocol_name == "bgp":
+ bgp_module = Bgp_global(self._module)
+ bgp_module._validate_template()
+ bgp_module.want = w_p_dict
+ bgp_module.have = h_p_dict
+ bgp_module.generate_commands()
+ protocol_commands = bgp_module.commands
+ elif protocol_name == "ospf":
+ ospfv2_module = Ospfv2(self._module)
+ ospfv2_module._module.params["config"] = w_p_dict
+ ospfv2_module.state = self.state
+ protocol_commands = ospfv2_module.set_config(h_p_dict)
+ elif protocol_name == "ospfv3":
+ ospfv3_module = Ospfv3(self._module)
+ ospfv3_module._module.params["config"] = w_p_dict
+ ospfv3_module.state = self.state
+ protocol_commands = ospfv3_module.set_config(h_p_dict)
+ elif protocol_name == "static":
+ static_routes_module = Static_routes(self._module)
+ static_routes_module._module.params["config"] = w_p_dict
+ static_routes_module.state = self.state
+ protocol_commands = static_routes_module.set_config(h_p_dict)
+ else:
+ self._module.fail_json(
+ msg="The protocol {} is not supported".format(protocol_name),
+ )
+ self.commands.extend(
+ [
+ cmd.replace("protocols", "vrf name " + wname + " protocols", 1)
+ for cmd in protocol_commands
+ ],
+ )
+
+ def _compare_addr_family(self, want, have):
+ """Compare the address families of the VRF"""
+ afi_parsers = [
+ "disable_forwarding",
+ "disable_nht",
+ ]
+
+ wafi = self.afi_to_list(want)
+ hafi = self.afi_to_list(have)
+
+ lookup = {(d["name"], d["afi"]): d for d in hafi}
+ pairs = [(d1, lookup.get((d1["name"], d1["afi"]), {})) for d1 in wafi]
+
+ for wafd, hafd in pairs:
+ if "route_maps" in wafd:
+ self._compare_route_maps(wafd, hafd)
+ self.compare(parsers=afi_parsers, want=wafd, have=hafd)
+
+ def afi_to_list(self, data):
+ """Convert address family dict to list"""
+
+ return [
+ {"name": data["name"], **{**af, "afi": "ip" if af["afi"] == "ipv4" else af["afi"]}}
+ for af in data["address_family"]
+ ]
+
+ def _compare_route_maps(self, wafd, hafd):
+ want_rms = wafd.get("route_maps", [])
+ have_rms = hafd.get("route_maps", [])
+
+ for want in want_rms:
+ match = next(
+ (
+ h
+ for h in have_rms
+ if h["rm_name"] == want["rm_name"] and h["protocol"] == want["protocol"]
+ ),
+ {},
+ )
+ base = {"name": wafd["name"], "afi": wafd["afi"]}
+
+ self.compare(
+ parsers="route_maps",
+ want={**base, "route_maps": want},
+ have={**base, "route_maps": match},
+ )
+
+ def _canonicalise(self, obj):
+ if isinstance(obj, dict):
+ return {k: self._canonicalise(v) for k, v in obj.items()}
+
+ if isinstance(obj, list):
+ if not obj:
+ return obj
+
+ if not isinstance(obj[0], dict):
+ return sorted(obj)
+
+ canon = [self._canonicalise(i) for i in obj]
+
+ def sort_key(d):
+ for k in ("name", "address", "afi", "area_id", "neighbor_id", "dest"):
+ if k in d:
+ return d[k]
+ return tuple(sorted(d.items()))
+
+ return sorted(canon, key=sort_key)
+
+ return obj
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
@@ -28,11 +28,11 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_template
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"""
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
@@ -25,15 +25,14 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.bgp
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"""
diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py
index 74bbda74..24c444dd 100644
--- a/plugins/module_utils/network/vyos/facts/facts.py
+++ b/plugins/module_utils/network/vyos/facts/facts.py
@@ -80,6 +80,7 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.snmp_
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes import (
Static_routesFacts,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.vrf.vrf import VrfFacts
FACT_LEGACY_SUBSETS = dict(default=Default, neighbors=Neighbors, config=Config)
@@ -104,6 +105,7 @@ FACT_RESOURCE_SUBSETS = dict(
ntp_global=Ntp_globalFacts,
snmp_server=Snmp_serverFacts,
hostname=HostnameFacts,
+ vrf=VrfFacts,
)
diff --git a/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py b/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py
index a46f8563..3a48889e 100644
--- a/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py
+++ b/plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py
@@ -179,7 +179,7 @@ class Firewall_globalFacts(object):
if policies:
rules_lst = []
for sp in set(policies):
- sp_regex = r" %s .+$" % sp
+ sp_regex = r"^set firewall (?:global-options )?state-policy %s .+$" % sp
cfg = "\n".join(findall(sp_regex, conf, M))
obj = self.parse_policies(cfg, sp)
obj["connection_type"] = sp
@@ -233,7 +233,7 @@ class Firewall_globalFacts(object):
if groups:
rules_lst = []
for gr in set(groups):
- gr_regex = r" %s .+$" % gr
+ gr_regex = r"^set firewall group " + type + " %s .+$" % gr
cfg = "\n".join(findall(gr_regex, conf, M))
if "ipv6" in type:
# fmt: off
diff --git a/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py b/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py
index a6b56345..f8f02e7a 100644
--- a/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py
+++ b/plugins/module_utils/network/vyos/facts/firewall_rules/firewall_rules.py
@@ -61,12 +61,20 @@ class Firewall_rulesFacts(object):
objs = []
# check 1.4+ first
new_rules = True
- v6_rules = findall(r"^set firewall ipv6 (name|forward|input|output) (?:\'*)(\S+)(?:\'*)", data, M)
+ v6_rules = findall(
+ r"^set firewall ipv6 (name|forward|input|output) (?:\'*)(\S+)(?:\'*)",
+ data,
+ M,
+ )
if not v6_rules:
v6_rules = findall(r"^set firewall ipv6-name (?:\'*)(\S+)(?:\'*)", data, M)
if v6_rules:
new_rules = False
- v4_rules = findall(r"^set firewall ipv4 (name|forward|input|output) (?:\'*)(\S+)(?:\'*)", data, M)
+ v4_rules = findall(
+ r"^set firewall ipv4 (name|forward|input|output) (?:\'*)(\S+)(?:\'*)",
+ data,
+ M,
+ )
if not v4_rules:
v4_rules = findall(r"^set firewall name (?:\'*)(\S+)(?:\'*)", data, M)
if v4_rules:
@@ -171,12 +179,18 @@ class Firewall_rulesFacts(object):
:returns: The generated config
"""
conf = "\n".join(filter(lambda x: x, conf))
- a_lst = ["description", "default_action", "default_jump_target", "enable_default_log", "default_log"]
+ a_lst = [
+ "description",
+ "default_action",
+ "default_jump_target",
+ "enable_default_log",
+ "default_log",
+ ]
config = self.parse_attr(conf, a_lst, match)
if not config:
config = {}
- if 'default_log' in config:
- config['enable_default_log'] = config.pop('default_log')
+ if "default_log" in config:
+ config["enable_default_log"] = config.pop("default_log")
config["rules"] = self.parse_rules_lst(conf)
return config
@@ -219,6 +233,7 @@ class Firewall_rulesFacts(object):
"description",
"icmp",
"jump_target",
+ "offload_target",
"queue",
"queue_options",
]
@@ -263,8 +278,8 @@ class Firewall_rulesFacts(object):
found_lengths = findall(rule_regex, conf, M)
if found_lengths:
lengths = []
- for l in set(found_lengths):
- obj = {"length": l.strip("'")}
+ for pplen in set(found_lengths):
+ obj = {"length": pplen.strip("'")}
lengths.append(obj)
return lengths
@@ -389,21 +404,21 @@ class Firewall_rulesFacts(object):
out = search(r"^.*" + regex + " (.+)", conf, M)
if out:
val = out.group(1).strip("'")
- if attrib == 'type-name':
- config['type_name'] = val
- if attrib == 'code':
- config['code'] = int(val)
- if attrib == 'type':
+ if attrib == "type-name":
+ config["type_name"] = val
+ if attrib == "code":
+ config["code"] = int(val)
+ if attrib == "type":
# <1.3 could be # (type), #/# (type/code) or 'type' (type_name)
# recent this is only for strings
if "/" in val: # type/code
- (type_no, code) = val.split(".")
- config['type'] = type_no
- config['code'] = code
+ (type_no, code) = val.split("/")
+ config["type"] = int(type_no)
+ config["code"] = int(code)
elif val.isnumeric():
- config['type'] = type_no
+ config["type"] = int(val)
else:
- config['type_name'] = val
+ config["type_name"] = val
return config
def parse_icmp(self, conf, attrib=None):
@@ -414,7 +429,7 @@ class Firewall_rulesFacts(object):
:return: generated config dictionary.
"""
cfg_dict = self.parse_icmp_attr(conf, "icmp")
- if (len(cfg_dict) == 0):
+ if len(cfg_dict) == 0:
cfg_dict = self.parse_icmp_attr(conf, "icmpv6")
return cfg_dict
@@ -458,7 +473,7 @@ class Firewall_rulesFacts(object):
if not out:
if attrib == "disable":
out = search(r"^.*\d+" + " (disable$)", conf, M)
- if attrib == 'log':
+ if attrib == "log":
out = search(r"^.*\d+" + " (log$)", conf, M)
if out:
@@ -524,6 +539,6 @@ class Firewall_rulesFacts(object):
val = out.group(1).strip("'")
if "/" in val: # number/unit
(number, unit) = val.split("/")
- config['number'] = number
- config['unit'] = unit
+ config["number"] = number
+ config["unit"] = unit
return config
diff --git a/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py b/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py
index 7d4d1a08..d62ea9b8 100644
--- a/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py
+++ b/plugins/module_utils/network/vyos/facts/l3_interfaces/l3_interfaces.py
@@ -20,7 +20,6 @@ import re
from copy import deepcopy
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.l3_interfaces.l3_interfaces import (
@@ -139,7 +138,7 @@ class L3_interfacesFacts(object):
else:
config["ipv6"].append({"address": item})
- for key, value in iteritems(config):
+ for key, value in config.items():
if value == []:
config[key] = None
diff --git a/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py b/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py
index 8b60bef9..da80d967 100644
--- a/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py
+++ b/plugins/module_utils/network/vyos/facts/logging_global/logging_global.py
@@ -15,7 +15,6 @@ for a given resource, parsed, and the facts tree is populated
based on the configuration.
"""
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.logging_global.logging_global import (
@@ -38,7 +37,7 @@ class Logging_globalFacts(object):
def process_facts(self, objFinal):
if objFinal:
- for ke, vl in iteritems(objFinal):
+ for ke, vl in objFinal.items():
if ke == "files":
_files = []
for k, v in vl.items():
diff --git a/plugins/module_utils/network/vyos/facts/route_maps/route_maps.py b/plugins/module_utils/network/vyos/facts/route_maps/route_maps.py
index 2ad54e63..cfae26e3 100644
--- a/plugins/module_utils/network/vyos/facts/route_maps/route_maps.py
+++ b/plugins/module_utils/network/vyos/facts/route_maps/route_maps.py
@@ -25,6 +25,13 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.rou
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.route_maps import (
Route_mapsTemplate,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.route_maps_14 import (
+ Route_mapsTemplate14,
+)
+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
class Route_mapsFacts(object):
@@ -59,11 +66,18 @@ class Route_mapsFacts(object):
"""
facts = {}
objs = []
+
+ if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
+ route_maps_class = Route_mapsTemplate14
+ else:
+ route_maps_class = Route_mapsTemplate
+
if not data:
data = self.get_config(connection)
# parse native config using the Route_maps template
- route_maps_parser = Route_mapsTemplate(lines=data.splitlines())
+ route_maps_parser = route_maps_class(lines=data.splitlines())
+
if route_maps_parser.parse().get("route_maps"):
objs = list(route_maps_parser.parse().get("route_maps").values())
for item in objs:
diff --git a/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py b/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py
index e70a15f9..d961a0ff 100644
--- a/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py
+++ b/plugins/module_utils/network/vyos/facts/snmp_server/snmp_server.py
@@ -17,7 +17,6 @@ based on the configuration.
import re
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.snmp_server.snmp_server import (
@@ -63,7 +62,7 @@ class Snmp_serverFacts(object):
if objs:
if "communities" in objs:
for k in objs["communities"].values():
- for param, val in iteritems(k):
+ for param, val in k.items():
if param in ["clients", "networks"]:
if None in val:
val.remove(None)
diff --git a/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py b/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py
index 99b3917b..710d91fe 100644
--- a/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py
+++ b/plugins/module_utils/network/vyos/facts/static_routes/static_routes.py
@@ -164,9 +164,9 @@ class Static_routesFacts(object):
elif dis >= 1:
nh_info["enabled"] = False
for element in nh_list:
- if element["forward_router_address"] == nh_info["forward_router_address"]:
- if "interface" in nh_info.keys():
- element["interface"] = nh_info["interface"]
+ if element.get("forward_router_address") == nh_info.get(
+ "forward_router_address",
+ ):
if "admin_distance" in nh_info.keys():
element["admin_distance"] = nh_info["admin_distance"]
if "enabled" in nh_info.keys():
@@ -174,4 +174,5 @@ class Static_routesFacts(object):
nh_info = None
if nh_info is not None:
nh_list.append(nh_info)
+ nh_info = {}
return nh_list
diff --git a/plugins/module_utils/network/vyos/facts/vrf/__init__.py b/plugins/module_utils/network/vyos/facts/vrf/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/vrf/__init__.py
diff --git a/plugins/module_utils/network/vyos/facts/vrf/vrf.py b/plugins/module_utils/network/vyos/facts/vrf/vrf.py
new file mode 100644
index 00000000..6c7b8918
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/vrf/vrf.py
@@ -0,0 +1,227 @@
+# -*- 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 vrf 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.vrf.vrf import VrfArgs
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_global.bgp_global import (
+ Bgp_globalFacts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv2.ospfv2 import (
+ Ospfv2Facts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3 import (
+ Ospfv3Facts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes import (
+ Static_routesFacts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrf import (
+ VrfTemplate,
+)
+
+
+class VrfFacts(object):
+ """The vyos vrf facts class"""
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = VrfArgs.argument_spec
+
+ def get_config(self, connection):
+ return connection.get("show configuration commands | match 'set vrf'")
+
+ def get_config_set(self, data, connection):
+ """To classify the configurations beased on vrf"""
+ config_dict = {}
+ for config_line in data.splitlines():
+ vrf_inst = re.search(r"set vrf name (\S+).*", config_line)
+ vrf_bta = re.search(r"set vrf bind-to-all", config_line)
+ if vrf_bta:
+ config_dict["bind_to_all"] = config_dict.get("bind_to_all", "") + config_line + "\n"
+ if vrf_inst:
+ config_dict[vrf_inst.group(1)] = (
+ config_dict.get(vrf_inst.group(1), "") + config_line + "\n"
+ )
+ return list(config_dict.values())
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Vrf network resource
+
+ :param connection: the device connection
+ :param ansible_facts: Facts dictionary
+ :param data: previously collected conf
+
+ :rtype: dictionary
+ :returns: facts
+ """
+ facts = {}
+ objs = []
+
+ if not data:
+ data = self.get_config(connection)
+
+ vrf_facts = {}
+ instances = []
+ vrf_parser = VrfTemplate(lines=[], module=self._module)
+ resources = self.get_config_set(data, connection)
+
+ for resource in resources:
+ vrf_parser = VrfTemplate(
+ lines=resource.split("\n"),
+ module=self._module,
+ )
+ objs = vrf_parser.parse()
+
+ if objs and "protocols" in resource:
+
+ protocol_lines = []
+ for line in resource.strip().split("\n"):
+ if "protocols" in line:
+ idx = line.index("protocols")
+ protocol_lines.append("set " + line[idx:])
+ objs["protocols"] = self._parse_protocols("\n".join(protocol_lines))
+
+ if objs:
+ if "bind_to_all" in objs:
+ vrf_facts.update(objs)
+ if "name" in objs:
+ instances.append(self._normalise_instance(objs))
+
+ if instances:
+ vrf_facts.update({"instances": instances})
+
+ ansible_facts["ansible_network_resources"].pop("vrf_facts", None)
+ facts = {"vrf": []}
+
+ params = utils.remove_empties(
+ vrf_parser.validate_config(
+ self.argument_spec,
+ {"config": vrf_facts},
+ redact=True,
+ ),
+ )
+
+ if not resources:
+ params["config"].pop("bind_to_all", None)
+
+ if params.get("config"):
+ facts["vrf"] = params["config"]
+ ansible_facts["ansible_network_resources"].update(facts)
+ return ansible_facts
+
+ def _normalise_instance(self, instance):
+ n_inst = instance.copy()
+ af_map = {}
+
+ for af in instance.get("address_family", []):
+ afi = af.get("afi")
+ if not afi:
+ continue
+
+ if afi not in af_map:
+ af_map[afi] = {"afi": afi}
+
+ for k, v in af.items():
+ if k == "afi":
+ continue
+ elif k == "route_maps":
+ if "route_maps" not in af_map[afi]:
+ af_map[afi]["route_maps"] = []
+ af_map[afi]["route_maps"].extend(v)
+ else:
+ af_map[afi][k] = v
+
+ for afi_data in af_map.values():
+ if "route_maps" in afi_data:
+ seen = []
+ deduped = []
+ for item in afi_data["route_maps"]:
+ if item not in seen:
+ seen.append(item)
+ deduped.append(item)
+ afi_data["route_maps"] = deduped
+
+ n_inst["address_family"] = list(af_map.values())
+ return n_inst
+
+ def _parse_protocols(self, protocols):
+ """Parse protocols and return a dictionary"""
+
+ protocol_chunks = {}
+ parsed_protocols = {}
+
+ for line in protocols.split("\n"):
+ parts = line.split()
+ if len(parts) > 2 and parts[0] == "set" and parts[1] == "protocols":
+ protocol = parts[2]
+ protocol_chunks.setdefault(protocol, []).append(line)
+
+ protocol_strings = {proto: "\n".join(lines) for proto, lines in protocol_chunks.items()}
+
+ for protocol_name, protocol_string in protocol_strings.items():
+ protocol_dict = {}
+
+ if protocol_name == "bgp":
+ bgp_module = Bgp_globalFacts(self._module)
+ protocol_dict = bgp_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+
+ elif protocol_name == "ospf":
+ ospf_module = Ospfv2Facts(self._module)
+ protocol_dict = ospf_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+
+ elif protocol_name == "ospfv3":
+ ospfv3_module = Ospfv3Facts(self._module)
+ protocol_dict = ospfv3_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+
+ elif protocol_name == "static":
+ static_routes_module = Static_routesFacts(self._module)
+ protocol_dict = static_routes_module.populate_facts(
+ connection=self._module._connection,
+ ansible_facts={"ansible_network_resources": {}},
+ data=protocol_string,
+ )
+ parsed_protocols[protocol_name] = list(
+ protocol_dict.get("ansible_network_resources").values(),
+ )[0]
+ else:
+ self._module.fail_json(msg="The protocol is not supported" + protocol_name)
+
+ return parsed_protocols
diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py b/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py
index f8f86cd2..fccfc9c2 100644
--- a/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py
+++ b/plugins/module_utils/network/vyos/rm_templates/bgp_address_family.py
@@ -293,8 +293,8 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+aggregate-address
\s+(?P<address>\S+)
- \s*(?P<as_set>as-set)*
- \s*(?P<summary_only>summary-only)*
+ \s*(?P<as_set>as-set)?
+ \s*(?P<summary_only>summary-only)?
$""",
re.VERBOSE,
),
@@ -397,8 +397,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+network
\s+(?P<address>\S+)
\s+path-limit
- \s+(?P<limit>\S+)
- *$""",
+ \s+(?P<limit>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_network,
@@ -432,8 +431,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+network
\s+(?P<address>\S+)
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_network,
@@ -499,8 +497,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+redistribute
\s+(?P<proto>\S+)
\s+metric
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_redistribute,
@@ -534,8 +531,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+redistribute
\s+(?P<proto>\S+)
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_redistribute,
@@ -568,8 +564,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+redistribute
\s+table
- \s+(?P<tab>\S+)
- *$""",
+ \s+(?P<tab>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_redistribute,
@@ -659,8 +654,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+allowas-in
\s+number
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -877,8 +871,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+capability
\s+prefix-list
- \s+(?P<orf>\S+)
- *$""",
+ \s+(?P<orf>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -915,8 +908,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+default-originate
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -992,8 +984,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+prefix-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor_prefix_list,
@@ -1033,8 +1024,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+filter-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor_filter_list,
@@ -1073,8 +1063,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+maximum-prefix
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -1176,8 +1165,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+peer-group
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -1246,8 +1234,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+route-map
\s+(?P<action>export|import)
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor_route_map,
@@ -1389,8 +1376,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+unsuppress-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -1424,8 +1410,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+weight
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_address_family_14.py b/plugins/module_utils/network/vyos/rm_templates/bgp_address_family_14.py
index fd4c9de9..09cd41a7 100644
--- a/plugins/module_utils/network/vyos/rm_templates/bgp_address_family_14.py
+++ b/plugins/module_utils/network/vyos/rm_templates/bgp_address_family_14.py
@@ -309,8 +309,8 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+aggregate-address
\s+(?P<address>\S+)
- \s*(?P<as_set>as-set)*
- \s*(?P<summary_only>summary-only)*
+ \s*(?P<as_set>as-set)?
+ \s*(?P<summary_only>summary-only)?
$""",
re.VERBOSE,
),
@@ -410,8 +410,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+network
\s+(?P<address>\S+)
\s+path-limit
- \s+(?P<limit>\S+)
- *$""",
+ \s+(?P<limit>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_network,
@@ -444,8 +443,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+network
\s+(?P<address>\S+)
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_network,
@@ -508,8 +506,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+redistribute
\s+(?P<proto>\S+)
- \s+metric\s+(?P<val>\S+)
- *$""",
+ \s+metric\s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_redistribute,
@@ -542,8 +539,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+redistribute
\s+(?P<proto>\S+)
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_redistribute,
@@ -575,8 +571,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+redistribute
\s+table
- \s+(?P<tab>\S+)
- *$""",
+ \s+(?P<tab>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_redistribute,
@@ -663,8 +658,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+allowas-in
\s+number
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -875,8 +869,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+capability
\s+prefix-list
- \s+(?P<orf>\S+)
- *$""",
+ \s+(?P<orf>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -912,8 +905,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+default-originate
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -987,8 +979,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+prefix-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor_prefix_list,
@@ -1027,8 +1018,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+filter-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor_filter_list,
@@ -1066,8 +1056,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+maximum-prefix
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -1166,8 +1155,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+peer-group
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -1234,8 +1222,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+(?P<afi>\S+)-unicast
\s+route-map
\s+(?P<action>export|import)
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor_route_map,
@@ -1373,8 +1360,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+unsuppress-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
@@ -1407,8 +1393,7 @@ class Bgp_address_familyTemplate14(NetworkTemplate):
\s+address-family
\s+(?P<afi>\S+)-unicast
\s+weight
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_af_neighbor,
diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_global.py b/plugins/module_utils/network/vyos/rm_templates/bgp_global.py
index 621f65ea..03f6265b 100644
--- a/plugins/module_utils/network/vyos/rm_templates/bgp_global.py
+++ b/plugins/module_utils/network/vyos/rm_templates/bgp_global.py
@@ -17,7 +17,6 @@ the given network resource.
import re
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
@@ -26,7 +25,7 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.r
def _tmplt_bgp_params_confederation(config_data):
command = []
for list_el in config_data["bgp_params"]["confederation"]:
- for k, v in iteritems(list_el):
+ for k, v in list_el.items():
command.append(
"protocols bgp {as_number} parameters confederation ".format(**config_data)
+ k
@@ -65,7 +64,7 @@ def _tmplt_bgp_params_default(config_data):
def _tmplt_bgp_neighbor_timers(config_data):
command = []
- for k, v in iteritems(config_data["neighbor"]["timers"]):
+ for k, v in config_data["neighbor"]["timers"].items():
command.append(
"protocols bgp {as_number} neighbor ".format(**config_data)
+ config_data["neighbor"]["address"]
@@ -80,7 +79,7 @@ def _tmplt_bgp_neighbor_timers(config_data):
def _tmplt_bgp_timers(config_data):
command = []
- for k, v in iteritems(config_data["timers"]):
+ for k, v in config_data["timers"].items():
command.append(
"protocols bgp {as_number} ".format(**config_data) + "timers " + k + " " + str(v),
)
@@ -238,8 +237,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+advertisement-interval
- \s+(?P<interval>\S+)
- *$""",
+ \s+(?P<interval>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} advertisement-interval {{ neighbor.advertisement_interval }}",
@@ -438,8 +436,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+capability
\s+orf
\s+prefix-list
- \s+(?P<orf>\S+)
- *$""",
+ \s+(?P<orf>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} capability orf prefix-list {{ neighbor.capability.orf }}",
@@ -468,8 +465,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<address>\S+)
\s+default-originate
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} default-originate route-map {{ neighbor.default_originate }}",
@@ -495,8 +491,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+description
- \s+(?P<desc>\S+)
- *$""",
+ \s+(?P<desc>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} description {{ neighbor.description }}",
@@ -574,8 +569,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+disable-send-community
- \s+(?P<comm>\S+)
- *$""",
+ \s+(?P<comm>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-send-community {{ neighbor.disable_send_community }}",
@@ -634,8 +628,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+ebgp-multihop
- \s+(?P<hop>\S+)
- *$""",
+ \s+(?P<hop>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} ebgp-multihop {{ neighbor.ebgp_multihop }}",
@@ -662,8 +655,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<address>\S+)
\s+filter-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_filter_list,
@@ -722,8 +714,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+maximum-prefix
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} maximum-prefix {{ neighbor.maximum_prefix }}",
@@ -827,8 +818,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+password
- \s+(?P<pwd>\S+)
- *$""",
+ \s+(?P<pwd>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} password {{ neighbor.password }}",
@@ -854,8 +844,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+peer-group
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} peer-group {{ neighbor.peer_group_name }}",
@@ -881,8 +870,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+port
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} port {{ neighbor.port }}",
@@ -909,8 +897,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<address>\S+)
\s+prefix-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_prefix_list,
@@ -941,8 +928,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+remote-as
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} remote-as {{ neighbor.remote_as }}",
@@ -995,8 +981,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<address>\S+)
\s+route-map
\s+(?P<action>export|import)
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_route_map,
@@ -1158,8 +1143,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+unsuppress-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} unsuppress-map {{ neighbor.unsuppress_map }}",
@@ -1185,8 +1169,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+update-source
- \s+(?P<src>\S+)
- *$""",
+ \s+(?P<src>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} update-source {{ neighbor.update_source }}",
@@ -1212,8 +1195,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+weight
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} weight {{ neighbor.weight }}",
@@ -1239,8 +1221,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+ttl-security
- \s+(?P<ttl>\S+)
- *$""",
+ \s+(?P<ttl>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} ttl-security {{ neighbor.ttl_security }}",
@@ -1267,8 +1248,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<address>\S+)
\s+timers
\s+(?P<type>connect|holdtime|keepalive)
- \s+(?P<sec>\S+)
- *$""",
+ \s+(?P<sec>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_timers,
@@ -1296,8 +1276,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<as_num>\d+)
\s+timers
\s+(?P<type>\S+)
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_timers,
@@ -1419,8 +1398,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<as_num>\d+)
\s+parameters
\s+cluster-id
- \s+(?P<id>\S+)
- *$""",
+ \s+(?P<id>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters cluster-id {{ bgp_params.cluster_id }}",
@@ -1443,8 +1421,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+parameters
\s+confederation
\s+(?P<type>identifier|peers)
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_params_confederation,
@@ -1472,8 +1449,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+parameters
\s+dampening
\s+half-life
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters dampening half-life {{ bgp_params.dampening.half_life}}",
@@ -1498,8 +1474,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+parameters
\s+dampening
\s+max-suppress-time
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters dampening max-suppress-time {{ bgp_params.dampening.max_suppress_time}}",
@@ -1524,8 +1499,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+parameters
\s+dampening
\s+re-use
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters dampening re-use {{ bgp_params.dampening.re_use}}",
@@ -1550,8 +1524,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+parameters
\s+dampening
\s+start-suppress-time
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters dampening start-suppress-time {{ bgp_params.dampening.start_suppress_time}}",
@@ -1575,9 +1548,8 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<as_num>\d+)
\s+parameters
\s+default
- \s*(?P<no_ipv4_unicast>no-ipv4-unicast)*
- \s*(?P<local_pref>local-pref\s\S+)
- *$""",
+ \s*(?P<no_ipv4_unicast>no-ipv4-unicast)?
+ \s*(?P<local_pref>local-pref\s\S+)?\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_params_default,
@@ -1649,8 +1621,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+distance\sprefix
\s+(?P<prefix>\S+)
\s+distance
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters distance prefix {{ bgp_params.distance.prefix }} distance {{ bgp_params.distance.value }}",
@@ -1679,8 +1650,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+parameters
\s+distance\sglobal
\s+(?P<type>\S+)
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_params_distance,
@@ -1730,8 +1700,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<as_num>\d+)
\s+parameters
\s+graceful-restart\s+stalepath-time
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters graceful-restart stalepath-time {{ bgp_params.graceful_restart }}",
@@ -1819,8 +1788,7 @@ class Bgp_globalTemplate(NetworkTemplate):
\s+(?P<as_num>\d+)
\s+parameters
\s+router-id
- \s+(?P<id>\S+)
- *$""",
+ \s+(?P<id>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp {{ as_number }} parameters router-id {{ bgp_params.router_id }}",
diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_global_14.py b/plugins/module_utils/network/vyos/rm_templates/bgp_global_14.py
index b8beb923..cbe21e3a 100644
--- a/plugins/module_utils/network/vyos/rm_templates/bgp_global_14.py
+++ b/plugins/module_utils/network/vyos/rm_templates/bgp_global_14.py
@@ -17,7 +17,6 @@ the given network resource.
import re
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
@@ -26,12 +25,9 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.r
def _tmplt_bgp_params_confederation(config_data):
command = []
for list_el in config_data["bgp_params"]["confederation"]:
- for k, v in iteritems(list_el):
+ for k, v in list_el.items():
command.append(
- "protocols bgp parameters confederation ".format(**config_data)
- + k
- + " "
- + str(v),
+ "protocols bgp parameters confederation ".format(**config_data) + k + " " + str(v),
)
return command
@@ -65,7 +61,7 @@ def _tmplt_bgp_params_default(config_data):
def _tmplt_bgp_neighbor_timers(config_data):
command = []
- for k, v in iteritems(config_data["neighbor"]["timers"]):
+ for k, v in config_data["neighbor"]["timers"].items():
command.append(
"protocols bgp neighbor ".format(**config_data)
+ config_data["neighbor"]["address"]
@@ -80,7 +76,7 @@ def _tmplt_bgp_neighbor_timers(config_data):
def _tmplt_bgp_timers(config_data):
command = []
- for k, v in iteritems(config_data["timers"]):
+ for k, v in config_data["timers"].items():
command.append(
"protocols bgp ".format(**config_data) + "timers " + k + " " + str(v),
)
@@ -238,8 +234,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+advertisement-interval
- \s+(?P<interval>\S+)
- *$""",
+ \s+(?P<interval>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} advertisement-interval {{ neighbor.advertisement_interval }}",
@@ -431,8 +426,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+capability
\s+orf
\s+prefix-list
- \s+(?P<orf>\S+)
- *$""",
+ \s+(?P<orf>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} capability orf prefix-list {{ neighbor.capability.orf }}",
@@ -460,8 +454,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+(?P<address>\S+)
\s+default-originate
\s+route-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} default-originate route-map {{ neighbor.default_originate }}",
@@ -486,8 +479,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+description
- \s+(?P<desc>\S+)
- *$""",
+ \s+(?P<desc>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} description {{ neighbor.description }}",
@@ -562,8 +554,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+disable-send-community
- \s+(?P<comm>\S+)
- *$""",
+ \s+(?P<comm>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} disable-send-community {{ neighbor.disable_send_community }}",
@@ -620,8 +611,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+ebgp-multihop
- \s+(?P<hop>\S+)
- *$""",
+ \s+(?P<hop>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} ebgp-multihop {{ neighbor.ebgp_multihop }}",
@@ -647,8 +637,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+(?P<address>\S+)
\s+filter-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_filter_list,
@@ -705,8 +694,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+maximum-prefix
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} maximum-prefix {{ neighbor.maximum_prefix }}",
@@ -806,8 +794,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+password
- \s+(?P<pwd>\S+)
- *$""",
+ \s+(?P<pwd>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} password {{ neighbor.password }}",
@@ -832,8 +819,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+peer-group
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} peer-group {{ neighbor.peer_group_name }}",
@@ -858,8 +844,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+port
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} port {{ neighbor.port }}",
@@ -885,8 +870,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+(?P<address>\S+)
\s+prefix-list
\s+(?P<action>export|import)
- \s+(?P<list>\S+)
- *$""",
+ \s+(?P<list>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_prefix_list,
@@ -916,8 +900,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+remote-as
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} remote-as {{ neighbor.remote_as }}",
@@ -968,8 +951,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+(?P<address>\S+)
\s+route-map
\s+(?P<action>export|import)
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_route_map,
@@ -1125,8 +1107,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+unsuppress-map
- \s+(?P<map>\S+)
- *$""",
+ \s+(?P<map>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} unsuppress-map {{ neighbor.unsuppress_map }}",
@@ -1151,8 +1132,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+update-source
- \s+(?P<src>\S+)
- *$""",
+ \s+(?P<src>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} update-source {{ neighbor.update_source }}",
@@ -1177,8 +1157,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+weight
- \s+(?P<num>\S+)
- *$""",
+ \s+(?P<num>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} weight {{ neighbor.weight }}",
@@ -1203,8 +1182,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+neighbor
\s+(?P<address>\S+)
\s+ttl-security
- \s+(?P<ttl>\S+)
- *$""",
+ \s+(?P<ttl>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp neighbor {{ neighbor.address }} ttl-security {{ neighbor.ttl_security }}",
@@ -1230,8 +1208,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+(?P<address>\S+)
\s+timers
\s+(?P<type>connect|holdtime|keepalive)
- \s+(?P<sec>\S+)
- *$""",
+ \s+(?P<sec>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_neighbor_timers,
@@ -1258,8 +1235,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+bgp
\s+timers
\s+(?P<type>\S+)
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_timers,
@@ -1376,8 +1352,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+bgp
\s+parameters
\s+cluster-id
- \s+(?P<id>\S+)
- *$""",
+ \s+(?P<id>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters cluster-id {{ bgp_params.cluster_id }}",
@@ -1399,8 +1374,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+parameters
\s+confederation
\s+(?P<type>identifier|peers)
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_params_confederation,
@@ -1427,8 +1401,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+parameters
\s+dampening
\s+half-life
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters dampening half-life {{ bgp_params.dampening.half_life}}",
@@ -1452,8 +1425,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+parameters
\s+dampening
\s+max-suppress-time
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters dampening max-suppress-time {{ bgp_params.dampening.max_suppress_time}}",
@@ -1477,8 +1449,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+parameters
\s+dampening
\s+re-use
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters dampening re-use {{ bgp_params.dampening.re_use}}",
@@ -1502,8 +1473,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+parameters
\s+dampening
\s+start-suppress-time
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters dampening start-suppress-time {{ bgp_params.dampening.start_suppress_time}}",
@@ -1526,9 +1496,8 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+bgp
\s+parameters
\s+default
- \s*(?P<no_ipv4_unicast>no-ipv4-unicast)*
- \s*(?P<local_pref>local-pref\s\S+)
- *$""",
+ \s*(?P<no_ipv4_unicast>no-ipv4-unicast)?
+ \s*(?P<local_pref>local-pref\s\S+)?\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_params_default,
@@ -1597,8 +1566,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+distance\sprefix
\s+(?P<prefix>\S+)
\s+distance
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters distance prefix {{ bgp_params.distance.prefix }} distance {{ bgp_params.distance.value }}",
@@ -1626,8 +1594,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+parameters
\s+distance\sglobal
\s+(?P<type>\S+)
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_bgp_params_distance,
@@ -1675,8 +1642,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+bgp
\s+parameters
\s+graceful-restart\s+stalepath-time
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters graceful-restart stalepath-time {{ bgp_params.graceful_restart }}",
@@ -1760,8 +1726,7 @@ class Bgp_globalTemplate14(NetworkTemplate):
\s+bgp
\s+parameters
\s+router-id
- \s+(?P<id>\S+)
- *$""",
+ \s+(?P<id>\S+)\s*$""",
re.VERBOSE,
),
"setval": "protocols bgp parameters router-id {{ bgp_params.router_id }}",
diff --git a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py
index 134effca..af04da3b 100644
--- a/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py
+++ b/plugins/module_utils/network/vyos/rm_templates/ospf_interfaces.py
@@ -365,8 +365,7 @@ class Ospf_interfacesTemplate(NetworkTemplate):
\s+(?P<proto>ospf|ospfv3)
\s+authentication
\s+plaintext-password
- \s+(?P<text>\S+)
- *$""",
+ \s+(?P<text>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_ospf_int_auth_password,
@@ -399,8 +398,7 @@ class Ospf_interfacesTemplate(NetworkTemplate):
\s+key-id
\s+(?P<id>\d+)
\s+md5-key
- \s+(?P<text>\S+)
- *$""",
+ \s+(?P<text>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_ospf_int_auth_md5,
@@ -572,8 +570,7 @@ class Ospf_interfacesTemplate(NetworkTemplate):
\s+(?P<afi>ip|ipv6)
\s+(?P<proto>ospf|ospfv3)
\s+network
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_ospf_int_network,
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..484d7c44 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
@@ -5,6 +5,7 @@
from __future__ import absolute_import, division, print_function
+
__metaclass__ = type
"""
@@ -239,8 +240,7 @@ class Ospf_interfacesTemplate14(NetworkTemplate):
\s+protocols
\s+(?P<proto>ospf|ospfv3)
\s+interface
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"remval": _tmplt_ospf_int_delete,
@@ -265,8 +265,7 @@ class Ospf_interfacesTemplate14(NetworkTemplate):
\s+(?P<name>\S+)
\s+authentication
\s+plaintext-password
- \s+(?P<text>\S+)
- *$""",
+ \s+(?P<text>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_ospf_int_auth_password,
@@ -297,8 +296,7 @@ class Ospf_interfacesTemplate14(NetworkTemplate):
\s+key-id
\s+(?P<id>\d+)
\s+md5-key
- \s+(?P<text>\S+)
- *$""",
+ \s+(?P<text>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_ospf_int_auth_md5,
@@ -458,8 +456,7 @@ class Ospf_interfacesTemplate14(NetworkTemplate):
\s+interface
\s+(?P<name>\S+)
\s+network
- \s+(?P<val>\S+)
- *$""",
+ \s+(?P<val>\S+)\s*$""",
re.VERBOSE,
),
"setval": _tmplt_ospf_int_network,
diff --git a/plugins/module_utils/network/vyos/rm_templates/route_maps.py b/plugins/module_utils/network/vyos/rm_templates/route_maps.py
index 8f218a6b..51d0ea1c 100644
--- a/plugins/module_utils/network/vyos/rm_templates/route_maps.py
+++ b/plugins/module_utils/network/vyos/rm_templates/route_maps.py
@@ -33,8 +33,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "route_map",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\s*$""",
re.VERBOSE,
),
"compval": "route_map",
@@ -51,8 +50,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "sequence",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\s*$""",
re.VERBOSE,
),
"compval": "sequence",
@@ -75,8 +73,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "call",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\scall\s(?P<call>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\scall\s(?P<call>\S+)\s*$""",
re.VERBOSE,
),
"setval": "policy route-map {{route_map}} rule {{sequence}} call {{call}}",
@@ -99,8 +96,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "description",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sdescription\s(?P<description>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sdescription\s(?P<description>\S+)\s*$""",
re.VERBOSE,
),
"setval": "policy route-map {{route_map}} rule {{sequence}} description {{description}}",
@@ -123,8 +119,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "action",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\saction\s(?P<action>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\saction\s(?P<action>\S+)\s*$""",
re.VERBOSE,
),
"setval": "policy route-map {{route_map}} rule {{sequence}} action {{action}}",
@@ -147,8 +142,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "continue_sequence",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\scontinue\s(?P<continue>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\scontinue\s(?P<continue>\S+)\s*$""",
re.VERBOSE,
),
"setval": "policy route-map {{route_map}} rule {{sequence}} continue {{continue_sequence}}",
@@ -171,8 +165,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "on_match_next",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\son-match\s(?P<next>next)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\son-match\s(?P<next>next)\s*$""",
re.VERBOSE,
),
"compval": "on_match.next",
@@ -198,8 +191,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "on_match_goto",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\son-match\sgoto\s(?P<goto>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\son-match\sgoto\s(?P<goto>\S+)\s*$""",
re.VERBOSE,
),
"compval": "on_match.goto",
@@ -225,8 +217,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_aggregator_ip",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\saggregator\sip\s(?P<ip>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\saggregator\sip\s(?P<ip>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.aggregator.ip",
@@ -254,8 +245,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_aggregator_as",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\saggregator\sas\s(?P<as>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\saggregator\sas\s(?P<as>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.aggregator.as",
@@ -283,8 +273,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_as_path_exclude",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sas-path-exclude\s(?P<as>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sas-path-exclude\s(?P<as>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.as_path_exclude",
@@ -310,12 +299,12 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_as_path_prepend",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sas-path-prepend\s(?P<as>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sas-path-prepend\s(?P<as>.*)
+ $""",
re.VERBOSE,
),
"compval": "set.as_path_prepend",
- "setval": "policy route-map {{route_map}} rule {{sequence}} set as-path-prepend {{set.as_path_prepend}}",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} set as-path-prepend '{{set.as_path_prepend}}'",
"result": {
"route_maps": {
"{{ route_map }}": {
@@ -337,10 +326,10 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_atomic_aggregate",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\satomic-aggregate(?P<as>)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\s(?P<as>atomic-aggregate)\s*$""",
re.VERBOSE,
),
+ "compval": "set.atomic_aggregate",
"setval": "policy route-map {{route_map}} rule {{sequence}} set atomic-aggregate",
"result": {
"route_maps": {
@@ -363,8 +352,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_bgp_extcommunity_rt",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sbgp-extcommunity-rt\s(?P<bgp>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sbgp-extcommunity-rt\s(?P<bgp>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.bgp_extcommunity_rt",
@@ -391,13 +379,12 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_comm_list",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scomm-list\scomm-list\s(?P<comm_list>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\scommunity-list\s(?P<comm_list>\S+)\s*$""",
re.VERBOSE,
),
- "compval": "set.comm_list.comm_list",
+ "compval": "match.community.community_list",
"setval": "policy route-map {{route_map}} rule {{sequence}} "
- "set comm-list comm-list {{set.comm_list.comm_list}}",
+ "match community community-list {{set.comm_list.comm_list}}",
"result": {
"route_maps": {
"{{ route_map }}": {
@@ -406,8 +393,8 @@ class Route_mapsTemplate(NetworkTemplate):
"{{sequence}}":
{
"sequence": "{{sequence}}",
- "set": {
- "comm_list": {"comm_list": "{{comm_list}}"},
+ "match": {
+ "community": {"community_list": "{{comm_list}}"},
},
},
},
@@ -419,8 +406,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_comm_list_delete",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scomm-list\sdelete(?P<delete>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scomm-list\s(?P<delete>delete)\s*$""",
re.VERBOSE,
),
"compval": "set.comm_list.comm_list",
@@ -447,8 +433,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_extcommunity_rt",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity-rt\s(?P<extcommunity_rt>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity-rt\s(?P<extcommunity_rt>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.extcommunity_rt",
@@ -475,8 +460,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_extcommunity_soo",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity-soo\s(?P<extcommunity_soo>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity-soo\s(?P<extcommunity_soo>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.extcommunity_soo",
@@ -500,11 +484,65 @@ class Route_mapsTemplate(NetworkTemplate):
},
},
{
+ "name": "set_extcommunity_bandwidth",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity\sbandwidth\s(?P<extcommunity_bw>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.extcommunity_bandwidth",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set extcommunity bandwidth {{set.extcommunity_bandwidth}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "extcommunity_bandwidth": "{{extcommunity_bw}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_extcommunity_bandwidth_non_transitive",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)
+ \sset\sextcommunity\s(?P<extcommunity_bw_nt>bandwidth-non-transitive)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.extcommunity_bandwidth_non_transitive",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set extcommunity bandwidth-non-transitive",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "extcommunity_bandwidth_non_transitive": "{{True if extcommunity_bw_nt is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
"name": "set_ip_next_hop",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sip-next-hop\s(?P<ip_next_hop>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sip-next-hop\s(?P<ip_next_hop>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.ip_next_hop",
@@ -533,8 +571,7 @@ class Route_mapsTemplate(NetworkTemplate):
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sipv6-next-hop
\s(?P<type>global|local)
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.ipv6_next_hop",
@@ -564,8 +601,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_large_community",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\slarge-community\s(?P<large_community>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\slarge-community\s(?P<large_community>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.large_community",
@@ -592,8 +628,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_local_preference",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\slocal-preference\s(?P<local_preference>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\slocal-preference\s(?P<local_preference>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.local_preference",
@@ -620,8 +655,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_metric",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\smetric\s(?P<metric>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\smetric\s(?P<metric>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.metric",
@@ -648,8 +682,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_metric_type",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\smetric-type\s(?P<metric_type>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\smetric-type\s(?P<metric_type>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.metric_type",
@@ -676,8 +709,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_origin",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sorigin\s(?P<origin>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sorigin\s(?P<origin>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.origin",
@@ -704,8 +736,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_originator_id",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\soriginator-id\s(?P<originator_id>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\soriginator-id\s(?P<originator_id>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.originator_id",
@@ -732,8 +763,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_src",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\ssrc\s(?P<src>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\ssrc\s(?P<src>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.src",
@@ -760,8 +790,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_tag",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\stag\s(?P<tag>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\stag\s(?P<tag>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.tag",
@@ -788,8 +817,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "set_weight",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sweight\s(?P<weight>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sweight\s(?P<weight>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.weight",
@@ -813,11 +841,37 @@ class Route_mapsTemplate(NetworkTemplate):
},
},
{
+ "name": "set_table",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\stable\s(?P<table>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.weight",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set table {{set.table}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "table": "{{table}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
"name": "set_community",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scommunity\s(?P<value>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scommunity\s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "set.community.value",
@@ -846,8 +900,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_as_path",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sas-path\s(?P<as_path>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sas-path\s(?P<as_path>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.as_path",
@@ -874,8 +927,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_community_community_list",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\scommunity-list\s(?P<community_list>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\scommunity-list\s(?P<community_list>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.community.community_list",
@@ -902,8 +954,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_community_exact_match",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\sexact-match(?P<exact_match>)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\sexact-match(?P<exact_match>)\s*$""",
re.VERBOSE,
),
"compval": "match.community.exact_match",
@@ -930,8 +981,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_extcommunity",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sextcommunity\s(?P<extcommunity>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sextcommunity\s(?P<extcommunity>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.extcommunity",
@@ -958,8 +1008,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_interface",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sinterface\s(?P<interface>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sinterface\s(?P<interface>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.interface",
@@ -986,8 +1035,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_large_community_large_community_list",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\slarge-community\slarge-community-list\s(?P<lc>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\slarge-community\slarge-community-list\s(?P<lc>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.large_community_large_community_list",
@@ -1014,8 +1062,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_metric",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\smetric\s(?P<metric>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\smetric\s(?P<metric>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.metric",
@@ -1042,8 +1089,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_origin",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sorigin\s(?P<origin>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sorigin\s(?P<origin>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.origin",
@@ -1070,8 +1116,7 @@ class Route_mapsTemplate(NetworkTemplate):
"name": "match_peer",
"getval": re.compile(
r"""
- ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\speer\s(?P<peer>\S+)
- *$""",
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\speer\s(?P<peer>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.peer",
@@ -1100,8 +1145,7 @@ class Route_mapsTemplate(NetworkTemplate):
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sip\saddress
\s(?P<list_type>access-list|prefix-list)
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.ip.address",
@@ -1134,8 +1178,7 @@ class Route_mapsTemplate(NetworkTemplate):
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sip\snexthop
\s(?P<list_type>access-list|prefix-list)
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.ip.next_hop",
@@ -1168,8 +1211,7 @@ class Route_mapsTemplate(NetworkTemplate):
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sip\sroute-source
\s(?P<list_type>access-list|prefix-list)
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.ip.route_source",
@@ -1202,8 +1244,7 @@ class Route_mapsTemplate(NetworkTemplate):
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sipv6\saddress
\s(?P<list_type>access-list|prefix-list)
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.ipv6.address",
@@ -1235,8 +1276,7 @@ class Route_mapsTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sipv6\snexthop
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.ipv6.next_hop",
@@ -1261,12 +1301,37 @@ class Route_mapsTemplate(NetworkTemplate):
},
},
{
+ "name": "match_protocol",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sprotocol\s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.protocol",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match protocol {{match.protocol}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "protocol": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
"name": "match_rpki",
"getval": re.compile(
r"""
^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\srpki
- \s(?P<value>\S+)
- *$""",
+ \s(?P<value>\S+)\s*$""",
re.VERBOSE,
),
"compval": "match.rpki",
diff --git a/plugins/module_utils/network/vyos/rm_templates/route_maps_14.py b/plugins/module_utils/network/vyos/rm_templates/route_maps_14.py
new file mode 100644
index 00000000..ea61a555
--- /dev/null
+++ b/plugins/module_utils/network/vyos/rm_templates/route_maps_14.py
@@ -0,0 +1,1364 @@
+# -*- 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 Route_maps 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,
+)
+
+
+class Route_mapsTemplate14(NetworkTemplate):
+ def __init__(self, lines=None):
+ prefix = {"set": "set", "remove": "delete"}
+ super(Route_mapsTemplate14, self).__init__(lines=lines, tmplt=self, prefix=prefix)
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "route_map",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "route_map",
+ "setval": "policy route-map {{route_map}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ },
+ },
+ },
+ },
+ {
+ "name": "sequence",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "compval": "sequence",
+ "setval": "policy route-map {{route_map}} rule {{sequence}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "call",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\scall\s(?P<call>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "setval": "policy route-map {{route_map}} rule {{sequence}} call {{call}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "call": "{{call}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "description",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sdescription\s(?P<description>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "setval": "policy route-map {{route_map}} rule {{sequence}} description {{description}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "description": "{{description}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "action",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\saction\s(?P<action>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "setval": "policy route-map {{route_map}} rule {{sequence}} action {{action}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "action": "{{action}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "continue_sequence",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\scontinue\s(?P<continue>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "setval": "policy route-map {{route_map}} rule {{sequence}} continue {{continue_sequence}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "continue_sequence": "{{continue}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "on_match_next",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\son-match\s(?P<next>next)
+ *$""",
+ re.VERBOSE,
+ ),
+ "compval": "on_match.next",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} on-match next",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "on_match": {
+ "next": "{{True if next is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "on_match_goto",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\son-match\sgoto\s(?P<goto>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "on_match.goto",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} on-match goto {{on_match.goto}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "on_match": {
+ "goto": "{{goto}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_aggregator_ip",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\saggregator\sip\s(?P<ip>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.aggregator.ip",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} set aggregator ip {{set.aggregator.ip}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "aggregator": {
+ "ip": "{{ip}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_aggregator_as",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\saggregator\sas\s(?P<as>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.aggregator.as",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} set aggregator as {{set.aggregator.as}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "aggregator": {
+ "as": "{{as}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_as_path_exclude",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sas-path\sexclude\s(?P<as>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.as_path_exclude",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} set as-path exclude {{set.as_path_exclude}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "as_path_exclude": "{{as}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_as_path_prepend",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sas-path\sprepend\s(?P<as>.*)
+ $""",
+ re.VERBOSE,
+ ),
+ "compval": "set.as_path_prepend",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} set as-path prepend '{{set.as_path_prepend}}'",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "as_path_prepend": "{{as}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_atomic_aggregate",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\s(?P<as>atomic-aggregate)
+ *$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.atomic_aggregate",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} set atomic-aggregate",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "atomic_aggregate": "{{True if as is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_bgp_extcommunity_rt",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sbgp-extcommunity-rt\s(?P<bgp>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.bgp_extcommunity_rt",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set bgp-extcommunity-rt {{set.bgp_extcommunity_rt}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "bgp_extcommunity_rt": "{{bgp}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_comm_list",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\scommunity-list\s(?P<comm_list>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.community.community_list",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match community community-list {{set.comm_list.comm_list}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "community": {"community_list": "{{comm_list}}"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_comm_list_delete",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scomm-list\s(?P<delete>delete)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.comm_list.comm_list",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set comm-list delete",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "comm_list": {"delete": "{{True if delete is defined}}"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_extcommunity_rt",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity\srt\s(?P<extcommunity_rt>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.extcommunity_rt",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set extcommunity rt {{set.extcommunity_rt}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "extcommunity_rt": "{{extcommunity_rt}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_extcommunity_soo",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity\ssoo\s(?P<extcommunity_soo>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.extcommunity_soo",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set extcommunity soo {{set.extcommunity_soo}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "extcommunity_soo": "{{extcommunity_soo}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_extcommunity_bandwidth",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity\sbandwidth\s(?P<extcommunity_bw>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.extcommunity_bandwidth",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set extcommunity bandwidth {{set.extcommunity_bandwidth}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "extcommunity_bandwidth": "{{extcommunity_bw}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_extcommunity_bandwidth_non_transitive",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sextcommunity\s(?P<extcommunity_bw_nt>bandwidth-non-transitive)
+ *$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.extcommunity_bandwidth_non_transitive",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set extcommunity bandwidth-non-transitive",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "extcommunity_bandwidth_non_transitive": "{{True if extcommunity_bw_nt is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_ip_next_hop",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sip-next-hop\s(?P<ip_next_hop>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.ip_next_hop",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set ip-next-hop {{set.ip_next_hop}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "ip_next_hop": "{{ip_next_hop}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_ipv6_next_hop",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sipv6-next-hop
+ \s(?P<type>global|local)
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.ipv6_next_hop",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set ipv6-next-hop {{set.ipv6_next_hop.ip_type}} {{set.ipv6_next_hop.value}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "ipv6_next_hop": {
+ "ip_type": "{{type}}",
+ "value": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_large_community",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\slarge-community\s(?P<op>none|replace\s(?P<large_community>\S+))
+ $""",
+ re.VERBOSE,
+ ),
+ "compval": "set.large_community",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set large-community {{set.large_community if set.large_community == 'none' else 'replace ' + set.large_community}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "large_community": "{{op if op == 'none' else large_community}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_local_preference",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\slocal-preference\s(?P<local_preference>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.local_preference",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set local-preference {{set.local_preference}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "local_preference": "{{local_preference}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_metric",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\smetric\s(?P<metric>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.metric",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set metric {{set.metric}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "metric": "{{metric}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_metric_type",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\smetric-type\s(?P<metric_type>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.metric_type",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set metric-type {{set.metric_type}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "metric_type": "{{metric_type}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_origin",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sorigin\s(?P<origin>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.origin",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set origin {{set.origin}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "origin": "{{origin}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_originator_id",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\soriginator-id\s(?P<originator_id>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.originator_id",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set originator-id {{set.originator_id}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "originator_id": "{{originator_id}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_src",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\ssrc\s(?P<src>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.src",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set src {{set.src}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "src": "{{src}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_tag",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\stag\s(?P<tag>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.tag",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set tag {{set.tag}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "tag": "{{tag}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_weight",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\sweight\s(?P<weight>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.weight",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set weight {{set.weight}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "weight": "{{weight}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_table",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\stable\s(?P<table>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "set.weight",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set table {{set.table}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "table": "{{table}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "set_community",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\sset\scommunity\s(?P<op>none|replace\s(?P<value>\S+))
+ $""",
+ re.VERBOSE,
+ ),
+ "compval": "set.community.value",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "set community {{set.community.value if set.community.value == 'none' else 'replace ' + set.community.value}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "set": {
+ "community": {
+ "value": "{{op if op == 'none' else value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_as_path",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sas-path\s(?P<as_path>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.as_path",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match as-path {{match.as_path}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "as_path": "{{as_path}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_community_community_list",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\scommunity-list\s(?P<community_list>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.community.community_list",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match community community-list {{match.community.community_list}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "community": {"community_list": "{{community_list}}"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_community_exact_match",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\scommunity\sexact-match(?P<exact_match>)
+ *$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.community.exact_match",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match community exact-match",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "community": {"exact_match": "{{True if exact_match is defined}}"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_extcommunity",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sextcommunity\s(?P<extcommunity>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.extcommunity",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match extcommunity {{match.extcommunity}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "extcommunity": "{{extcommunity}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_interface",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sinterface\s(?P<interface>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.interface",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match interface {{match.interface}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "interface": "{{interface}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_large_community_large_community_list",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\slarge-community\slarge-community-list\s(?P<lc>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.large_community_large_community_list",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match large-community large-community-list {{match.large_community_large_community_list}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "large_community_large_community_list": "{{lc}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_metric",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\smetric\s(?P<metric>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.metric",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match metric {{match.metric}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "metric": "{{metric}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_origin",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sorigin\s(?P<origin>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.origin",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match origin {{match.origin}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "origin": "{{origin}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_peer",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\speer\s(?P<peer>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.peer",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match peer {{match.peer}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}":
+ {
+ "sequence": "{{sequence}}",
+ "match": {
+ "peer": "{{peer}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_ip_address",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sip\saddress
+ \s(?P<list_type>access-list|prefix-list)
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.ip.address",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match ip address {{match.ip.address.list_type}} {{match.ip.address.value}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "ip": {
+ "address": {
+ "list_type": "{{list_type}}",
+ "value": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_ip_next_hop",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sip\snexthop
+ \s(?P<list_type>access-list|prefix-list)
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.ip.next_hop",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match ip nexthop {{match.ip.next_hop.list_type}} {{match.ip.next_hop.value}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "ip": {
+ "next_hop": {
+ "list_type": "{{list_type}}",
+ "value": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_ip_route_source",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sip\sroute-source
+ \s(?P<list_type>access-list|prefix-list)
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.ip.route_source",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match ip route-source {{match.ip.route_source.list_type}} {{match.ip.route_source.value}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "ip": {
+ "route_source": {
+ "list_type": "{{list_type}}",
+ "value": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_ipv6_address",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sipv6\saddress
+ \s(?P<list_type>access-list|prefix-list)
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.ipv6.address",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match ipv6 address {{match.ipv6.address.list_type}} {{match.ipv6.address.value}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "ipv6": {
+ "address": {
+ "list_type": "{{list_type}}",
+ "value": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_ipv6_nexthop",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sipv6\snexthop
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.ipv6.next_hop",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match ipv6 nexthop {{match.ipv6.next_hop}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "ipv6": {
+ "next_hop": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_protocol",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\sprotocol\s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.protocol",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match protocol {{match.protocol}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "protocol": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "match_rpki",
+ "getval": re.compile(
+ r"""
+ ^set\spolicy\sroute-map\s(?P<route_map>\S+)\srule\s(?P<sequence>\d+)\smatch\srpki
+ \s(?P<value>\S+)\s*$""",
+ re.VERBOSE,
+ ),
+ "compval": "match.rpki",
+ "setval": "policy route-map {{route_map}} rule {{sequence}} "
+ "match rpki {{match.rpki}}",
+ "result": {
+ "route_maps": {
+ "{{ route_map }}": {
+ "route_map": '{{ route_map }}',
+ "entries": {
+ "{{sequence}}": {
+ "sequence": "{{sequence}}",
+ "match": {
+ "rpki": "{{value}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ ]
+ # fmt: on
diff --git a/plugins/module_utils/network/vyos/rm_templates/snmp_server.py b/plugins/module_utils/network/vyos/rm_templates/snmp_server.py
index 71753083..ff1c6465 100644
--- a/plugins/module_utils/network/vyos/rm_templates/snmp_server.py
+++ b/plugins/module_utils/network/vyos/rm_templates/snmp_server.py
@@ -140,9 +140,9 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\scommunity
\s+(?P<name>\S+)
- \s*(?P<auth>authorization\srw|authorization\sro)*
- \s*(client\s(?P<client>\S+))*
- \s*(network\s(?P<network>\S+))*
+ \s*(?P<auth>authorization\srw|authorization\sro)?
+ \s*(client\s(?P<client>\S+))?
+ \s*(network\s(?P<network>\S+))?
$""",
re.VERBOSE,
),
@@ -164,8 +164,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^set\sservice\ssnmp\scontact
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "service snmp contact {{ contact }}",
@@ -179,8 +178,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^set\sservice\ssnmp\sdescription
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "service snmp description {{ description }}",
@@ -195,8 +193,8 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\slisten-address
\s+(?P<addr>\S+)
- \s*(port)*
- \s*(?P<port>\d+)*
+ \s*(port)?
+ \s*(?P<port>\d+)?
$""",
re.VERBOSE,
),
@@ -232,8 +230,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^set\sservice\ssnmp\ssmux-peer
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "service snmp smux-peer {{ smux_peer }}",
@@ -247,8 +244,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^set\sservice\ssnmp\strap-source
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "service snmp trap-source {{ trap_source }}",
@@ -263,9 +259,8 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\strap-target
\s+(?P<name>\S+)
- \s*(?P<comm>community\s\S+)*
- \s*(?P<port>port\s\d+)*
- $""",
+ \s*(?P<comm>community\s\S+)?
+ \s*(?P<port>port\s\d+)? $""",
re.VERBOSE,
),
"setval": _tmplt_snmp_server_trap_target,
@@ -283,8 +278,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^set\sservice\ssnmp\sv3\sengineid
- \s+(?P<name>\S+)
- *$""",
+ \s+(?P<name>\S+)\s*$""",
re.VERBOSE,
),
"setval": "service snmp v3 engineid {{ snmp_v3.engine_id }}",
@@ -301,9 +295,9 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\sgroup
\s+(?P<name>\S+)
- \s*(?P<mode>mode\s\S+)*
- \s*(?P<sec>seclevel\s\S+)*
- \s*(?P<view>view\s\S+)*
+ \s*(?P<mode>mode\s\S+)?
+ \s*(?P<sec>seclevel\s\S+)?
+ \s*(?P<view>view\s\S+)?
$""",
re.VERBOSE,
),
@@ -329,9 +323,9 @@ class Snmp_serverTemplate(NetworkTemplate):
^set\sservice\ssnmp\sv3\strap-target
\s+(?P<name>\S+)
\s+auth
- \s*(?P<enc>encrypted-password\s\S+)*
- \s*(?P<plain>plaintext-password\s\S+)*
- \s*(?P<type>type\s\S+)*
+ \s*(?P<enc>encrypted-password\s\S+)?
+ \s*(?P<plain>plaintext-password\s\S+)?
+ \s*(?P<type>type\s\S+)?
$""",
re.VERBOSE,
),
@@ -358,8 +352,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\strap-target
\s+(?P<name>\S+)
- \s+(?P<port>port\s\d+)*
- $""",
+ \s+(?P<port>port\s\d+)? $""",
re.VERBOSE,
),
"setval": "service snmp v3 trap-target port {{ snmp_v3.trap_targets.port }}",
@@ -381,7 +374,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\strap-target
\s+(?P<name>\S+)
- \s+(?P<protocol>protocol\s\S+)*
+ \s+(?P<protocol>protocol\s\S+)?
$""",
re.VERBOSE,
),
@@ -404,7 +397,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\strap-target
\s+(?P<name>\S+)
- \s+(?P<type>type\s\S+)*
+ \s+(?P<type>type\s\S+)?
$""",
re.VERBOSE,
),
@@ -427,7 +420,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\strap-target
\s+(?P<name>\S+)
- \s+(?P<user>user\s\S+)*
+ \s+(?P<user>user\s\S+)?
$""",
re.VERBOSE,
),
@@ -451,9 +444,9 @@ class Snmp_serverTemplate(NetworkTemplate):
^set\sservice\ssnmp\sv3\strap-target
\s+(?P<name>\S+)
\s+privacy
- \s*(?P<enc>encrypted-password\s\S+)*
- \s*(?P<plain>plaintext-password\s\S+)*
- \s*(?P<type>type\s\S+)*
+ \s*(?P<enc>encrypted-password\s\S+)?
+ \s*(?P<plain>plaintext-password\s\S+)?
+ \s*(?P<type>type\s\S+)?
$""",
re.VERBOSE,
),
@@ -481,9 +474,9 @@ class Snmp_serverTemplate(NetworkTemplate):
^set\sservice\ssnmp\sv3\suser
\s+(?P<name>\S+)
\s+auth
- \s*(?P<enc>encrypted-password\s\S+)*
- \s*(?P<plain>plaintext-password\s\S+)*
- \s*(?P<type>type\s\S+)*
+ \s*(?P<enc>encrypted-password\s\S+)?
+ \s*(?P<plain>plaintext-password\s\S+)?
+ \s*(?P<type>type\s\S+)?
$""",
re.VERBOSE,
),
@@ -511,9 +504,9 @@ class Snmp_serverTemplate(NetworkTemplate):
^set\sservice\ssnmp\sv3\suser
\s+(?P<name>\S+)
\s+privacy
- \s*(?P<enc>encrypted-password\s\S+)*
- \s*(?P<plain>plaintext-password\s\S+)*
- \s*(?P<type>type\s\S+)*
+ \s*(?P<enc>encrypted-password\s\S+)?
+ \s*(?P<plain>plaintext-password\s\S+)?
+ \s*(?P<type>type\s\S+)?
$""",
re.VERBOSE,
),
@@ -540,8 +533,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\suser
\s+(?P<name>\S+)
- \s+(?P<group>group\s.+)*
- $""",
+ \s+(?P<group>group\s.+)? $""",
re.VERBOSE,
),
"setval": "service snmp v3 user {{ snmp_v3.users.user }} group {{ snmp_v3.users.group }}",
@@ -563,7 +555,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^set\sservice\ssnmp\sv3\suser
\s+(?P<name>\S+)
- \s+(?P<mode>mode\s\S+)*
+ \s+(?P<mode>mode\s\S+)?
$""",
re.VERBOSE,
),
@@ -587,8 +579,8 @@ class Snmp_serverTemplate(NetworkTemplate):
^set\sservice\ssnmp\sv3\sview
\s+(?P<name>\S+)
\s+(?P<oid>oid\s\S+)
- \s*(?P<ex>exclude\s\S+)*
- \s*(?P<mask>mask\s\S+)*
+ \s*(?P<ex>exclude\s\S+)?
+ \s*(?P<mask>mask\s\S+)?
$""",
re.VERBOSE,
),
diff --git a/plugins/module_utils/network/vyos/rm_templates/vrf.py b/plugins/module_utils/network/vyos/rm_templates/vrf.py
new file mode 100644
index 00000000..5171404e
--- /dev/null
+++ b/plugins/module_utils/network/vyos/rm_templates/vrf.py
@@ -0,0 +1,249 @@
+# -*- 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 VRF 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,
+)
+
+
+class VrfTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ prefix = {"set": "set", "remove": "delete"}
+ super(VrfTemplate, self).__init__(lines=lines, tmplt=self, prefix=prefix, module=module)
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "table_id",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+vrf
+ \s+name
+ \s+(?P<name>\S+)
+ \s+table
+ \s+'(?P<tid>\S+)'
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{ name }} table {{ table_id }}",
+ "result": {
+ "name": "{{ name }}",
+ "table_id": "{{ tid }}",
+ },
+ },
+ {
+ "name": "bind_to_all",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \s(?P<bta>bind-to-all)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf bind-to-all",
+ "result": {
+ "bind_to_all": "{{ True if bta is defined }}",
+ },
+ },
+ {
+ "name": "vni",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+vrf
+ \s+name
+ \s+(?P<name>\S+)
+ \s+vni
+ \s'(?P<vni>\S+)'
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} vni {{vni}}",
+ "result": {
+ "name": "{{ name }}",
+ "vni": "{{ vni }}",
+ },
+ },
+ {
+ "name": "description",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \sdescription
+ \s(?P<desc>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} description {{description}}",
+ "result": {
+ "name": "{{ name }}",
+ "description": "{{ desc }}",
+ },
+ },
+ {
+ "name": "disable_vrf",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<disable>disable)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} disable",
+ "compval": "disable",
+ "result": {
+ "name": "{{ name }}",
+ "disable": "{{ True if disable is defined }}",
+ },
+ },
+ # {
+ # "name": "address_family",
+ # "getval": re.compile(
+ # r"""
+ # ^set
+ # \svrf
+ # \sname
+ # \s(?P<name>\S+)
+ # \s(?P<af>ip|ipv6)
+ # $""",
+ # re.VERBOSE,
+ # ),
+ # "setval": "vrf name {{name}} {{ af }}",
+ # 'compval': "address_family",
+ # "result": {
+ # "name": "{{ name }}",
+ # "address_family": {
+ # '{{ "ipv4" if af == "ip" else "ipv6" }}': {
+ # "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ # },
+ # },
+ # },
+ # },
+ # {
+ # "name": "address_family.disable_forwarding",
+ # "getval": re.compile(
+ # r"""
+ # ^set
+ # \svrf
+ # \sname
+ # \s(?P<name>\S+)
+ # \s(?P<af>ip|ipv6)
+ # \s(?P<df>disable-forwarding)
+ # $""",
+ # re.VERBOSE,
+ # ),
+ # "setval": "vrf name {{name}} {{ afi }} disable-forwarding",
+ # # "compval": "address_family.ipv6.disable_forwarding",
+ # "result": {
+ # "name": "{{ name }}",
+ # "address_family": {
+ # '{{ "ipv4" if af == "ip" else "ipv6" }}': {
+ # "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ # "disable_forwarding": "{{ True if df is defined }}",
+ # },
+ # },
+ # },
+ # },
+ {
+ "name": "disable_forwarding",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<af>ip|ipv6)
+ \s(?P<df>disable-forwarding)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} {{ afi }} disable-forwarding",
+ "compval": "disable_forwarding",
+ "result": {
+ "name": "{{ name }}",
+ 'address_family': [{
+ "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ "disable_forwarding": "{{ True if df is defined }}",
+ }],
+ },
+ },
+ {
+ "name": "disable_nht",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<af>ip|ipv6)
+ \snht
+ \s(?P<nht>no-resolve-via-default)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} {{ afi }} nht no-resolve-via-default",
+ "compval": "nht_no_resolve_via_default",
+ "result": {
+ "name": "{{ name }}",
+ "address_family": [{
+ "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ "nht_no_resolve_via_default": "{{ True if nht is defined }}",
+ }],
+ },
+ },
+ {
+ "name": "route_maps",
+ "getval": re.compile(
+ r"""
+ ^set
+ \svrf
+ \sname
+ \s(?P<name>\S+)
+ \s(?P<af>ip|ipv6)
+ \sprotocol
+ \s(?P<proto>\S+)
+ \sroute-map
+ \s'(?P<rm>\S+)'
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "vrf name {{name}} {{ afi }} protocol {{ route_maps.protocol }} route-map {{ route_maps.rm_name }}",
+ "compval": "route_maps",
+ "remval": "vrf name {{name}} {{ afi }} protocol {{ route_maps.protocol }}",
+ "result": {
+ "name": "{{ name }}",
+ "address_family": [{
+ "afi": '{{ "ipv4" if af == "ip" else "ipv6" }}',
+ "route_maps": [{
+ "rm_name": "{{ rm }}",
+ "protocol": "{{ proto }}",
+ }],
+ }],
+ },
+ },
+ ]
+ # fmt: on
diff --git a/plugins/module_utils/network/vyos/utils/utils.py b/plugins/module_utils/network/vyos/utils/utils.py
index 4c371962..78445c02 100644
--- a/plugins/module_utils/network/vyos/utils/utils.py
+++ b/plugins/module_utils/network/vyos/utils/utils.py
@@ -9,7 +9,6 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible.module_utils.basic import missing_required_lib
-from ansible.module_utils.six import iteritems
try:
@@ -198,7 +197,7 @@ def key_value_in_dict(have_key, have_value, want_dict):
:param want_dict:
:return:
"""
- for key, value in iteritems(want_dict):
+ for key, value in want_dict.items():
if key == have_key and value == have_value:
return True
return False
@@ -270,7 +269,7 @@ def _is_w_same(w, h, key):
def _in_target(h, key):
"""
- This function checks whether the target exist and key present in target config.
+ This functi checks whether the target exist and key present in target config.
:param h: target config.
:param key: attribute name.
:return: True/False.
@@ -286,3 +285,25 @@ def in_target_not_none(h, key):
:return: True/False.
"""
return True if h and key in h and h[key] is not None else False
+
+
+def combine(a, b, recursive=False, list_merge="replace"):
+ """
+ Merge two dictionaries (shallow or deep).
+ :param a: dict
+ :param b: dict
+ :param recursive: bool, deep merge
+ :param list_merge: str, only 'replace' is supported (default Ansible behavior)
+ """
+ if not isinstance(a, dict) or not isinstance(b, dict):
+ raise ValueError("combine expects two dictionaries")
+
+ result = a.copy()
+
+ for k, v in b.items():
+ if recursive and k in result and isinstance(result[k], dict) and isinstance(v, dict):
+ result[k] = combine(result[k], v, recursive=True, list_merge=list_merge)
+ else:
+ result[k] = v
+
+ return result
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
@@ -7,6 +7,8 @@
"""Provide version object to compare version numbers."""
from __future__ import absolute_import, division, print_function
+
+
__metaclass__ = type
diff --git a/plugins/module_utils/network/vyos/vyos.py b/plugins/module_utils/network/vyos/vyos.py
index 1430b1b1..4987d6b0 100644
--- a/plugins/module_utils/network/vyos/vyos.py
+++ b/plugins/module_utils/network/vyos/vyos.py
@@ -34,6 +34,7 @@ import json
from ansible.module_utils._text import to_text
from ansible.module_utils.connection import Connection, ConnectionError
+
_DEVICE_CONFIGS = {}
@@ -68,8 +69,13 @@ def get_config(module, flags=None, format=None):
flags = [] if flags is None else flags
global _DEVICE_CONFIGS
- if _DEVICE_CONFIGS != {}:
- return _DEVICE_CONFIGS
+ # If _DEVICE_CONFIGS is non-empty and module.params["match"] is "none",
+ # return the cached device configurations. This avoids redundant calls
+ # to the connection when no specific match criteria are provided.
+ if _DEVICE_CONFIGS != {} and (
+ module.params["match"] is not None and module.params["match"] == "none"
+ ):
+ return to_text(_DEVICE_CONFIGS)
else:
connection = get_connection(module)
try:
@@ -90,11 +96,13 @@ def run_commands(module, commands, check_rc=True):
return response
-def load_config(module, commands, commit=False, comment=None):
+def load_config(module, commands, commit=False, comment=None, confirm=None):
connection = get_connection(module)
try:
- response = connection.edit_config(candidate=commands, commit=commit, comment=comment)
+ response = connection.edit_config(
+ candidate=commands, commit=commit, comment=comment, confirm=confirm
+ )
except ConnectionError as exc:
module.fail_json(msg=to_text(exc, errors="surrogate_then_replace"))