summaryrefslogtreecommitdiffstats
path: root/ansible_collections/cisco/iosxr/plugins/module_utils
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
commit38b7c80217c4e72b1d8988eb1e60bb6e77334114 (patch)
tree356e9fd3762877d07cde52d21e77070aeff7e789 /ansible_collections/cisco/iosxr/plugins/module_utils
parentAdding upstream version 7.7.0+dfsg. (diff)
downloadansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.tar.xz
ansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.zip
Adding upstream version 9.4.0+dfsg.upstream/9.4.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/cisco/iosxr/plugins/module_utils')
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/common/__init__.py (renamed from ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/__init__.py)0
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_address_family/bgp_address_family.py3
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_global/bgp_global.py201
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_neighbor_address_family/bgp_neighbor_address_family.py63
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/__init__.py (renamed from ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/__init__.py)0
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/bgp_templates.py612
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/l2_interfaces/l2_interfaces.py1
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lacp/lacp.py1
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lldp_global/lldp_global.py1
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/acls/acls.py3
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py7
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/__init__.py (renamed from ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/__init__.py)0
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/bgp_templates.py295
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/interfaces/interfaces.py31
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l2_interfaces/l2_interfaces.py24
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l3_interfaces/l3_interfaces.py12
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lacp/lacp.py3
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lldp_global/lldp_global.py4
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/logging_global/logging_global.py1
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py20
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ping/ping.py2
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/snmp_server/snmp_server.py2
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/static_routes/static_routes.py59
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/__init__.py (renamed from ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/__init__.py)0
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/bgp_templates.py89
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/facts.py4
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/interfaces/interfaces.py42
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l2_interfaces/l2_interfaces.py23
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l3_interfaces/l3_interfaces.py79
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/legacy/base.py32
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv2/ospfv2.py2
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv3/ospfv3.py2
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/iosxr.py3
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/address_family.py133
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/neighbors.py136
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/process.py121
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/module.py71
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/providers.py127
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_address_family.py4
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_global.py124
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_templates.py2816
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv2.py14
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv3.py14
-rw-r--r--ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/utils/utils.py39
44 files changed, 4476 insertions, 744 deletions
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/__init__.py b/ansible_collections/cisco/iosxr/plugins/module_utils/common/__init__.py
index e69de29bb..e69de29bb 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/__init__.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/common/__init__.py
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_address_family/bgp_address_family.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_address_family/bgp_address_family.py
index 7413c1ad9..10d4e1666 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_address_family/bgp_address_family.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_address_family/bgp_address_family.py
@@ -149,6 +149,9 @@ class Bgp_address_familyArgs(object): # pylint: disable=R0903
},
"dampening": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "value", "route_policy"],
+ ],
"options": {
"set": {"type": "bool"},
"value": {"type": "int"},
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_global/bgp_global.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_global/bgp_global.py
index 051e26996..3009b9f32 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_global/bgp_global.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_global/bgp_global.py
@@ -270,6 +270,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"fast_detect": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable", "strict_mode"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -292,6 +295,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"send": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -299,6 +305,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"receive": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -317,6 +326,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"all": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -332,6 +344,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"description": {"type": "str"},
"dmz_link_bandwidth": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"set": {"type": "bool"},
@@ -340,6 +355,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"dscp": {"type": "str"},
"ebgp_multihop": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "mpls"],
+ ],
"options": {
"value": {"type": "int"},
"mpls": {"type": "bool"},
@@ -347,6 +365,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ebgp_recv_extcommunity_dmz": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"set": {"type": "bool"},
@@ -354,6 +375,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ebgp_send_extcommunity_dmz": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "cumulatie", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"cumulatie": {"type": "bool"},
@@ -362,6 +386,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"egress_engineering": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"set": {"type": "bool"},
@@ -377,6 +404,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"set": {"type": "bool"},
"activate": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -386,6 +416,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"as_prepends": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -395,6 +428,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"local_preference": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
"inheritance_disable": {
@@ -413,6 +449,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ignore_connected_check": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"set": {"type": "bool"},
@@ -421,6 +460,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"keychain": {
"type": "dict",
"no_log": False,
+ "mutually_exclusive": [
+ ["name", "inheritance_disable"],
+ ],
"options": {
"name": {"type": "str"},
"inheritance_disable": {"type": "bool"},
@@ -431,6 +473,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"address": {
"type": "dict",
+ "mutually_exclusive": [
+ ["ipv4_address", "inheritance_disable"],
+ ],
"options": {
"ipv4_address": {"type": "str"},
"inheritance_disable": {
@@ -442,8 +487,24 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"local_as": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
+ "no_prepend": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "replace_as": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "dual_as": {"type": "bool"},
+ },
+ },
+ },
+ },
"inheritance_disable": {"type": "bool"},
},
},
@@ -455,6 +516,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"in": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "disable", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
"disable": {"type": "bool"},
@@ -465,6 +529,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"out": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "disable", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
"disable": {"type": "bool"},
@@ -486,6 +553,19 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
},
},
+ "password": {
+ "type": "dict",
+ "no_log": False,
+ "mutually_exclusive": [
+ ["encrypted", "inheritance_disable"],
+ ],
+ "options": {
+ "encrypted": {"type": "str", "no_log": True},
+ "inheritance_disable": {
+ "type": "bool",
+ },
+ },
+ },
"receive_buffer_size": {"type": "int"},
"remote_as": {"type": "int"},
"send_buffer_size": {"type": "int"},
@@ -495,6 +575,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"shutdown": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"set": {"type": "bool"},
@@ -505,6 +588,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"mss": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
"inheritance_disable": {
@@ -523,6 +609,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ttl_security": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {"type": "bool"},
"set": {"type": "bool"},
@@ -568,10 +657,24 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
},
"update_source": {"type": "str"},
+ "use": {
+ "type": "dict",
+ "options": {
+ "neighbor_group": {
+ "type": "str",
+ },
+ "session_group": {
+ "type": "str",
+ },
+ },
+ },
},
},
"nsr": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -862,6 +965,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"fast_detect": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable", "strict_mode"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -886,6 +992,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"send": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {
"type": "bool",
@@ -897,6 +1006,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"receive": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {
"type": "bool",
@@ -921,6 +1033,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"all": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -938,6 +1053,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"description": {"type": "str"},
"dmz_link_bandwidth": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -955,6 +1073,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ebgp_recv_extcommunity_dmz": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -964,6 +1085,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ebgp_send_extcommunity_dmz": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -974,6 +1098,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"egress_engineering": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -991,6 +1118,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"set": {"type": "bool"},
"activate": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -1000,6 +1130,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"as_prepends": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -1009,6 +1142,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"local_preference": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
"inheritance_disable": {
@@ -1027,6 +1163,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ignore_connected_check": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -1036,6 +1175,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"keychain": {
"type": "dict",
+ "mutually_exclusive": [
+ ["name", "inheritance_disable"],
+ ],
"no_log": False,
"options": {
"name": {"type": "str"},
@@ -1049,6 +1191,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"address": {
"type": "dict",
+ "mutually_exclusive": [
+ ["ipv4_address", "inheritance_disable"],
+ ],
"options": {
"ipv4_address": {
"type": "str",
@@ -1062,8 +1207,24 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"local_as": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
+ "no_prepend": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "replace_as": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "dual_as": {"type": "bool"},
+ },
+ },
+ },
+ },
"inheritance_disable": {
"type": "bool",
},
@@ -1077,6 +1238,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"in": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "disable", "inheritance_disable"],
+ ],
"options": {
"value": {
"type": "int",
@@ -1091,6 +1255,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"out": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "disable", "inheritance_disable"],
+ ],
"options": {
"value": {
"type": "int",
@@ -1118,6 +1285,19 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
},
},
+ "password": {
+ "type": "dict",
+ "mutually_exclusive": [
+ ["encrypted", "inheritance_disable"],
+ ],
+ "no_log": False,
+ "options": {
+ "encrypted": {"type": "str", "no_log": True},
+ "inheritance_disable": {
+ "type": "bool",
+ },
+ },
+ },
"receive_buffer_size": {"type": "int"},
"remote_as": {"type": "int"},
"send_buffer_size": {"type": "int"},
@@ -1131,6 +1311,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"shutdown": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -1143,6 +1326,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"options": {
"mss": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "inheritance_disable"],
+ ],
"options": {
"value": {"type": "int"},
"inheritance_disable": {
@@ -1161,6 +1347,9 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
"ttl_security": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"inheritance_disable": {
"type": "bool",
@@ -1208,6 +1397,17 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
},
},
"update_source": {"type": "str"},
+ "use": {
+ "type": "dict",
+ "options": {
+ "neighbor_group": {
+ "type": "str",
+ },
+ "session_group": {
+ "type": "str",
+ },
+ },
+ },
},
},
"rd": {
@@ -1239,6 +1439,7 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"deleted",
"merged",
"replaced",
+ "overridden",
"gathered",
"rendered",
"parsed",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_neighbor_address_family/bgp_neighbor_address_family.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_neighbor_address_family/bgp_neighbor_address_family.py
index a720860b7..68e1bbeae 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_neighbor_address_family/bgp_neighbor_address_family.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_neighbor_address_family/bgp_neighbor_address_family.py
@@ -80,6 +80,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"send_cost_community_disable": {"type": "bool"},
"send_med": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -89,10 +92,16 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"allowas_in": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "value"],
+ ],
"options": {"value": {"type": "int"}, "set": {"type": "bool"}},
},
"as_override": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -105,6 +114,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"default_originate": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "route_policy", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"route_policy": {"type": "str"},
@@ -137,6 +149,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"multipath": {"type": "bool"},
"next_hop_self": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -179,6 +194,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"route_reflector_client": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -186,6 +204,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_community_ebgp": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -193,6 +214,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_community_gshut_ebgp": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -200,6 +224,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_extended_community_ebgp": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -207,6 +234,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_multicast_attributes": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -217,6 +247,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"options": {
"inbound": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "always", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"always": {"type": "bool"},
@@ -271,6 +304,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"send_cost_community_disable": {"type": "bool"},
"send_med": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "disable"],
+ ],
"options": {
"set": {"type": "bool"},
"disable": {"type": "bool"},
@@ -280,6 +316,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"allowas_in": {
"type": "dict",
+ "mutually_exclusive": [
+ ["value", "set"],
+ ],
"options": {
"value": {"type": "int"},
"set": {"type": "bool"},
@@ -288,6 +327,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"as_override": {
"type": "dict",
"aliases": ["as_overrride"],
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -299,6 +341,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"default_originate": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "route_policy", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"route_policy": {"type": "str"},
@@ -331,6 +376,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"multipath": {"type": "bool"},
"next_hop_self": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -364,6 +412,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"route_reflector_client": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -371,6 +422,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_community_ebgp": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -378,6 +432,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_community_gshut_ebgp": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -385,6 +442,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
},
"send_extended_community_ebgp": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"inheritance_disable": {"type": "bool"},
@@ -395,6 +455,9 @@ class Bgp_neighbor_address_familyArgs(object): # pylint: disable=R0903
"options": {
"inbound": {
"type": "dict",
+ "mutually_exclusive": [
+ ["set", "always", "inheritance_disable"],
+ ],
"options": {
"set": {"type": "bool"},
"always": {"type": "bool"},
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/__init__.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/__init__.py
index e69de29bb..e69de29bb 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/__init__.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/__init__.py
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/bgp_templates.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/bgp_templates.py
new file mode 100644
index 000000000..793f26282
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/bgp_templates/bgp_templates.py
@@ -0,0 +1,612 @@
+# -*- coding: utf-8 -*-
+# Copyright 2023 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
+# ansible.content_builder.
+#
+# Manually editing this file is not advised.
+#
+# To update the argspec make the desired changes
+# in the documentation in the module file and re-run
+# ansible.content_builder commenting out
+# the path to external 'docstring' in build.yaml.
+#
+##############################################
+
+"""
+The arg spec for the iosxr_bgp_templates module
+"""
+
+
+class Bgp_templatesArgs(object): # pylint: disable=R0903
+ """The arg spec for the iosxr_bgp_templates module"""
+
+ argument_spec = {
+ "config": {
+ "type": "dict",
+ "options": {
+ "as_number": {"type": "str"},
+ "neighbor": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "name": {"type": "str"},
+ "address_family": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "afi": {
+ "type": "str",
+ "choices": ["ipv4", "ipv6"],
+ },
+ "safi": {
+ "type": "str",
+ "choices": [
+ "flowspec",
+ "mdt",
+ "multicast",
+ "mvpn",
+ "rt-filter",
+ "tunnel",
+ "unicast",
+ "labeled-unicast",
+ "sr-policy",
+ ],
+ },
+ "signalling": {
+ "type": "dict",
+ "options": {
+ "bgp_disable": {"type": "bool"},
+ "ldp_disable": {"type": "bool"},
+ },
+ },
+ "advertise": {
+ "type": "dict",
+ "options": {
+ "local_labeled_route": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ "permanent_network": {"type": "bool"},
+ },
+ },
+ "aigp": {
+ "type": "dict",
+ "options": {
+ "disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ "send_cost_community_disable": {
+ "type": "bool",
+ },
+ "send_med": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "allowas_in": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "set": {"type": "bool"},
+ },
+ },
+ "as_override": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "bestpath_origin_as_allow_invalid": {
+ "type": "bool",
+ },
+ "capability_orf_prefix": {
+ "type": "str",
+ "choices": ["both", "send", "none", "receive"],
+ },
+ "default_originate": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "route_policy": {"type": "str"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "encapsulation_type_srv6": {"type": "bool"},
+ "long_lived_graceful_restart": {
+ "type": "dict",
+ "options": {
+ "capable": {"type": "bool"},
+ "stale_time": {
+ "type": "dict",
+ "options": {
+ "send": {"type": "int"},
+ "accept": {"type": "int"},
+ },
+ },
+ },
+ },
+ "maximum_prefix": {
+ "type": "dict",
+ "options": {
+ "max_limit": {"type": "int"},
+ "threshold_value": {"type": "int"},
+ "restart": {"type": "int"},
+ "warning_only": {"type": "bool"},
+ "discard_extra_paths": {"type": "bool"},
+ },
+ },
+ "multipath": {"type": "bool"},
+ "next_hop_self": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "next_hop_unchanged": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ "multipath": {"type": "bool"},
+ },
+ },
+ "optimal_route_reflection_group_name": {
+ "type": "str",
+ },
+ "orf_route_policy": {"type": "str"},
+ "origin_as": {
+ "type": "dict",
+ "options": {
+ "validation": {
+ "type": "dict",
+ "options": {
+ "disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "remove_private_AS": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inbound": {"type": "bool"},
+ "entire_aspath": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "route_policy": {
+ "type": "dict",
+ "options": {
+ "inbound": {"type": "str"},
+ "outbound": {"type": "str"},
+ },
+ },
+ "route_reflector_client": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "send_community_ebgp": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "send_community_gshut_ebgp": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "send_extended_community_ebgp": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "send_multicast_attributes": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ "soft_reconfiguration": {
+ "type": "dict",
+ "options": {
+ "inbound": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "always": {"type": "bool"},
+ "inheritance_disable": {
+ "type": "bool",
+ },
+ },
+ },
+ },
+ },
+ "weight": {"type": "int"},
+ "update": {
+ "type": "dict",
+ "options": {
+ "out_originator_loopcheck_disable": {
+ "type": "bool",
+ },
+ "out_originator_loopcheck_set": {
+ "type": "bool",
+ },
+ },
+ },
+ "use": {"type": "str"},
+ },
+ },
+ "advertisement_interval": {"type": "int"},
+ "bfd": {
+ "type": "dict",
+ "options": {
+ "fast_detect": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "disable": {"type": "bool"},
+ "strict_mode": {"type": "bool"},
+ },
+ },
+ "minimum_interval": {"type": "int"},
+ "multiplier": {"type": "int"},
+ },
+ },
+ "bmp_activate": {
+ "type": "dict",
+ "options": {"server": {"type": "int"}},
+ },
+ "capability": {
+ "type": "dict",
+ "options": {
+ "additional_paths": {
+ "type": "dict",
+ "options": {
+ "send": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ "receive": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "suppress": {
+ "type": "dict",
+ "options": {
+ "four_byte_AS": {
+ "type": "dict",
+ "options": {"set": {"type": "bool"}},
+ },
+ "all": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {
+ "type": "bool",
+ },
+ "set": {"type": "bool"},
+ },
+ },
+ },
+ },
+ },
+ },
+ "cluster_id": {"type": "str"},
+ "description": {"type": "str"},
+ "dmz_link_bandwidth": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "dscp": {"type": "str"},
+ "ebgp_multihop": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "mpls": {"type": "bool"},
+ },
+ },
+ "ebgp_recv_extcommunity_dmz": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "ebgp_send_extcommunity_dmz": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "cumulatie": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "egress_engineering": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "enforce_first_as": {
+ "type": "dict",
+ "options": {"disable": {"type": "bool"}},
+ },
+ "graceful_maintenance": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "activate": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "as_prepends": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "value": {"type": "int"},
+ },
+ },
+ "local_preference": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "graceful_restart": {
+ "type": "dict",
+ "options": {
+ "restart_time": {"type": "int"},
+ "stalepath_time": {"type": "int"},
+ },
+ },
+ "ignore_connected_check": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "idle_watch_time": {"type": "int"},
+ "internal_vpn_client": {"type": "bool"},
+ "keychain": {
+ "type": "dict",
+ "no_log": False,
+ "options": {
+ "name": {"type": "str", "no_log": True},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "local": {
+ "type": "dict",
+ "options": {
+ "address": {
+ "type": "dict",
+ "options": {
+ "ipv4_address": {"type": "str"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "local_as": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "no_prepend": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "replace_as": {
+ "type": "dict",
+ "options": {
+ "set": {"type": "bool"},
+ "dual_as": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "local_address_subnet": {"type": "str"},
+ "log": {
+ "type": "dict",
+ "options": {
+ "log_message": {
+ "type": "dict",
+ "options": {
+ "in": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "disable": {"type": "bool"},
+ "inheritance_disable": {
+ "type": "bool",
+ },
+ },
+ },
+ "out": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "disable": {"type": "bool"},
+ "inheritance_disable": {
+ "type": "bool",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "maximum_peers": {"type": "int"},
+ "password": {
+ "type": "dict",
+ "no_log": False,
+ "options": {
+ "encrypted": {"type": "str", "no_log": True},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ "peer_set": {"type": "int"},
+ "precedence": {
+ "type": "str",
+ "choices": [
+ "critical",
+ "flash",
+ "flash-override",
+ "immediate",
+ "internet",
+ "network",
+ "priority",
+ "routine",
+ ],
+ },
+ "receive_buffer_size": {"type": "int"},
+ "remote_as": {"type": "int"},
+ "remote_as_list": {"type": "str"},
+ "send_buffer_size": {"type": "int"},
+ "session_open_mode": {
+ "type": "str",
+ "choices": ["active-only", "both", "passive-only"],
+ },
+ "shutdown": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "tcp": {
+ "type": "dict",
+ "options": {
+ "mss": {
+ "type": "dict",
+ "options": {
+ "value": {"type": "int"},
+ "inheritance_disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "timers": {
+ "type": "dict",
+ "options": {
+ "keepalive_time": {"type": "int"},
+ "holdtime": {"type": "int"},
+ "min_holdtime": {"type": "int"},
+ },
+ },
+ "ttl_security": {
+ "type": "dict",
+ "options": {
+ "inheritance_disable": {"type": "bool"},
+ "set": {"type": "bool"},
+ },
+ },
+ "update": {
+ "type": "dict",
+ "options": {
+ "in": {
+ "type": "dict",
+ "options": {
+ "filtering": {
+ "type": "dict",
+ "options": {
+ "attribute_filter": {
+ "type": "dict",
+ "options": {
+ "group": {"type": "str"},
+ },
+ },
+ "logging": {
+ "type": "dict",
+ "options": {
+ "disable": {"type": "bool"},
+ },
+ },
+ "update_message": {
+ "type": "dict",
+ "options": {
+ "buffers": {"type": "int"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "update_source": {"type": "str"},
+ "use": {
+ "type": "dict",
+ "options": {
+ "neighbor_group": {"type": "str"},
+ "session_group": {"type": "str"},
+ },
+ },
+ },
+ },
+ },
+ },
+ "running_config": {"type": "str"},
+ "state": {
+ "type": "str",
+ "choices": [
+ "deleted",
+ "merged",
+ "overridden",
+ "replaced",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ } # pylint: disable=C0301
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/l2_interfaces/l2_interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/l2_interfaces/l2_interfaces.py
index e58ddebbb..dff2f7680 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/l2_interfaces/l2_interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/l2_interfaces/l2_interfaces.py
@@ -69,6 +69,7 @@ class L2_InterfacesArgs(object):
"type": "list",
},
"q_vlan": {"type": "list", "elements": "int"},
+ "qvlan": {"type": "list", "elements": "str"},
"propagate": {"type": "bool"},
"encapsulation": {
"type": "dict",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lacp/lacp.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lacp/lacp.py
index 2bdda1778..3fcaf8cb0 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lacp/lacp.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lacp/lacp.py
@@ -58,6 +58,7 @@ class LacpArgs(object): # pylint: disable=R0903
"choices": [
"merged",
"replaced",
+ "overridden",
"deleted",
"parsed",
"rendered",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lldp_global/lldp_global.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lldp_global/lldp_global.py
index 6c6c39479..117065223 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lldp_global/lldp_global.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/argspec/lldp_global/lldp_global.py
@@ -62,6 +62,7 @@ class Lldp_globalArgs(object): # pylint: disable=R0903
"choices": [
"merged",
"replaced",
+ "overridden",
"deleted",
"parsed",
"rendered",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/acls/acls.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/acls/acls.py
index 9f9b1ea61..0e0ea7d00 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/acls/acls.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/acls/acls.py
@@ -502,7 +502,8 @@ class Acls(ConfigBase):
) ^ set(flatten_dict(want_ace.get("protocol_options", {})))
if delta or protocol_opt_delta:
- want_ace = self._dict_merge(have_ace, want_ace)
+ if self.state not in ["replaced"]:
+ want_ace = self._dict_merge(have_ace, want_ace)
return self._compute_commands(want_ace)
def _prepare_for_diff(self, ace):
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py
index 69b752be9..4cb4083c6 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_global/bgp_global.py
@@ -116,6 +116,7 @@ class Bgp_global(ResourceModule):
"""
if self.state not in ["parsed", "gathered"]:
self.generate_commands()
+ # import epdb;epdb.serve()
self.run_commands()
return self.result
@@ -123,7 +124,7 @@ class Bgp_global(ResourceModule):
"""Generate configuration commands to send based on
want, have and desired state.
"""
- if self.state in ["merged", "replaced"]:
+ if self.state in ["merged", "replaced", "overridden"]:
w_asn = self.want.get("as_number")
h_asn = self.have.get("as_number")
@@ -242,6 +243,8 @@ class Bgp_global(ResourceModule):
for the Bgp_global neighbor resource.
"""
neighbor_parsers = [
+ "use.neighbor_group",
+ "use.session_group",
"advertisement_interval",
"bfd_fast_detect_disable",
"bfd_fast_detect_strict_mode",
@@ -275,6 +278,8 @@ class Bgp_global(ResourceModule):
"local",
"local_address",
"origin_as",
+ "password_inheritance_disable",
+ "password_encrypted",
"remote_as",
"receive_buffer_size",
"send_buffer_size",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/__init__.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/__init__.py
index e69de29bb..e69de29bb 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/__init__.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/__init__.py
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/bgp_templates.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/bgp_templates.py
new file mode 100644
index 000000000..c62687dfa
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/bgp_templates/bgp_templates.py
@@ -0,0 +1,295 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2023 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 iosxr_bgp_templates 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.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
+ ResourceModule,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ dict_merge,
+)
+
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.facts import Facts
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.rm_templates.bgp_templates import (
+ Bgp_templatesTemplate,
+)
+
+
+class Bgp_templates(ResourceModule):
+ """
+ The iosxr_bgp_templates config class
+ """
+
+ def __init__(self, module):
+ super(Bgp_templates, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="bgp_templates",
+ tmplt=Bgp_templatesTemplate(),
+ )
+ self.parsers = [
+ "router",
+ "advertise.local_labeled_route.disable",
+ "advertise.local_labeled_route.set",
+ "advertise.permanent_network",
+ "aigp.set",
+ "aigp.disable",
+ "aigp.send_med",
+ "aigp.send_cost_community_disable",
+ "allowas_in",
+ "as_override",
+ "bestpath_origin_as_allow_invalid",
+ "capability_orf_prefix",
+ "default_originate.set",
+ "default_originate.route_policy",
+ "default_originate.inheritance_disable",
+ "long_lived_graceful_restart_capable",
+ "long_lived_graceful_restart_stale_time",
+ "maximum_prefix",
+ "multipath",
+ "next_hop_self",
+ "next_hop_unchanged.set",
+ "next_hop_unchanged.inheritance_disable",
+ "next_hop_unchanged.multipath",
+ "optimal_route_reflection_group_name",
+ "origin_as",
+ "remove_private_AS",
+ "remove_private_AS.set",
+ "route_reflector_client",
+ "send_community_ebgp",
+ "send_community_gshut_ebgp",
+ "send_extended_community_ebgp",
+ "send_multicast_attributes",
+ "soft_reconfiguration",
+ "weight",
+ "route_policy.inbound",
+ "route_policy.outbound",
+ "signalling",
+ "update.out_originator_loopcheck_disable",
+ "update.out_originator_loopcheck_set",
+ "use",
+ ]
+
+ 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.
+ """
+ w_asn = self.want.pop("as_number", "")
+ h_asn = self.have.pop("as_number", "")
+
+ asn = w_asn or h_asn
+ wantd = self._bgp_list_to_dict(deepcopy(self.want))
+ haved = self._bgp_list_to_dict(deepcopy(self.have))
+ # if state is merged, merge want onto have and then compare
+ if self.state == "merged":
+ wantd = dict_merge(haved, wantd)
+
+ # 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}
+ wantd = {}
+
+ if self.state in ["overridden", "deleted"]:
+ cmds = []
+ for k, have in iteritems(haved.get("neighbor", {})):
+ if k not in wantd.get("neighbor", {}):
+ cmds.append("no neighbor-group {0}".format(have["name"]))
+ self.commands.extend(cmds)
+
+ self._compare(asn, want=wantd, have=haved)
+
+ def sort_commands(self, index):
+ old_cmd = self.commands[index:]
+ self.commands = self.commands[0:index]
+ self.commands.extend(
+ [each for each in old_cmd if "no" in each]
+ + [each for each in old_cmd if "no" not in each],
+ )
+
+ def _compare(self, asn, want, have):
+ """Leverages the base class `compare()` method and
+ populates the list of commands to be run by comparing
+ the `want` and `have` data with the `parsers` defined
+ for the Bgp_global network resource.
+ """
+ self._compare_ngs(want=want, have=have)
+ if self.commands and "router bgp" not in self.commands[0]:
+ self.commands.insert(0, "router bgp {0}".format(asn))
+
+ def _compare_ngs(self, want, have):
+ """Leverages the base class `compare()` method and
+ populates the list of commands to be run by comparing
+ the `want` and `have` data with the `parsers` defined
+ for the Bgp_global neighbor resource.
+ """
+ neighbor_parsers = [
+ "use.neighbor_group",
+ "use.session_group",
+ "advertisement_interval",
+ "bfd_fast_detect_disable",
+ "bfd_fast_detect_strict_mode",
+ "bfd_fast_detect_set",
+ "bfd_nbr_minimum_interval",
+ "bfd_nbr_multiplier",
+ "bmp_activate",
+ "dmz_link_bandwidth",
+ "dmz_link_bandwidth_inheritance_disable",
+ "neighbor_description",
+ "neighbor_cluster_id",
+ "dscp",
+ "ebgp_multihop_value",
+ "ebgp_multihop_mpls",
+ "ebgp_recv_extcommunity_dmz",
+ "ebgp_recv_extcommunity_dmz_set",
+ "ebgp_send_extcommunity_dmz",
+ "ebgp_send_extcommunity_dmz_set",
+ "ebgp_send_extcommunity_dmz_cumulatie",
+ "egress_engineering",
+ "egress_engineering_set",
+ "idle_watch_time",
+ "internal_vpn_client",
+ "ignore_connected_check",
+ "ignore_connected_check_set",
+ "neighbor_enforce_first_as_disable",
+ "neighbor_graceful_restart_restart_time",
+ "neighbor_graceful_restart_stalepath_time",
+ "keychain",
+ "keychain_name",
+ "local_as_inheritance_disable",
+ "local_as",
+ "local",
+ "local_address",
+ "origin_as",
+ "password_inheritance_disable",
+ "password_encrypted",
+ "peer_set",
+ "precedence",
+ "remote_as",
+ "remote_as_list",
+ "receive_buffer_size",
+ "send_buffer_size",
+ "session_open_mode",
+ "neighbor_shutdown",
+ "neighbor_shutdown_inheritance_disable",
+ "neighbor_tcp_mss",
+ "neighbor_tcp_mss_inheritance_disable",
+ "neighbor_timers_keepalive",
+ "update_source",
+ "neighbor_ttl_security_inheritance_disable",
+ "neighbor_ttl_security",
+ "neighbor_graceful_maintenance_set",
+ "neighbor_graceful_maintenance_activate",
+ "neighbor_graceful_maintenance_activate_inheritance_disable",
+ "neighbor_graceful_maintenance_as_prepends",
+ "neighbor_graceful_maintenance_local_preference_disable",
+ "neighbor_graceful_maintenance_local_preference",
+ "neighbor_graceful_maintenance_as_prepends_value",
+ "neighbor_capability_additional_paths_send",
+ "neighbor_capability_additional_paths_send_disable",
+ "neighbor_capability_additional_paths_rcv_disable",
+ "neighbor_capability_additional_paths_rcv",
+ "neighbor_capability_suppress_four_byte_AS",
+ "neighbor_capability_suppress_all",
+ "neighbor_capability_suppress_all_inheritance_disable",
+ "neighbor_log_message_in_value",
+ "neighbor_log_message_in_disable",
+ "neighbor_log_message_in_inheritance_disable",
+ "neighbor_log_message_out_value",
+ "neighbor_log_message_out_disable",
+ "neighbor_log_message_out_inheritance_disable",
+ "neighbor_update_in_filtering_attribute_filter_group",
+ "neighbor_update_in_filtering_logging_disable",
+ "neighbor_update_in_filtering_message_buffers",
+ ]
+
+ want_nbr = want.get("neighbor", {})
+ have_nbr = have.get("neighbor", {})
+ for name, entry in iteritems(want_nbr):
+ have = have_nbr.pop(name, {})
+ begin = len(self.commands)
+ self.compare(parsers=neighbor_parsers, want=entry, have=have)
+ if self.state in ["replaced", "overridden"]:
+ self.sort_commands(begin)
+ self._compare_af(want=entry, have=have)
+ name = entry.get("name", "")
+ if len(self.commands) != begin:
+ self.commands.insert(
+ begin,
+ self._tmplt.render(
+ {"name": name},
+ "neighbor_group",
+ False,
+ ),
+ )
+
+ def _compare_af(self, want, have):
+ """Custom handling of afs option
+ :params want: the want BGP dictionary
+ :params have: the have BGP dictionary
+ """
+ wafs = want.get("address_family", {})
+ hafs = have.get("address_family", {})
+ for name, entry in iteritems(wafs):
+ begin = len(self.commands)
+ af_have = hafs.pop(name, {})
+ self.compare(parsers=self.parsers, want=entry, have=af_have)
+ if self.state in ["replaced", "overridden"]:
+ self.sort_commands(begin)
+ if len(self.commands) != begin or (not af_have and entry):
+ self.commands.insert(
+ begin,
+ self._tmplt.render(
+ {"afi": entry.get("afi"), "safi": entry.get("safi")},
+ "address_family",
+ False,
+ ),
+ )
+
+ for name, entry in iteritems(hafs):
+ self.addcmd(
+ {"afi": entry.get("afi"), "safi": entry.get("safi")},
+ "address_family",
+ True,
+ )
+
+ def _bgp_list_to_dict(self, data):
+ if "neighbor" in data:
+ for nbr in data["neighbor"]:
+ if "address_family" in nbr:
+ nbr["address_family"] = {
+ (x["afi"], x.get("safi")): x for x in nbr["address_family"]
+ }
+ data["neighbor"] = {x["name"]: x for x in data["neighbor"]}
+ return data
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/interfaces/interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/interfaces/interfaces.py
index 2a0c18852..d13206109 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/interfaces/interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/interfaces/interfaces.py
@@ -181,21 +181,33 @@ class Interfaces(ConfigBase):
to the desired configuration
"""
commands = []
+ not_in_have = set()
+ in_have = set()
for each in have:
for interface in want:
- if each["name"] == interface["name"] or interface["name"] in each["name"]:
+ interface["name"] = normalize_interface(interface["name"])
+ if each["name"] == interface["name"]:
+ in_have.add(interface["name"])
break
+ if interface["name"] != each["name"]:
+ not_in_have.add(interface["name"])
else:
# We didn't find a matching desired state, which means we can
# pretend we received an empty desired state.
interface = dict(name=each["name"])
- commands.extend(self._clear_config(interface, each))
+ kwargs = {"want": interface, "have": each}
+ commands.extend(self._clear_config(**kwargs))
continue
have_dict = filter_dict_having_none_value(interface, each)
- want = dict()
- commands.extend(self._clear_config(want, have_dict))
+ commands.extend(self._clear_config(dict(), have_dict))
commands.extend(self._set_config(interface, each))
+ # Add the want interface that's not already configured in have interface
+ for each in not_in_have - in_have:
+ for every in want:
+ interface = "interface {0}".format(every["name"])
+ if each and interface not in commands:
+ commands.extend(self._set_config(every, {}))
# Remove the duplicate interface call
commands = remove_duplicate_interface(commands)
@@ -305,6 +317,17 @@ class Interfaces(ConfigBase):
and want.get("duplex") != have.get("duplex")
):
remove_command_from_config_list(interface, "duplex", commands)
+
+ if interface_type.lower() in [
+ "gigabitethernet",
+ "fourhundredgige",
+ "fiftygige",
+ "fortygige",
+ "hundredgige",
+ "twohundredgige",
+ "tengige",
+ "twentyfivegige",
+ ]:
if have.get("mtu") and want.get("mtu") != have.get("mtu"):
remove_command_from_config_list(interface, "mtu", commands)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l2_interfaces/l2_interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l2_interfaces/l2_interfaces.py
index c571d3fa0..da44bb709 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l2_interfaces/l2_interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l2_interfaces/l2_interfaces.py
@@ -262,12 +262,20 @@ class L2_Interfaces(ConfigBase):
return commands
+ def _handle_deprecated(self, config):
+ if config.get("q_vlan"):
+ config["qvlan"] = config.get("q_vlan")
+ del config["q_vlan"]
+ return config
+
def _set_config(self, want, have, module):
# Set the interface config based on the want and have config
commands = []
interface = "interface " + want["name"]
l2_protocol_bool = False
# Get the diff b/w want and have
+ want = self._handle_deprecated(want)
+ have = self._handle_deprecated(have)
diff = dict_diff(have, want)
if diff:
# For merging with already configured l2protocol
@@ -286,7 +294,7 @@ class L2_Interfaces(ConfigBase):
wants_native = diff.get("native_vlan")
l2transport = diff.get("l2transport")
- q_vlan = diff.get("q_vlan")
+ qvlan = diff.get("qvlan")
encapsulation = diff.get("encapsulation")
propagate = diff.get("propagate")
if l2_protocol_bool is False:
@@ -308,18 +316,16 @@ class L2_Interfaces(ConfigBase):
)
add_command_to_config_list(interface, cmd, commands)
- if q_vlan and "." in interface:
- q_vlans = " ".join(map(str, want.get("q_vlan")))
- if q_vlans != have.get("q_vlan"):
+ if qvlan and "." in interface:
+ q_vlans = " ".join(map(str, want.get("qvlan")))
+ if q_vlans != have.get("qvlan"):
cmd = "dot1q vlan {0}".format(q_vlans)
add_command_to_config_list(interface, cmd, commands)
else:
if l2transport or l2protocol:
for each in l2protocol:
each = dict(each)
- if isinstance(each, dict) and "cpsv" in list(
- each.keys(),
- ):
+ if isinstance(each, dict) and each.get("cpsv"):
cmd = "l2transport l2protocol {0} {1}".format(
"cpsv",
each.get("cpsv"),
@@ -361,6 +367,8 @@ class L2_Interfaces(ConfigBase):
def _clear_config(self, want, have):
# Delete the interface config based on the want and have config
commands = []
+ want = self._handle_deprecated(want)
+ have = self._handle_deprecated(have)
if want.get("name"):
interface = "interface " + want["name"]
@@ -375,7 +383,7 @@ class L2_Interfaces(ConfigBase):
commands,
)
- if have.get("q_vlan"):
+ if have.get("qvlan"):
remove_command_from_config_list(
interface,
"encapsulation dot1q",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l3_interfaces/l3_interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l3_interfaces/l3_interfaces.py
index 98b7c5965..9b55e2f91 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l3_interfaces/l3_interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/l3_interfaces/l3_interfaces.py
@@ -11,6 +11,8 @@ created
from __future__ import absolute_import, division, print_function
+import copy
+
__metaclass__ = type
@@ -119,7 +121,7 @@ class L3_Interfaces(ConfigBase):
to the desired configuration
"""
want = self._module.params["config"]
- have = existing_l3_interfaces_facts
+ have = copy.deepcopy(existing_l3_interfaces_facts)
resp = self.set_state(want, have)
return to_list(resp)
@@ -308,8 +310,12 @@ class L3_Interfaces(ConfigBase):
if want.get("ipv4"):
for each in want.get("ipv4"):
if each.get("address") != "dhcp":
- ip_addr_want = validate_n_expand_ipv4(module, each)
- each["address"] = ip_addr_want
+ each["address"] = validate_n_expand_ipv4(module, each)
+
+ if have.get("ipv4"):
+ for each in have.get("ipv4"):
+ if each.get("address") != "dhcp":
+ each["address"] = validate_n_expand_ipv4(module, each)
# Get the diff b/w want and have
want_dict = dict_to_set(want)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lacp/lacp.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lacp/lacp.py
index 8a6744e54..ee0a7768d 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lacp/lacp.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lacp/lacp.py
@@ -137,6 +137,7 @@ class Lacp(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
+ commands = []
if self.state in ("merged", "replaced", "rendered") and not want:
self._module.fail_json(
msg="value of config parameter must not be empty for state {0}".format(
@@ -148,7 +149,7 @@ class Lacp(ConfigBase):
commands = self._state_deleted(want, have)
elif self.state in ("merged", "rendered"):
commands = self._state_merged(want, have)
- elif self.state == "replaced":
+ elif self.state in ["replaced", "overridden"]:
commands = self._state_replaced(want, have)
return commands
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lldp_global/lldp_global.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lldp_global/lldp_global.py
index e4fda3c7c..a5c872f6f 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lldp_global/lldp_global.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/lldp_global/lldp_global.py
@@ -80,7 +80,6 @@ class Lldp_global(ConfigBase):
commands.extend(self.set_config(existing_lldp_global_facts))
if commands and self.state in self.ACTION_STATES:
-
if not self._module.check_mode:
self._connection.edit_config(commands)
result["changed"] = True
@@ -136,6 +135,7 @@ class Lldp_global(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
+ commands = []
state = self._module.params["state"]
if state in ("merged", "replaced", "rendered") and not want:
self._module.fail_json(
@@ -148,7 +148,7 @@ class Lldp_global(ConfigBase):
commands = self._state_deleted(want, have)
elif state in ("merged", "rendered"):
commands = self._state_merged(want, have)
- elif state == "replaced":
+ elif state in ["replaced", "overridden"]:
commands = self._state_replaced(want, have)
return commands
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/logging_global/logging_global.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/logging_global/logging_global.py
index ff790e548..d3d5223be 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/logging_global/logging_global.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/logging_global/logging_global.py
@@ -178,7 +178,6 @@ class Logging_global(ResourceModule):
self.addcmd(hentry, x, negate=True)
def list_to_dict(self, config):
-
data = deepcopy(config)
if "tls_servers" in data:
data["tls_servers"] = {x["name"]: x for x in data["tls_servers"]}
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py
index 05ce42472..16e0bc3e9 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ospfv3/ospfv3.py
@@ -10,7 +10,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.rm_base.resource_module import (
@@ -107,22 +106,11 @@ class Ospfv3(ResourceModule):
haved = {k: v for k, v in iteritems(haved) if k in wantd or not wantd}
wantd = {}
- # delete processes first so we do run into "more than one" errors
- if self.state == "deleted":
- haved_del = deepcopy(haved)
- want_process = {}
- for k, t_want in iteritems(haved_del):
- want_process["process_id"] = t_want.get("process_id")
- if not (len(t_want) == 2 and not t_want.get("areas")):
- self._compare(want=want_process, have=haved_del.get(k, {}))
- if self.state == "overridden":
- haved_del = deepcopy(haved)
- want = {}
- for k, t_want in iteritems(haved_del):
+ # if state is overridden, first remove processes that are in have but not in want
+ if self.state in ["overridden", "deleted"]:
+ for k, have in iteritems(haved):
if k not in wantd:
- want["process_id"] = t_want.get("process_id")
- if not (len(t_want) == 2 and not t_want.get("areas")):
- self._compare(want=want, have=haved_del.get(k, {}))
+ self.addcmd(have, "pid", True)
for k, want in iteritems(wantd):
self._compare(want=want, have=haved.pop(k, {}))
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ping/ping.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ping/ping.py
index ce2a5229c..587fbde98 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ping/ping.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/ping/ping.py
@@ -84,7 +84,7 @@ class Ping:
Returns the percent of packet loss, received packets, transmitted packets, and RTT data.
"""
- if type(ping_results) == list:
+ if isinstance(ping_results, list):
ping_results = ping_results[0]
ping_data = PingTemplate(lines=ping_results.splitlines())
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/snmp_server/snmp_server.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/snmp_server/snmp_server.py
index 9ee3e1a12..b69f2abd7 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/snmp_server/snmp_server.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/snmp_server/snmp_server.py
@@ -281,7 +281,6 @@ class Snmp_server(ResourceModule):
"users",
"targets",
]:
-
wantx = want.get(x, {})
havex = have.get(x, {})
if "." in x:
@@ -350,7 +349,6 @@ class Snmp_server(ResourceModule):
return host_dict
def list_to_dict(self, config):
-
data = deepcopy(config)
if data.get("vrfs"):
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/static_routes/static_routes.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/static_routes/static_routes.py
index b558f01af..ce8694389 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/static_routes/static_routes.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/config/static_routes/static_routes.py
@@ -439,6 +439,57 @@ class Static_routes(ConfigBase):
return commands
+ def _static_route_popper(self, want_afi, have_afi):
+ """ """
+ commands = []
+
+ update_commands = []
+ if not want_afi.get("routes", []):
+ commands.append(
+ "no address-family {0} {1}".format(
+ have_afi["afi"],
+ have_afi["safi"],
+ ),
+ )
+ else:
+ for have_route in have_afi.get("routes", []):
+ want_route = (
+ search_obj_in_list(
+ have_route["dest"],
+ want_afi.get("routes", []),
+ key="dest",
+ )
+ or {}
+ )
+
+ rotated_want_next_hops = self.rotate_next_hops(
+ want_route.get("next_hops", {}),
+ )
+ rotated_have_next_hops = self.rotate_next_hops(
+ have_route.get("next_hops", {}),
+ )
+
+ for key in rotated_want_next_hops.keys():
+ if key in rotated_have_next_hops:
+ cmd = "no {0}".format(want_route["dest"])
+ for item in key:
+ if "." in item or ":" in item or "/" in item:
+ cmd += " {0}".format(item)
+ else:
+ cmd += " vrf {0}".format(item)
+ update_commands.append(cmd)
+ if update_commands:
+ update_commands.insert(
+ 0,
+ "address-family {0} {1}".format(
+ have_afi["afi"],
+ have_afi["safi"],
+ ),
+ )
+ commands.extend(update_commands)
+
+ return commands
+
def _state_deleted(self, want, have):
"""The command generator when state is deleted
@@ -460,12 +511,8 @@ class Static_routes(ConfigBase):
or {}
)
if have_afi:
- commands.append(
- "no address-family {0} {1}".format(
- have_afi["afi"],
- have_afi["safi"],
- ),
- )
+ commands.extend(self._static_route_popper(want_afi, have_afi))
+
if "vrf" in want and commands:
commands.insert(0, "vrf {0}".format(want["vrf"]))
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/__init__.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/__init__.py
index e69de29bb..e69de29bb 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/__init__.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/__init__.py
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/bgp_templates.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/bgp_templates.py
new file mode 100644
index 000000000..98889ae59
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/bgp_templates/bgp_templates.py
@@ -0,0 +1,89 @@
+# -*- coding: utf-8 -*-
+# Copyright 2023 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 iosxr bgp_templates fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.argspec.bgp_templates.bgp_templates import (
+ Bgp_templatesArgs,
+)
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.rm_templates.bgp_templates import (
+ Bgp_templatesTemplate,
+)
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.utils.utils import (
+ flatten_config,
+)
+
+
+class Bgp_templatesFacts(object):
+ """The iosxr bgp_templates facts class"""
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = Bgp_templatesArgs.argument_spec
+
+ def get_config(self, connection):
+ return connection.get("show running-config router bgp")
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Bgp_templates 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)
+ data = flatten_config(data, "neighbor-group")
+ # parse native config using the Bgp_templates template
+ bgp_templates_parser = Bgp_templatesTemplate(lines=data.splitlines(), module=self._module)
+ objs = bgp_templates_parser.parse()
+ if objs:
+ objs["neighbor"] = self._post_parse(objs).get(
+ "neighbor",
+ [],
+ )
+ ansible_facts["ansible_network_resources"].pop("bgp_templates", None)
+
+ params = utils.remove_empties(
+ bgp_templates_parser.validate_config(self.argument_spec, {"config": objs}, redact=True),
+ )
+
+ facts["bgp_templates"] = params.get("config", {})
+ ansible_facts["ansible_network_resources"].update(facts)
+
+ return ansible_facts
+
+ def _post_parse(self, data):
+ """Converts the intermediate data structure
+ to valid format as per argspec.
+ :param obj: dict
+ """
+ if "neighbor" in data:
+ data["neighbor"] = sorted(
+ list(data["neighbor"].values()),
+ key=lambda k, s="name": k[s],
+ )
+ for nbrg in data["neighbor"]:
+ if nbrg.get("address_family"):
+ nbrg["address_family"] = list(nbrg["address_family"].values())
+ return data
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/facts.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/facts.py
index 4d7e7b100..5cafa587d 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/facts.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/facts.py
@@ -34,6 +34,9 @@ from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.bg
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.bgp_neighbor_address_family.bgp_neighbor_address_family import (
Bgp_neighbor_address_familyFacts,
)
+from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.bgp_templates.bgp_templates import (
+ Bgp_templatesFacts,
+)
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.facts.hostname.hostname import (
HostnameFacts,
)
@@ -122,6 +125,7 @@ FACT_RESOURCE_SUBSETS = dict(
ntp_global=Ntp_globalFacts,
snmp_server=Snmp_serverFacts,
hostname=HostnameFacts,
+ bgp_templates=Bgp_templatesFacts,
)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/interfaces/interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/interfaces/interfaces.py
index e89dbca2e..5efcd6084 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/interfaces/interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/interfaces/interfaces.py
@@ -92,24 +92,24 @@ class InterfacesFacts(object):
config = deepcopy(spec)
match = re.search(r"^(\S+)", conf)
-
- intf = match.group(1)
- if match.group(1).lower() == "preconfigure":
- match = re.search(r"^(\S+) (.*)", conf)
- if match:
- intf = match.group(2)
-
- if get_interface_type(intf) == "unknown":
- return {}
- # populate the facts from the configuration
- config["name"] = intf
- config["description"] = utils.parse_conf_arg(conf, "description")
- if utils.parse_conf_arg(conf, "speed"):
- config["speed"] = int(utils.parse_conf_arg(conf, "speed"))
- if utils.parse_conf_arg(conf, "mtu"):
- config["mtu"] = int(utils.parse_conf_arg(conf, "mtu"))
- config["duplex"] = utils.parse_conf_arg(conf, "duplex")
- enabled = utils.parse_conf_cmd_arg(conf, "shutdown", False)
- config["enabled"] = enabled if enabled is not None else True
-
- return utils.remove_empties(config)
+ if match:
+ intf = match.group(1)
+ if match.group(1).lower() == "preconfigure":
+ match = re.search(r"^(\S+) (.*)", conf)
+ if match:
+ intf = match.group(2)
+
+ if get_interface_type(intf) == "unknown":
+ return {}
+ # populate the facts from the configuration
+ config["name"] = intf
+ config["description"] = utils.parse_conf_arg(conf, "description")
+ if utils.parse_conf_arg(conf, "speed"):
+ config["speed"] = int(utils.parse_conf_arg(conf, "speed"))
+ if utils.parse_conf_arg(conf, "mtu"):
+ config["mtu"] = int(utils.parse_conf_arg(conf, "mtu"))
+ config["duplex"] = utils.parse_conf_arg(conf, "duplex")
+ enabled = utils.parse_conf_cmd_arg(conf, "shutdown", False)
+ config["enabled"] = enabled if enabled is not None else True
+
+ return utils.remove_empties(config)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l2_interfaces/l2_interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l2_interfaces/l2_interfaces.py
index cdb1d72cf..f562e20f8 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l2_interfaces/l2_interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l2_interfaces/l2_interfaces.py
@@ -93,18 +93,17 @@ class L2_InterfacesFacts(object):
"""
config = deepcopy(spec)
match = re.search(r"^(\S+)", conf)
+ if match:
+ intf = match.group(1)
- intf = match.group(1)
+ if intf.lower() == "preconfigure":
+ match = re.search(r"^(\S+) (.*)", conf)
+ if match:
+ intf = match.group(2)
- if match.group(1).lower() == "preconfigure":
- match = re.search(r"^(\S+) (.*)", conf)
- if match:
- intf = match.group(2)
+ if get_interface_type(intf) == "unknown":
+ return {}
- if get_interface_type(intf) == "unknown":
- return {}
-
- if intf.lower().startswith("gi"):
config["name"] = intf
# populate the facts from the configuration
@@ -128,11 +127,11 @@ class L2_InterfacesFacts(object):
encapsulation.group(2).split("second-dot1q ")[1],
)
else:
- config["q_vlan"] = []
+ config["qvlan"] = []
if dot1q:
- config["q_vlan"].append(int(dot1q.split(" ")[0]))
+ config["qvlan"].append(dot1q.split(" ")[0])
if len(dot1q.split(" ")) > 1:
- config["q_vlan"].append(int(dot1q.split(" ")[2]))
+ config["qvlan"].append(dot1q.split(" ")[2])
if utils.parse_conf_cmd_arg(conf, "l2transport", True):
config["l2transport"] = True
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l3_interfaces/l3_interfaces.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l3_interfaces/l3_interfaces.py
index bf5ce5f85..b4dba858e 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l3_interfaces/l3_interfaces.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/l3_interfaces/l3_interfaces.py
@@ -27,6 +27,7 @@ from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.argspec.
)
from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.utils.utils import (
get_interface_type,
+ netmask_to_cidr,
)
@@ -93,39 +94,45 @@ class L3_InterfacesFacts(object):
"""
config = deepcopy(spec)
match = re.search(r"^(\S+)", conf)
-
- intf = match.group(1)
- if match.group(1).lower() == "preconfigure":
- match = re.search(r"^(\S+) (.*)", conf)
- if match:
- intf = match.group(2)
-
- if get_interface_type(intf) == "unknown":
- return {}
-
- # populate the facts from the configuration
- config["name"] = intf
-
- # Get the configured IPV4 details
- ipv4 = []
- ipv4_all = re.findall(r"ipv4 address (\S+.*)", conf)
- for each in ipv4_all:
- each_ipv4 = dict()
- if "secondary" in each:
- each_ipv4["address"] = each.split(" secondary")[0]
- each_ipv4["secondary"] = True
- else:
- each_ipv4["address"] = each
- ipv4.append(each_ipv4)
- config["ipv4"] = ipv4
-
- # Get the configured IPV6 details
- ipv6 = []
- ipv6_all = re.findall(r"ipv6 address (\S+)", conf)
- for each in ipv6_all:
- each_ipv6 = dict()
- each_ipv6["address"] = each
- ipv6.append(each_ipv6)
- config["ipv6"] = ipv6
-
- return utils.remove_empties(config)
+ if match:
+ intf = match.group(1)
+ if match.group(1).lower() == "preconfigure":
+ match = re.search(r"^(\S+) (.*)", conf)
+ if match:
+ intf = match.group(2)
+
+ if get_interface_type(intf) == "unknown":
+ return {}
+
+ # populate the facts from the configuration
+ config["name"] = intf
+
+ # Get the configured IPV4 details
+ ipv4 = []
+ ipv4_all = re.findall(r"ipv4 address (\S+.*)", conf)
+ for each in ipv4_all:
+ each_ipv4 = dict()
+ if "secondary" in each:
+ each_ipv4["address"] = self.format_ipv4(each.split(" secondary")[0])
+ each_ipv4["secondary"] = True
+ elif "secondary" not in each and "dhcp" not in each:
+ each_ipv4["address"] = self.format_ipv4(each)
+ elif "dhcp" in each:
+ each_ipv4["address"] = "dhcp"
+ ipv4.append(each_ipv4)
+ config["ipv4"] = ipv4
+
+ # Get the configured IPV6 details
+ ipv6 = []
+ ipv6_all = re.findall(r"ipv6 address (\S+)", conf)
+ for each in ipv6_all:
+ each_ipv6 = dict()
+ each_ipv6["address"] = each
+ ipv6.append(each_ipv6)
+ config["ipv6"] = ipv6
+ return utils.remove_empties(config)
+
+ def format_ipv4(self, address):
+ if address.split(" ")[1]:
+ cidr_val = netmask_to_cidr(address.split(" ")[1])
+ return address.split(" ")[0] + "/" + cidr_val
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/legacy/base.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/legacy/base.py
index 9e346d36c..cc657f42a 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/legacy/base.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/legacy/base.py
@@ -30,7 +30,6 @@ from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.iosxr im
class FactsBase(object):
-
COMMANDS = frozenset()
def __init__(self, module):
@@ -58,8 +57,7 @@ class Default(FactsBase):
device_info = resp["device_info"]
platform_facts["system"] = device_info["network_os"]
-
- for item in ("model", "image", "version", "platform", "hostname"):
+ for item in ("serialnum", "model", "image", "version", "platform", "hostname"):
val = device_info.get("network_os_%s" % item)
if val:
platform_facts[item] = val
@@ -71,13 +69,14 @@ class Default(FactsBase):
class Hardware(FactsBase):
-
- COMMANDS = ["dir /all", "show memory summary"]
+ COMMANDS = ["dir /all", "show memory summary", "show processes cpu | include CPU utilization"]
def populate(self):
super(Hardware, self).populate()
+
data = self.responses[0]
self.facts["filesystems"] = self.parse_filesystems(data)
+ self.facts["cpu_utilization"] = self.parse_cpu_utilization(self.responses[2])
data = self.responses[1]
match = re.search(r"Physical Memory: (\d+)M total \((\d+)", data)
@@ -88,9 +87,29 @@ class Hardware(FactsBase):
def parse_filesystems(self, data):
return re.findall(r"^Directory of (\S+)", data, re.M)
+ def parse_cpu_utilization(self, data):
+ facts = {}
+ cpu_utilization_regex = re.compile(
+ r"""
+ ^CPU\sutilization\sfor\sone\sminute:(\s(?P<one_min>[0-9]+)?%)?;
+ \sfive\sminutes:\s(?P<five_mins>[0-9]+)?%;
+ \sfifteen\sminutes:\s(?P<fifteen_mins>[0-9]+)?%
+ """,
+ re.VERBOSE,
+ )
-class Config(FactsBase):
+ for line in data.split("\n"):
+ cpu_utilization_match = cpu_utilization_regex.match(line)
+ if cpu_utilization_match:
+ facts["one_minute"] = int(cpu_utilization_match.group("one_min"))
+ facts["five_minutes"] = int(cpu_utilization_match.group("five_mins"))
+ facts["fifteen_minutes"] = int(cpu_utilization_match.group("fifteen_mins"))
+
+ return facts
+
+
+class Config(FactsBase):
COMMANDS = ["show running-config"]
def populate(self):
@@ -99,7 +118,6 @@ class Config(FactsBase):
class Interfaces(FactsBase):
-
COMMANDS = [
"show interfaces",
"show ipv6 interface",
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv2/ospfv2.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv2/ospfv2.py
index 240ecb4d5..b5c2693f1 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv2/ospfv2.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv2/ospfv2.py
@@ -19,7 +19,7 @@ import re
from copy import deepcopy
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv3/ospfv3.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv3/ospfv3.py
index 49302ce9b..d34f15fbd 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv3/ospfv3.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/facts/ospfv3/ospfv3.py
@@ -13,7 +13,7 @@ import re
from copy import deepcopy
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/iosxr.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/iosxr.py
index ea15fdfcd..c7498aa19 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/iosxr.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/iosxr.py
@@ -36,7 +36,6 @@ import re
from difflib import Differ
from ansible.module_utils._text import to_bytes, to_text
-from ansible.module_utils.basic import env_fallback
from ansible.module_utils.connection import Connection, ConnectionError
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.netconf import (
NetconfConnection,
@@ -146,7 +145,6 @@ def build_xml_subtree(container_ele, xmap, param=None, opcode=None):
if (
opcode in ("delete", "merge") and meta.get("operation", "unknown") == "edit"
) or meta.get("operation", None) is None:
-
if meta.get("tag", False) is True:
if parent.tag == container_ele.tag:
if meta.get("ns", False) is True:
@@ -430,7 +428,6 @@ def load_config(
nc_get_filter=None,
label=None,
):
-
conn = get_connection(module)
diff = None
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/address_family.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/address_family.py
deleted file mode 100644
index 0d5393407..000000000
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/address_family.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#
-# (c) 2019, Ansible by Red Hat, inc
-# 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
-import re
-
-from ansible.module_utils.six import iteritems
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
-
-from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.providers import (
- CliProvider,
-)
-
-
-class AddressFamily(CliProvider):
- def render(self, config=None):
- commands = list()
- safe_list = list()
-
- router_context = "router bgp %s" % self.get_value("config.bgp_as")
- context_config = None
-
- for item in self.get_value("config.address_family"):
- context = "address-family %s %s" % (item["afi"], item["safi"])
- context_commands = list()
-
- if config:
- context_path = [router_context, context]
- context_config = self.get_config_context(
- config,
- context_path,
- indent=1,
- )
-
- for key, value in iteritems(item):
- if value is not None:
- meth = getattr(self, "_render_%s" % key, None)
- if meth:
- resp = meth(item, context_config)
- if resp:
- context_commands.extend(to_list(resp))
-
- if context_commands:
- commands.append(context)
- commands.extend(context_commands)
- commands.append("exit")
-
- safe_list.append(context)
-
- if config:
- resp = self._negate_config(config, safe_list)
- commands.extend(resp)
-
- return commands
-
- def _negate_config(self, config, safe_list=None):
- commands = list()
- matches = re.findall(r"(address-family .+)$", config, re.M)
- for item in set(matches).difference(safe_list):
- commands.append("no %s" % item)
- return commands
-
- def _render_networks(self, item, config=None):
- commands = list()
- safe_list = list()
-
- for entry in item["networks"]:
- network = entry["prefix"]
- if entry["masklen"]:
- network = "%s/%s" % (entry["prefix"], entry["masklen"])
- safe_list.append(network)
-
- cmd = "network %s" % network
-
- if entry["route_map"]:
- cmd += " route-policy %s" % entry["route_map"]
-
- if not config or cmd not in config:
- commands.append(cmd)
-
- if config and self.params["operation"] == "replace":
- matches = re.findall(r"network (\S+)", config, re.M)
- for entry in set(matches).difference(safe_list):
- commands.append("no network %s" % entry)
-
- return commands
-
- def _render_redistribute(self, item, config=None):
- commands = list()
- safe_list = list()
-
- for entry in item["redistribute"]:
- option = entry["protocol"]
-
- cmd = "redistribute %s" % entry["protocol"]
-
- if entry["id"] and entry["protocol"] in (
- "ospf",
- "eigrp",
- "isis",
- "ospfv3",
- ):
- cmd += " %s" % entry["id"]
- option += " %s" % entry["id"]
-
- if entry["metric"]:
- cmd += " metric %s" % entry["metric"]
-
- if entry["route_map"]:
- cmd += " route-policy %s" % entry["route_map"]
-
- if not config or cmd not in config:
- commands.append(cmd)
-
- safe_list.append(option)
-
- if self.params["operation"] == "replace":
- if config:
- matches = re.findall(
- r"redistribute (\S+)(?:\s*)(\d*)",
- config,
- re.M,
- )
- for i in range(0, len(matches)):
- matches[i] = " ".join(matches[i]).strip()
- for entry in set(matches).difference(safe_list):
- commands.append("no redistribute %s" % entry)
-
- return commands
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/neighbors.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/neighbors.py
deleted file mode 100644
index 29e4a1d2e..000000000
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/neighbors.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#
-# (c) 2019, Ansible by Red Hat, inc
-# 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
-import re
-import socket
-
-from ansible.module_utils.six import iteritems
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
-
-from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.providers import (
- CliProvider,
-)
-
-
-class Neighbors(CliProvider):
- def render(self, config=None):
- commands = list()
- safe_list = list()
-
- router_context = "router bgp %s" % self.get_value("config.bgp_as")
- context_config = None
-
- for item in self.get_value("config.neighbors"):
- context_commands = list()
-
- neighbor = item["neighbor"]
-
- try:
- socket.inet_aton(neighbor)
- context = "neighbor %s" % neighbor
- except socket.error:
- context = "neighbor-group %s" % neighbor
-
- if config:
- context_path = [router_context, context]
- context_config = self.get_config_context(
- config,
- context_path,
- indent=1,
- )
-
- for key, value in iteritems(item):
- if value is not None:
- meth = getattr(self, "_render_%s" % key, None)
- if meth:
- resp = meth(item, context_config)
- if resp:
- context_commands.extend(to_list(resp))
-
- if context_commands:
- commands.append(context)
- commands.extend(context_commands)
- commands.append("exit")
-
- safe_list.append(context)
-
- if config and safe_list:
- commands.extend(self._negate_config(config, safe_list))
-
- return commands
-
- def _negate_config(self, config, safe_list=None):
- commands = list()
- matches = re.findall(r"(neighbor \S+)", config, re.M)
- for item in set(matches).difference(safe_list):
- commands.append("no %s" % item)
- return commands
-
- def _render_remote_as(self, item, config=None):
- cmd = "remote-as %s" % item["remote_as"]
- if not config or cmd not in config:
- return cmd
-
- def _render_description(self, item, config=None):
- cmd = "description %s" % item["description"]
- if not config or cmd not in config:
- return cmd
-
- def _render_enabled(self, item, config=None):
- cmd = "shutdown"
- if item["enabled"] is True:
- cmd = "no %s" % cmd
- if not config or cmd not in config:
- return cmd
-
- def _render_update_source(self, item, config=None):
- cmd = "update-source %s" % item["update_source"].replace(" ", "")
- if not config or cmd not in config:
- return cmd
-
- def _render_password(self, item, config=None):
- cmd = "password %s" % item["password"]
- if not config or cmd not in config:
- return cmd
-
- def _render_ebgp_multihop(self, item, config=None):
- cmd = "ebgp-multihop %s" % item["ebgp_multihop"]
- if not config or cmd not in config:
- return cmd
-
- def _render_tcp_mss(self, item, config=None):
- cmd = "tcp mss %s" % item["tcp_mss"]
- if not config or cmd not in config:
- return cmd
-
- def _render_advertisement_interval(self, item, config=None):
- cmd = "advertisement-interval %s" % item["advertisement_interval"]
- if not config or cmd not in config:
- return cmd
-
- def _render_neighbor_group(self, item, config=None):
- cmd = "use neighbor-group %s" % item["neighbor_group"]
- if not config or cmd not in config:
- return cmd
-
- def _render_timers(self, item, config):
- """generate bgp timer related configuration"""
- keepalive = item["timers"]["keepalive"]
- holdtime = item["timers"]["holdtime"]
- min_neighbor_holdtime = item["timers"]["min_neighbor_holdtime"]
-
- if keepalive and holdtime:
- cmd = "timers %s %s" % (keepalive, holdtime)
- if min_neighbor_holdtime:
- cmd += " %s" % min_neighbor_holdtime
- if not config or cmd not in config:
- return cmd
- else:
- raise ValueError(
- "required both options for timers: keepalive and holdtime",
- )
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/process.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/process.py
deleted file mode 100644
index bd2c08ae1..000000000
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/cli/config/bgp/process.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#
-# (c) 2019, Ansible by Red Hat, inc
-# 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
-import re
-
-from ansible.module_utils.six import iteritems
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
-
-from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.cli.config.bgp.address_family import (
- AddressFamily,
-)
-from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.cli.config.bgp.neighbors import (
- Neighbors,
-)
-from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers.providers import (
- CliProvider,
- register_provider,
-)
-
-
-REDISTRIBUTE_PROTOCOLS = [
- "ospf",
- "ospfv3",
- "eigrp",
- "isis",
- "static",
- "connected",
- "lisp",
- "mobile",
- "rip",
- "subscriber",
-]
-
-
-@register_provider("iosxr", "iosxr_bgp")
-class Provider(CliProvider):
- def render(self, config=None):
- commands = list()
-
- existing_as = None
- if config:
- match = re.search(r"router bgp (\d+)", config, re.M)
- if match:
- existing_as = match.group(1)
-
- operation = self.params["operation"]
-
- context = None
-
- if self.params["config"]:
- context = "router bgp %s" % self.get_value("config.bgp_as")
-
- if operation == "delete":
- if existing_as:
- commands.append("no router bgp %s" % existing_as)
- elif context:
- commands.append("no %s" % context)
-
- else:
- if operation == "replace":
- if existing_as and int(existing_as) != self.get_value(
- "config.bgp_as",
- ):
- # The negate command has to be committed before new BGP AS is used.
- self.connection.edit_config(
- "no router bgp %s" % existing_as,
- )
- config = None
-
- elif operation == "override":
- if existing_as:
- # The negate command has to be committed before new BGP AS is used.
- self.connection.edit_config(
- "no router bgp %s" % existing_as,
- )
- config = None
-
- context_commands = list()
-
- for key, value in iteritems(self.get_value("config")):
- if value is not None:
- meth = getattr(self, "_render_%s" % key, None)
- if meth:
- resp = meth(config)
- if resp:
- context_commands.extend(to_list(resp))
-
- if context and context_commands:
- commands.append(context)
- commands.extend(context_commands)
- commands.append("exit")
-
- return commands
-
- def _render_router_id(self, config=None):
- cmd = "bgp router-id %s" % self.get_value("config.router_id")
- if not config or cmd not in config:
- return cmd
-
- def _render_log_neighbor_changes(self, config=None):
- cmd = "bgp log neighbor changes"
- log_neighbor_changes = self.get_value("config.log_neighbor_changes")
- if log_neighbor_changes is True:
- if not config or cmd not in config:
- return "%s detail" % cmd
- elif log_neighbor_changes is False:
- if config and cmd in config:
- return "%s disable" % cmd
-
- def _render_neighbors(self, config):
- """generate bgp neighbor configuration"""
- return Neighbors(self.params).render(config)
-
- def _render_address_family(self, config):
- """generate address-family configuration"""
- return AddressFamily(self.params).render(config)
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/module.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/module.py
deleted file mode 100644
index afb9b9e7e..000000000
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/module.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# (c) 2019, Ansible by Red Hat, inc
-# 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
-from ansible.module_utils._text import to_text
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.connection import Connection
-
-from ansible_collections.cisco.iosxr.plugins.module_utils.network.iosxr.providers import providers
-
-
-class NetworkModule(AnsibleModule):
-
- fail_on_missing_provider = True
-
- def __init__(self, connection=None, *args, **kwargs):
- super(NetworkModule, self).__init__(*args, **kwargs)
-
- if connection is None:
- connection = Connection(self._socket_path)
-
- self.connection = connection
-
- @property
- def provider(self):
- if not hasattr(self, "_provider"):
- capabilities = self.from_json(self.connection.get_capabilities())
-
- network_os = capabilities["device_info"]["network_os"]
- network_api = capabilities["network_api"]
-
- if network_api == "cliconf":
- connection_type = "network_cli"
-
- cls = providers.get(
- network_os,
- self._name.split(".")[-1],
- connection_type,
- )
-
- if not cls:
- msg = "unable to find suitable provider for network os %s" % network_os
- if self.fail_on_missing_provider:
- self.fail_json(msg=msg)
- else:
- self.warn(msg)
-
- obj = cls(self.params, self.connection, self.check_mode)
-
- setattr(self, "_provider", obj)
-
- return getattr(self, "_provider")
-
- def get_facts(self, subset=None):
- try:
- self.provider.get_facts(subset)
- except Exception as exc:
- self.fail_json(msg=to_text(exc))
-
- def edit_config(self, config_filter=None):
- current_config = self.connection.get_config(flags=config_filter)
- try:
- commands = self.provider.edit_config(current_config)
- changed = bool(commands)
- return {"commands": commands, "changed": changed}
- except Exception as exc:
- self.fail_json(msg=to_text(exc))
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/providers.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/providers.py
deleted file mode 100644
index 94220ffaf..000000000
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/providers/providers.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#
-# (c) 2019, Ansible by Red Hat, inc
-# 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
-import json
-
-from threading import RLock
-
-from ansible.module_utils.six import itervalues
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.config import (
- NetworkConfig,
-)
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
-
-
-_registered_providers = {}
-_provider_lock = RLock()
-
-
-def register_provider(network_os, module_name):
- def wrapper(cls):
- _provider_lock.acquire()
- try:
- if network_os not in _registered_providers:
- _registered_providers[network_os] = {}
- for ct in cls.supported_connections:
- if ct not in _registered_providers[network_os]:
- _registered_providers[network_os][ct] = {}
- for item in to_list(module_name):
- for entry in itervalues(_registered_providers[network_os]):
- entry[item] = cls
- finally:
- _provider_lock.release()
- return cls
-
- return wrapper
-
-
-def get(network_os, module_name, connection_type):
- network_os_providers = _registered_providers.get(network_os)
- if network_os_providers is None:
- raise ValueError("unable to find a suitable provider for this module")
- if connection_type not in network_os_providers:
- raise ValueError("provider does not support this connection type")
- elif module_name not in network_os_providers[connection_type]:
- raise ValueError("could not find a suitable provider for this module")
- return network_os_providers[connection_type][module_name]
-
-
-class ProviderBase(object):
-
- supported_connections = ()
-
- def __init__(self, params, connection=None, check_mode=False):
- self.params = params
- self.connection = connection
- self.check_mode = check_mode
-
- @property
- def capabilities(self):
- if not hasattr(self, "_capabilities"):
- resp = self.from_json(self.connection.get_capabilities())
- setattr(self, "_capabilities", resp)
- return getattr(self, "_capabilities")
-
- def get_value(self, path):
- params = self.params.copy()
- for key in path.split("."):
- params = params[key]
- return params
-
- def get_facts(self, subset=None):
- raise NotImplementedError(self.__class__.__name__)
-
- def edit_config(self):
- raise NotImplementedError(self.__class__.__name__)
-
-
-class CliProvider(ProviderBase):
-
- supported_connections = ("network_cli",)
-
- @property
- def capabilities(self):
- if not hasattr(self, "_capabilities"):
- resp = self.from_json(self.connection.get_capabilities())
- setattr(self, "_capabilities", resp)
- return getattr(self, "_capabilities")
-
- def get_config_context(self, config, path, indent=1):
- if config is not None:
- netcfg = NetworkConfig(indent=indent, contents=config)
- try:
- config = netcfg.get_block_config(to_list(path))
- except ValueError:
- config = None
- return config
-
- def render(self, config=None):
- raise NotImplementedError(self.__class__.__name__)
-
- def cli(self, command):
- try:
- if not hasattr(self, "_command_output"):
- setattr(self, "_command_output", {})
- return self._command_output[command]
- except KeyError:
- out = self.connection.get(command)
- try:
- out = json.loads(out)
- except ValueError:
- pass
- self._command_output[command] = out
- return out
-
- def get_facts(self, subset=None):
- return self.populate()
-
- def edit_config(self, config=None):
- commands = self.render(config)
- if commands and self.check_mode is False:
- self.connection.edit_config(commands)
- return commands
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_address_family.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_address_family.py
index a1d9bfda8..f5ced0b0b 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_address_family.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_address_family.py
@@ -74,7 +74,6 @@ def _tmpl_bgp_dampening(config_data):
def _tmpl_maximum_paths_ibgp(config_data):
-
ibgp_conf = config_data.get("maximum_paths", {}).get("ibgp", {})
if ibgp_conf:
command = "maximum-paths ibgp"
@@ -97,7 +96,6 @@ def _tmpl_maximum_paths_ibgp(config_data):
def _tmpl_maximum_paths_ebgp(config_data):
-
ebgp_conf = config_data.get("maximum_paths", {}).get("ebgp", {})
if ebgp_conf:
command = "maximum-paths ebgp"
@@ -111,7 +109,6 @@ def _tmpl_maximum_paths_ebgp(config_data):
def _tmpl_maximum_paths_eibgp(config_data):
-
eibgp_conf = config_data.get("maximum_paths", {}).get("eibgp", {})
if eibgp_conf:
command = "maximum-paths ebgp"
@@ -137,7 +134,6 @@ def _tmpl_nexthop(config_data):
nexthop_conf = config_data.get("nexthop", {})
commands = []
if nexthop_conf:
-
if "resolution_prefix_length_minimum" in nexthop_conf:
command = "nexthop resolution prefix-length minimum " + str(
nexthop_conf["resolution_prefix_length_minimum"],
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_global.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_global.py
index f584d13f5..c1a5962c7 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_global.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_global.py
@@ -32,6 +32,21 @@ def _tmplt_confederation_peers(config_data):
return cmds
+def _templ_local_as(config_data):
+ conf = config_data.get("local_as", {})
+ if conf.get("value"):
+ command = "local-as " + str(conf.get("value", {}))
+ if "no_prepend" in conf:
+ if "replace_as" in conf.get("no_prepend", {}):
+ if "dual_as" in conf.get("no_prepend", {}).get("replace_as", {}):
+ command += " no-prepend replace-as dual-as"
+ elif "set" in conf.get("no_prepend", {}).get("replace_as", {}):
+ command += " no-prepend replace-as"
+ elif "set" in conf.get("no_prepend", {}):
+ command += " no-prepend"
+ return command
+
+
class Bgp_globalTemplate(NetworkTemplate):
def __init__(self, lines=None, module=None):
super(Bgp_globalTemplate, self).__init__(
@@ -2052,10 +2067,12 @@ class Bgp_globalTemplate(NetworkTemplate):
r"""
\s+(?P<nbr_address>neighbor\s\S+)
\s(?P<local_as>local-as\s\S+)
+ (\s(?P<no_prepend>no-prepend))?
+ (\s(?P<replace_as>replace-as))?
+ (\s(?P<dual_as>dual-as))?
$""", re.VERBOSE,
),
- "setval": "local-as {{ local_as.value }}",
- "compval": "local_as.value",
+ "setval": _templ_local_as,
"result": {
"vrfs": {
'{{ "vrf_" + vrf|d() }}': {
@@ -2063,6 +2080,14 @@ class Bgp_globalTemplate(NetworkTemplate):
"{{nbr_address.split(" ")[1]}}": {
"local_as": {
"value": "{{ local_as.split(" ")[1] }}",
+ "no_prepend":
+ {
+ "set": "{{ True if no_prepend is defined and replace_as is undefined and dual_as is undefined else None}}",
+ "replace_as": {
+ "set": "{{ True if replace_as is defined and dual_as is undefined}}",
+ "dual_as": "{{ not not dual_as}}",
+ },
+ },
},
},
},
@@ -2152,6 +2177,55 @@ class Bgp_globalTemplate(NetworkTemplate):
},
},
{
+ "name": "password_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+(?P<nbr_address>neighbor\s\S+)
+ \s(?P<password>password\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "password inheritance-disable",
+ "compval": "password.inheritance_disable",
+ "result": {
+ "vrfs": {
+ '{{ "vrf_" + vrf|d() }}': {
+ "neighbors": {
+ "{{nbr_address.split(" ")[1]}}": {
+ "password": {
+ "inheritance_disable": "{{ True if password is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "password_encrypted",
+ "getval": re.compile(
+ r"""
+ \s+(?P<nbr_address>neighbor\s\S+)
+ \spassword\sencrypted
+ \s(?P<password>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "password encrypted {{password.encrypted}}",
+ "compval": "password.encrypted",
+ "result": {
+ "vrfs": {
+ '{{ "vrf_" + vrf|d() }}': {
+ "neighbors": {
+ "{{nbr_address.split(" ")[1]}}": {
+ "password": {
+ "encrypted": "{{ password }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
"name": "receive_buffer_size",
"getval": re.compile(
r"""
@@ -2360,6 +2434,52 @@ class Bgp_globalTemplate(NetworkTemplate):
},
},
{
+ "name": "use.neighbor_group",
+ "getval": re.compile(
+ r"""
+ \s+(?P<nbr_address>neighbor\s\S+)
+ \suse\sneighbor-group\s(?P<neighbor_group>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "use neighbor-group {{ use.neighbor_group }}",
+ "result": {
+ "vrfs": {
+ '{{ "vrf_" + vrf|d() }}': {
+ "neighbors": {
+ "{{nbr_address.split(" ")[1]}}": {
+ "use": {
+ "neighbor_group": "{{ neighbor_group }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "use.session_group",
+ "getval": re.compile(
+ r"""
+ \s+(?P<nbr_address>neighbor\s\S+)
+ \suse\ssession-group\s(?P<session_group>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "use session-group {{ use.session_group }}",
+ "result": {
+ "vrfs": {
+ '{{ "vrf_" + vrf|d() }}': {
+ "neighbors": {
+ "{{nbr_address.split(" ")[1]}}": {
+ "use": {
+ "session_group": "{{ session_group }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
"name": "update_source",
"getval": re.compile(
r"""
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_templates.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_templates.py
new file mode 100644
index 000000000..f0274944c
--- /dev/null
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/bgp_templates.py
@@ -0,0 +1,2816 @@
+# -*- coding: utf-8 -*-
+# Copyright 2023 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 Bgp_templates 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,
+)
+
+
+UNIQUE_NEIB_ADD = "{{ nbr_address }}"
+
+
+def _tmpl_maximum_prefix(config_data):
+ conf = config_data.get("maximum_prefix", {})
+ if conf:
+ command = "maximum-prefix"
+ if "max_limit" in conf:
+ command += " " + str(conf["max_limit"])
+ if "threshold_value" in conf:
+ command += " " + str(conf["threshold_value"])
+ if "restart" in conf:
+ command += " restart " + str(conf["restart"])
+ elif "warning_only" in conf:
+ command += " warning-only"
+ elif "discard_extra_paths" in conf:
+ command += " discard-extra-paths"
+
+ return command
+
+
+def _tmpl_soft_reconfiguration(config_data):
+ conf = config_data.get("soft_reconfiguration", {})
+ if conf:
+ command = "soft-reconfiguration "
+ if "inbound" in conf:
+ command += "inbound"
+ if "set" in conf["inbound"]:
+ pass
+ elif "always" in conf["inbound"]:
+ command += " always"
+ if "inheritance_disable" in conf["inbound"]:
+ command += " inheritance-disable"
+
+ return command
+
+
+def _tmpl_remove_private_AS(config_data):
+ conf = config_data.get("remove_private_AS", {})
+ if conf:
+ command = "remove-private-AS"
+ if "inbound" in conf:
+ command += " inbound"
+ if "entire_aspath" in conf:
+ command += " entire-aspath"
+ if "inheritance_disable" in conf:
+ command += " inheritance-disable"
+ return command
+
+
+def _templ_local_as(config_data):
+ conf = config_data.get("local_as", {})
+ if conf.get("value"):
+ command = "local-as " + str(conf.get("value", {}))
+ if "no_prepend" in conf:
+ command = "local-as"
+ if "replace_as" in conf.get("no_prepend", {}):
+ if "dual_as" in conf.get("no_prepend", {}).get("replace_as", {}):
+ command += " no-prepend replace-as dual-as"
+ elif "set" in conf.get("no_prepend", {}).get("replace_as", {}):
+ command += " no-prepend replace-as"
+ elif "set" in conf.get("no_prepend", {}):
+ command += " no-prepend"
+ return command
+
+
+class Bgp_templatesTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ super(Bgp_templatesTemplate, self).__init__(
+ lines=lines,
+ tmplt=self,
+ module=module,
+ )
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "router",
+ "getval": re.compile(
+ r"""
+ ^router\s
+ bgp
+ \s(?P<as_num>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "router bgp {{ as_number }}",
+ "compval": "as_number",
+ "result": {"as_number": "{{ as_num }}"},
+ "shared": True,
+ },
+ {
+ "name": "address_family",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ (?P<address_family>\s+address-family\s(?P<afi>\S+)\s(?P<safi>\S+))
+ $""", re.VERBOSE,
+ ),
+ "setval": "address-family {{ afi}} {{safi}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "afi": "{{ afi}}",
+ "safi": "{{safi}}",
+ },
+ },
+ },
+ },
+ },
+ "shared": True,
+ },
+ {
+ "name": "neighbor_group",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "neighbor-group {{ name}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "name": UNIQUE_NEIB_ADD,
+ },
+ },
+ },
+ "shared": True,
+ },
+ {
+ "name": "signalling",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sSignalling(?P<signalling>)
+ (\sbgp\sdisable(?P<b_disable>))?
+ (\sldp\sdisable(?P<l_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "{{ 'signalling bgp disable' if signalling.bgp_disable else 'signalling ldp disable' }} ",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "signalling": {
+ "bgp_disable": "{{ True if b_disable is defined }}",
+ "ldp_disable": "{{ True if l_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "advertise.local_labeled_route.set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ (?P<a_Set>\sadvertise\slocal-labeled-route(?P<a_set>))
+ $""", re.VERBOSE,
+ ),
+ "setval": "advertise local-labeled-route",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "advertise": {
+ "local_labeled_route": {
+ "set": "{{ True if a_set is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "advertise.local_labeled_route.disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sadvertise
+ (\slocal-labeled-route\sdisable(?P<l_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "advertise local-labeled-route disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "advertise": {
+ "local_labeled_route": {
+ "disable": "{{ True if l_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "advertise.permanent_network",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sadvertise
+ (\spermanent-network(?P<set>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "advertise permanent-network",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "advertise": {
+ "permanent_network": "{{ True if set is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "aigp.set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ (?P<aigp>\saigp)
+ $""", re.VERBOSE,
+ ),
+ "setval": "aigp",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "aigp": {
+ "set": "{{ True if aigp is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "aigp.disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \saigp(?P<aigp>)
+ (\sdisable(?P<disable>))
+ $""", re.VERBOSE,
+ ),
+ "setval": "aigp disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "aigp": {
+ "disable": "{{ True if disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "aigp.send_med",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \saigp(?P<aigp>)
+ (\ssend\smed(?P<send_med>))?
+ (\ssend\smed\sdisable(?P<send_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "'aigp send med disable' if {{aigp.send_med.disable}} is defined else 'aigp send med'",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "aigp": {
+ "send_med": {
+ "set": "{{ True if send_med is defined }}",
+ "disable": "{{ True if send_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "aigp.send_cost_community_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \saigp(?P<aigp>)
+ (\ssend\scost-community\sdisable(?P<cc_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "aigp send cost-community disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "aigp": {
+ "send_cost_community_disable": "{{True if cc_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "allowas_in",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sallowas-in(?P<allowas_in>)(\s(?P<value>\S+))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "allowas-in {{allowas_in.value if allowas_in.value is defined }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "allowas_in": {
+ "set": "{{True if allowas_in is defined and value is not defined}}",
+ "value": "{{value }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "as_override",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sas-override(?P<as_override>)
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "as-override{{' inheritance-disable' if as_override.inheritance_disable is defined else ''}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "as_override": {
+ "set": "{{True if as_override is defined "
+ "and inheritance_disable is not defined}}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "bestpath_origin_as_allow_invalid",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbestpath\sorigin-as\sallow\sinvalid(?P<invalid>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bestpath origin-as allow invalid",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "bestpath_origin_as_allow_invalid": "{{ True if invalid is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "capability_orf_prefix",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability\sorf\sprefix\s(?P<capability_orf_prefix>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability orf prefix {{capability_orf_prefix }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "capability_orf_prefix": "{{capability_orf_prefix}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "default_originate.set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+default-originate(?P<default_originate>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "default-originate",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi}}': {
+ "default_originate": {
+ "set": "{{True if default_originate is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "default_originate.route_policy",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+default-originate(?P<default_originate>)
+ (\sroute-policy\s(?P<route_policy>\S+))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "default-originate route-policy {{default_originate.route_policy}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi}}': {
+ "default_originate": {
+ "route_policy": "{{route_policy}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "default_originate.inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+default-originate\s(?P<disable>inheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "default-originate inheritance-disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi}}': {
+ "default_originate": {
+ "inheritance_disable": "{{true if disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "encapsulation_type_srv6",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sencapsulation-type\ssrv6(?P<encapsulation_type_srv6>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "encapsulation-type srv6",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "encapsulation_type_srv6": "{{true if encapsulation_type_srv6 is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "long_lived_graceful_restart_capable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+long-lived-graceful-restart
+ \s(?P<capable>capable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "long-lived-graceful-restart capable",
+ "compval": "long_lived_graceful_restart.capable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "long_lived_graceful_restart": {
+ "capable": "{{True if capable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "long_lived_graceful_restart_stale_time",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+long-lived-graceful-restart
+ \s+stale-time\ssend\s(?P<stale_time_send>\d+)\saccept\s(?P<accept>\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "long-lived-graceful-restart stale-time send "
+ "{{stale_time.send}} accept {{stale_time.accept}}",
+ "compval": "long_lived_graceful_restart.stale_time",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "long_lived_graceful_restart": {
+ "stale_time": {
+ "send": "{{stale_time_send}}",
+ "accept": "{{accept}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "maximum_prefix",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+maximum-prefix
+ (\s(?P<maximum_prefix>\d+))?
+ (\s(?P<threshold_value>\d+))?
+ (\srestart\s(?P<restart>\d+))?
+ (\swarning-only\s(?P<warning_only>))?
+ (\sdiscard-extra-paths\s(?P<discard_extra_paths>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": _tmpl_maximum_prefix,
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "maximum_prefix": {
+ "max_limit": "{{maximum_prefix}}",
+ "threshold_value": "{{threshold_value}}",
+ "restart": "{{restart}}",
+ "warning_only": "{{ True if warning_only is defined}}",
+ "discard_extra_paths": "{{ True if discard_extra_paths is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ {
+ "name": "multipath",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \smultipath(?P<multipath>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "multipath",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "multipath": "{{True if multipath is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "next_hop_self",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \snext-hop-self(?P<next_hop_self>)
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "next-hop-self{{' inheritance-disable' if next_hop_self.inheritance_disable is defined else ''}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "next_hop_self": {
+ "set": "{{True if next_hop_self is defined and"
+ " inheritance_disable is not defined}}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "next_hop_unchanged.set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \snext-hop-unchanged(?P<next_hop_unchanged>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "next-hop-unchanged",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi}}': {
+ "next_hop_unchanged": {
+ "set": "{{True if next_hop_self is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "next_hop_unchanged.inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \snext-hop-unchanged(?P<next_hop_unchanged>)
+ ((?P<inheritance_disable>)\sinheritance-disable)?
+ $""", re.VERBOSE,
+ ),
+ "setval": "next-hop-unchanged inheritance-disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi}}': {
+ "next_hop_unchanged": {
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "next_hop_unchanged.multipath",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \snext-hop-unchanged(?P<next_hop_unchanged>)
+ (?P<multipath>\smultipath)?
+ $""", re.VERBOSE,
+ ),
+ "setval": "next-hop-unchanged multipath",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi}}': {
+ "next_hop_unchanged": {
+ "multipath": "{{True if multipath is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "optimal_route_reflection_group_name",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \soptimal-route-reflection\s(?P<group_name>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "optimal-route-reflection {{optimal_route_reflection_group_name}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "optimal_route_reflection_group_name": "{{ group_name}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "orf_route_policy",
+ "getval": re.compile(
+ r"""
+ \s+(?P<nbr_address>neighbor\s\S+)
+ \sorf\sroute-policy\s(?P<orf_rr>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "orf route-policy {{orf_route_policy}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "orf_route_policy": "{{orf_rr}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "origin_as",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sorigin-as\svalidation\sdisable(?P<origin_as>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "origin-as validation disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "origin_as": {
+ "validation": {
+ "disable": "{{True if origin_as is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "remove_private_AS.set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sremove-private-AS(?P<remove_private_AS>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "remove-private-AS",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "remove_private_AS": {
+ "set": "{{True if remove_private_AS is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "remove_private_AS",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sremove-private-AS(?P<remove_private_AS>)
+ (\sinbound(?P<inbound>))?
+ (\sentire-aspath(?P<entire_aspath>))?
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": _tmpl_remove_private_AS,
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "remove_private_AS": {
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ "inbound": "{{True if inbound is defined}}",
+ "entire_aspath": "{{True if entire_aspath is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "route_policy.inbound",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sroute-policy\s(?P<route_policy>\S+)
+ \sin
+ $""", re.VERBOSE,
+ ),
+ "setval": "route-policy {{route_policy.inbound}} in",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "route_policy": {
+ "inbound": "{{route_policy}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "route_policy.outbound",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sroute-policy\s(?P<route_policy>\S+)
+ \sout
+ $""", re.VERBOSE,
+ ),
+ "setval": "route-policy {{route_policy.outbound}} out",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "route_policy": {
+ "outbound": "{{route_policy}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "route_reflector_client",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sroute-reflector-client(?P<route_reflector_client>)
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "route-reflector-client{{' inheritance-disable' "
+ "if route_reflector_client.inheritance_disable is defined }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "route_reflector_client": {
+ "set": "{{True if route_reflector_client is defined and "
+ "inheritance_disable is not defined }}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "send_community_ebgp",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \ssend-community-ebgp(?P<send_community_ebgp>)
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "send-community-ebgp{{' inheritance-disable' "
+ "if send_community_ebgp.inheritance_disable is defined else ''}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "send_community_ebgp": {
+ "set": "{{True if send_community_ebgp is defined and "
+ "inheritance_disable is not defined}}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "send_community_gshut_ebgp",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \ssend-community-gshut-ebgp(?P<send_community_gshut_ebg>)
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "send-community-gshut-ebgp{{' inheritance-disable' "
+ "if send_community_gshut_ebgp.inheritance_disable is defined else ''}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "send_community_gshut_ebgp": {
+ "set": "{{True if send_community_gshut_ebg is defined and "
+ "inheritance_disable is not defined}}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "send_extended_community_ebgp",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \ssend-extended-community-ebgp(?P<send_extended_community_ebgp>)
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "send-extended-community-ebgp{{' inheritance-disable' "
+ "if send_extended_community_ebgp.inheritance_disable is defined else ''}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "send_extended_community_ebgp": {
+ "set": "{{True if send_extended_community_ebgp is defined and "
+ "inheritance_disable is not defined}}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "send_multicast_attributes",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s+(?P<send_multicast_attributes>send-multicast-attributes)
+ (\sdisable(?P<disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "send-multicast-attributes{{' disable' "
+ "if send_multicast_attributes.disable is defined else ''}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "send_multicast_attributes": {
+ "set": "{{True if send_multicast_attributes is "
+ "defined and disable is not defined}}",
+ "disable": "{{True if disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "soft_reconfiguration",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \ssoft-reconfiguration
+ \sinbound(?P<inbound>)
+ (\salways(?P<always>))?
+ (\sinheritance-disable(?P<inheritance_disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": _tmpl_soft_reconfiguration,
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "soft_reconfiguration": {
+ "inbound": {
+ "set": "{{True if inbound is defined and "
+ "inheritance_disable is not defined and "
+ "always is not defined}}",
+ "always": "{{True if always is defined }}",
+ "inheritance_disable": "{{True if inheritance_disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "weight",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sweight\s(?P<weight>\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "weight {{weight}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "weight": "{{weight}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "use",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \suse\s(?P<af_use>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "weight {{weight}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "use": "{{af_use}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "update.out_originator_loopcheck_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \supdate\sout\soriginator-loopcheck(?P<set>)
+ $""", re.VERBOSE,
+ ),
+ "setval": "update out originator-loopcheck",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "update": {
+ "out_originator_loopcheck_set": "{{True if set is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "update.out_originator_loopcheck_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \supdate\sout\soriginator-loopcheck(?P<set>)
+ (\sdisable(?P<disable>))?
+ $""", re.VERBOSE,
+ ),
+ "setval": "update out originator-loopcheck disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "address_family": {
+ '{{"address_family_" + afi + "_" + safi }}': {
+ "update": {
+ "out_originator_loopcheck_disable": "{{True if disable is defined}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "advertisement_interval",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<advertise_in>advertisement-interval\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "advertisement-interval {{ advertisement_interval }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "advertisement_interval": "{{ advertise_in.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "bfd_fast_detect_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbfd
+ \sfast-detect
+ \s(?P<disable>disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bfd fast-detect disable",
+ "compval": "bfd.fast_detect.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "bfd": {
+ "fast_detect": {"disable": "{{ True if disable is defined }}"},
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "bfd_fast_detect_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbfd
+ \s(?P<fast_detect>fast-detect)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bfd fast-detect",
+ "compval": "bfd.fast_detect.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "bfd": {
+ "fast_detect": {"set": "{{ True if fast_detect is defined }}"},
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "bfd_fast_detect_strict_mode",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbfd
+ \sfast-detect
+ \s(?P<strict_mode>strict-mode)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bfd fast-detect strict-mode",
+ "compval": "bfd.fast_detect.strict_mode",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "bfd": {
+ "fast_detect": {"strict_mode": "{{ True if strict_mode is defined }}"},
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "bfd_nbr_multiplier",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbfd
+ \s(?P<multiplier>multiplier\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bfd multiplier {{ bfd.multiplier}}",
+ "compval": "bfd.multiplier",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD:
+ {
+ "bfd": {
+ "multiplier": "{{multiplier.split(" ")[1]}}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "bfd_nbr_minimum_interval",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbfd
+ \s(?P<min_interval>minimum-interval\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bfd minimum-interval {{ bfd.minimum_interval}}",
+ "compval": "bfd.minimum_interval",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "bfd": {
+ "minimum_interval": "{{min_interval.split(" ")[1]}}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "bmp_activate",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sbmp-activate
+ \s(?P<bmp_activate>server\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "bmp-activate server {{bmp_activate.server}}",
+ "compval": "bmp_activate.serevr",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "bmp_activate": {"server": "{{ bmp_activate.split(" ")[1] }}"},
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_cluster_id",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<cluster_id>cluster-id\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "cluster-id {{ cluster_id }}",
+ "compval": "cluster_id",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {"cluster_id": "{{ cluster_id.split(" ")[1] }}"},
+ },
+ },
+ },
+ {
+ "name": "neighbor_description",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sdescription\s(?P<description>.+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "description {{ description }}",
+ "compval": "description",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {"description": "{{ description }}"},
+ },
+ },
+ },
+ {
+ "name": "dmz_link_bandwidth",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<dmz_link_bandwidth>dmz-link-bandwidth)
+ $""", re.VERBOSE,
+ ),
+ "setval": "dmz-link-bandwidth",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "dmz_link_bandwidth": {
+ "set": "{{ True if dmz_link_bandwidth is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "dmz_link_bandwidth_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sdmz-link-bandwidth
+ \s(?P<dmz_link_bandwidth>inheritance_disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "dmz-link-bandwidth inheritance-disable",
+ "compval": "dmz_link_bandwidth.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "dmz_link_bandwidth": {
+ "inheritance_disable": "{{ True if dmz_link_bandwidth is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "dscp",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<dscp>dscp\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "dscp {{ dscp }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "dscp": "{{ dscp.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_multihop_value",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_multihop>ebgp-multihop\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-multihop {{ ebgp_multihop.value}}",
+ "compval": "ebgp_multihop.value",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_multihop": {
+ "value": "{{ ebgp_multihop.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_multihop_mpls",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_multihop>ebgp-multihop\s\S*\smpls)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-multihop mpls",
+ "compval": "ebgp_multihop.mpls",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_multihop": {"mpls": "{{ True if ebgp_multihop is defined }}"},
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_recv_extcommunity_dmz_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_recv_extcommunity_dmz>ebgp-recv-extcommunity-dmz)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-recv-extcommunity-dmz inheritance-disable",
+ "compval": "ebgp_recv_extcommunity_dm.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_recv_extcommunity_dmz": {
+ "set": "{{ True if ebgp_recv_extcommunity_dmz is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_recv_extcommunity_dmz",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_recv_extcommunity_dmz>ebgp-recv-extcommunity-dmz\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-recv-extcommunity-dmz inheritance-disable ",
+ "compval": "ebgp_recv_extcommunity_dmz.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_recv_extcommunity_dmz": {
+ "inheritance_disable": "{{ True if ebgp_recv_extcommunity_dmz is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_send_extcommunity_dmz",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_send_extcommunity_dmz>ebgp-send-extcommunity-dmz\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-send-extcommunity-dmz inheritance-disable ",
+ "compval": "ebgp_send_extcommunity_dmz.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_send_extcommunity_dmz": {
+ "inheritance_disable": "{{ True if ebgp_send_extcommunity_dmz is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_send_extcommunity_dmz_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_send_extcommunity_dmz>ebgp-send-extcommunity-dmz)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-send-extcommunity-dmz",
+ "compval": "ebgp_send_extcommunity_dmz.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_send_extcommunity_dmz": {
+ "set": "{{ True if ebgp_send_extcommunity_dmz is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ebgp_send_extcommunity_dmz_cumulatie",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ebgp_send_extcommunity_dmz>ebgp-send-extcommunity-dmz\scumulatie)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ebgp-send-extcommunity-dmz cumulatie ",
+ "compval": "ebgp_send_extcommunity_dmz.cumulatie",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ebgp_send_extcommunity_dmz": {
+ "cumulatie": "{{ True if ebgp_send_extcommunity_dmz is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "egress_engineering",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<egress_engineering>egress-engineering\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "egress-engineering inheritance-disable ",
+ "compval": "egress_engineering.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "egress_engineering": {
+ "inheritance_disable": "{{ True if egress_engineering is defined }}",
+ },
+ },
+ },
+ },
+
+ },
+ {
+ "name": "egress_engineering_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<egress_engineering>egress-engineering)
+ $""", re.VERBOSE,
+ ),
+ "setval": "egress-engineering",
+ "compval": "egress_engineering.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "egress_engineering": {
+ "set": "{{ True if egress_engineering is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_enforce_first_as_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<enforce_first_as_disable>enforce-first-as\sdisable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "enforce-first-as disable",
+ "compval": "enforce_first_as.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "enforce_first_as": {
+ "disable": "{{ True if enforce_first_as_disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_restart_restart_time",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<graceful_restart_restart_time>graceful-restart\srestart-time\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-restart restart-time {{ graceful_restart.restart_time}}",
+ "compval": "graceful_restart.restart_time",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_restart": {
+ "restart_time": "{{ graceful_restart_restart_time.split(" ")[2] }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_restart_stalepath_time",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<graceful_restart_stalepath_time>graceful-restart\sstalepath-time\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-restart stalepath-time {{ graceful_restart.stalepath_time}}",
+ "compval": "graceful_restart.stalepath_time",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_restart": {
+ "stalepath_time": "{{ graceful_restart_stalepath_time.split(" ")[2] }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<graceful_maintenance>graceful-maintenance)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance",
+ "compval": "graceful_maintenance.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "set": "{{ True if graceful_maintenance is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_activate",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<graceful_maintenance>graceful-maintenance\sactivate)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance activate",
+ "compval": "graceful_maintenance.activate.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "activate": {"set": "{{ True if graceful_maintenance is defined }}"},
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_activate_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<graceful_maintenance>activate\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance activate inheritance-disable",
+ "compval": "graceful_maintenance.activate.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "activate": {
+ "inheritance_disable": "{{ True if graceful_maintenance is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_as_prepends",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<as_prepends>as-prepends\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance as-prepends inheritance-disable",
+ "compval": "graceful_maintenance.as_prepends.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "as_prepends": {
+ "inheritance_disable": "{{ True if as_prepends is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_local_preference_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<local_preference>local-preference\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance local-preference inheritance-disable",
+ "compval": "graceful_maintenance.local_preference.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "local_preference": {
+ "inheritance_disable": "{{ True if local_preference is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_local_preference",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<local_preference>local-preference\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance local-preference {{ graceful_maintenance.local_preference.value}}",
+ "compval": "graceful_maintenance.local_preference.value",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "local_preference": {
+ "value": "{{ local_preference.split(" ")[1]}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_graceful_maintenance_as_prepends_value",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<as_prepends>as-prepends\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "graceful-maintenance as-prepends {{ graceful_maintenance.as_prepends.value }}",
+ "compval": "graceful_maintenance.as_prepends.value",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "graceful_maintenance": {
+ "as_prepends": {
+ "value": "{{ as_prepends.split(" ")[1]}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ignore_connected_check_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ignore_connected_check>ignore-connected-check)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ignore-connected-check",
+ "compval": "ignore_connected_check.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ignore_connected_check": {
+ "set": "{{ True if ignore_connected_check is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "ignore_connected_check",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ignore_connected_check>ignore-connected-check\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ignore-connected-check inheritance-disable ",
+ "compval": "ignore_connected_check.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ignore_connected_check": {
+ "inheritance_disable": "{{ True if ignore_connected_check is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "idle_watch_time",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sidle-watch-time(?P<idle_watch_time>\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "idle-watch-time {{idle_watch_time}} ",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "idle_watch_time": "{{idle_watch_time}}",
+ },
+ },
+ },
+ },
+ {
+ "name": "internal_vpn_client",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ (?P<internal_vpn_client>\sinternal-vpn-client)
+ $""", re.VERBOSE,
+ ),
+ "setval": "internal-vpn-client",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "internal_vpn_client": "{{true if internal_vpn_client is defined}}",
+ },
+ },
+ },
+ },
+ {
+ "name": "keychain",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<keychain>keychain\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "keychain inheritance-disable ",
+ "compval": "keychain.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "keychain": {
+ "inheritance_disable": "{{ True if keychain is defined }}",
+ },
+ },
+ },
+ },
+
+ },
+ {
+ "name": "keychain_name",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<keychain>keychain\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "keychain {{ keychain.name }}",
+ "compval": "keychain.name",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "keychain": {
+ "name": "{{ keychain.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "local_address",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slocal
+ \s(?P<local>address\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "local address inheritance-disable",
+ "compval": "local.address.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "local": {
+ "address": {
+ "inheritance_disable": "{{ True if local is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "local",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slocal
+ \s(?P<local>address\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "local address {{ local.address.ipv4_address }}",
+ "compval": "local.address.ipv4_address",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "local": {
+ "address": {
+ "ipv4_address": "{{ local.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "local_as_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<local_as>local-as\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "local-as inheritance-disable",
+ "compval": "local_as.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "local_as": {
+ "inheritance_disable": "{{ True if local_as is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "local_as",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<local_as>local-as\s\S+)
+ (\s(?P<no_prepend>no-prepend))?
+ (\s(?P<replace_as>replace-as))?
+ (\s(?P<dual_as>dual-as))?
+ $""", re.VERBOSE,
+ ),
+ "setval": _templ_local_as,
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "local_as": {
+ "value": "{{ local_as.split(" ")[1] }}",
+ "no_prepend": {
+ "set": "{{ True if no_prepend is defined and replace_as is undefined and dual_as is undefined else None}}",
+ "replace_as": {
+ "set": "{{ True if replace_as is defined and dual_as is undefined}}",
+ "dual_as": "{{ not not dual_as}}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "local_address_subnet",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slocal-address-subnet(?P<local>\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "local-address-subnet {{local_address_subnet}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "local_address_subnet": "{{local.split(" ")[1]}}",
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_log_message_in_value",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slog
+ \smessage
+ \s(?P<value>in\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "log message in {{ log.message.in.value}}",
+ "compval": "log.log_message.in.value",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "log": {
+ "log_message": {
+ "in": {
+ "value": "{{ value.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_log_message_in_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slog
+ \smessage
+ \s(?P<disable>in\sdisable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "log message in disable",
+ "compval": "log.log_message.in.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "log": {
+ "log_message": {
+ "in": {
+ "disable": "{{ True if disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_log_message_in_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slog
+ \smessage
+ \s(?P<disable>in\sinheritance-diable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "log message in inheritance-diable",
+ "compval": "log.log_message.in.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "log": {
+ "log_message": {
+ "in": {
+ "inheritance_disable": "{{ True if disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_log_message_out_value",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slog
+ \smessage
+ \s(?P<value>out\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "log message out {{ log.message.out.value}}",
+ "compval": "log.log_message.out.value",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "log": {
+ "log_message": {
+ "out": {
+ "value": "{{ value.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_log_message_out_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slog
+ \smessage
+ \s(?P<disable>out\sdisable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "log message out disable",
+ "compval": "log.log_message.out.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "log": {
+ "log_message": {
+ "out": {
+ "disable": "{{ True if disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_log_message_out_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \slog
+ \smessage
+ \s(?P<disable>out\sinheritance-diable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "log message out inheritance-diable",
+ "compval": "log.log_message.out.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "log": {
+ "log_message": {
+ "out": {
+ "inheritance_disable": "{{ True if disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "maximum_peers",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \smaximum-peers(?P<local>\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "maximum-peers {maximum_peers}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "maximum_peers": "{{local}}",
+ },
+ },
+ },
+
+ },
+ {
+ "name": "password_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<password>password\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "password inheritance-disable",
+ "compval": "password.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "password": {
+ "inheritance_disable": "{{ True if password is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "password_encrypted",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \spassword\sencrypted
+ \s(?P<password>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "password encrypted {{password.encrypted}}",
+ "compval": "password.encrypted",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "password": {
+ "encrypted": "{{ password }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "peer_set",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \speer-set(?P<local>\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "peer-set {peer_set}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "peer_set": "{{local}}",
+ },
+ },
+ },
+ },
+ {
+ "name": "receive_buffer_size",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<receive_buffer_size>receive-buffer-size\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "receive-buffer-size {{ receive_buffer_size }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "receive_buffer_size": "{{ receive_buffer_size.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "send_buffer_size",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<send_buffer_size>send-buffer-size\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "send-buffer-size {{ send_buffer_size }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "send_buffer_size": "{{ send_buffer_size.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "precedence",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \sprecedence\s(?P<local>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "precedence {{precedence}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "precedence": "{{local}}",
+ },
+ },
+ },
+ },
+ {
+ "name": "remote_as",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<remote_as>remote-as\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "remote-as {{ remote_as }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "remote_as": "{{ remote_as.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "remote_as_list",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<remote_as>remote-as-list\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "remote-as-list {{ remote_as_list }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "remote_as_list": "{{ remote_as.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "session_open_mode",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<session_open_mode>session-open-mode\s(active-only|both|passive-only))
+ $""", re.VERBOSE,
+ ),
+ "setval": "session-open-mode {{ session_open_mode }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "session_open_mode": "{{ session_open_mode.split(" ")[1] }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_shutdown",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<shutdown>shutdown)
+ $""", re.VERBOSE,
+ ),
+ "setval": "shutdown",
+ "compval": "shutdown",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "shutdown": {
+ "set": "{{ True if shutdown is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_shutdown_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<shutdown>shutdown\sinheritance_disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "shutdown inheritance-disable",
+ "compval": "shutdown.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "shutdown": {"inheritance_disable": "{{ True if shutdown is defined }}"},
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_tcp_mss_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<tcp_mss_disable>tcp\smss\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "tcp mss inheritance-disable",
+ "compval": "tcp.mss.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "tcp": {
+ "mss": {
+ "inheritance_disable": "{{ True if tcp_mss_disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_tcp_mss",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<tcp_mss>tcp\smss\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "tcp mss {{ tcp.mss.value }}",
+ "compval": "tcp.mss.value",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "tcp": {
+ "mss": {
+ "value": "{{ tcp_mss.split(" ")[2] }}",
+ },
+ },
+ },
+ },
+ },
+
+ },
+ {
+ "name": "neighbor_timers_keepalive",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<timers_keepalive_time>timers\s\d+)
+ \s(?P<timers_holdtime>\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "timers {{ timers.keepalive_time}} {{ timers.holdtime }}",
+ "compval": "timers",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "timers": {
+ "keepalive_time": "{{ timers_keepalive_time.split(" ")[1] }}",
+ "holdtime": "{{ timers_holdtime.split(" ")[0] }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "use.neighbor_group",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \suse\sneighbor-group\s(?P<neighbor_group>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "use neighbor-group {{ use.neighbor_group }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "use": {
+ "neighbor_group": "{{ neighbor_group }}",
+ },
+ },
+ },
+ },
+
+ },
+ {
+ "name": "use.session_group",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \suse\ssession-group\s(?P<session_group>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "use session-group {{ use.session_group }}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "use": {
+ "session_group": "{{ session_group }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "update_source",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \supdate-source
+ \s(?P<update_source>\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "update-source {{ update_source}}",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "update_source": "{{ update_source}}",
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_ttl_security_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ttl_security>ttl-security\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ttl-security inheritance-disable",
+ "compval": "ttl_security.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ttl_security": {
+ "inheritance_disable": "{{ True if ttl_security is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_ttl_security",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<ttl_security>ttl-security)
+ $""", re.VERBOSE,
+ ),
+ "setval": "ttl-security",
+ "compval": "ttl_security.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "ttl_security": {
+ "set": "{{ True if ttl_security is defined }}",
+ },
+ },
+ },
+ },
+
+ },
+ {
+ "name": "neighbor_update_in_filtering_attribute_filter_group",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<attribute_filter_group>attribute-filter\sgroup\s\S+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "update in filtering attribute-filter group {{ update.in.filtering.attribute_filter.group }}",
+ "compval": "update.in.filtering.attribute_filter.group",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "update": {
+ "in": {
+ "filtering": {
+ "attribute_filter": {
+ "group": "{{ attribute_filter_group.split(" ")[2] }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_update_in_filtering_logging_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<logging_disable>logging\sdisable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "update in filtering logging disable",
+ "compval": "update.in.filtering.logging.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "update": {
+ "in": {
+ "filtering": {
+ "logging": {
+ "disable": "{{True if logging_disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+
+ },
+ {
+ "name": "neighbor_update_in_filtering_message_buffers",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \s(?P<message_buffers>message\sbuffers\s\d+)
+ $""", re.VERBOSE,
+ ),
+ "setval": "update in filtering message buffers {{ update.in.filtering.message.buffers}}",
+ "compval": "update.in.filtering.update_message.buffers",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "update": {
+ "in": {
+ "filtering": {
+ "update_message": {
+ "buffers": "{{ message_buffers.split(" ")[2] }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_additional_paths_send",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \sadditional-paths
+ \s(?P<additional_paths_send>send)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability additional-paths send",
+ "compval": "capability.additional_paths.send.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "additional_paths": {
+ "send": {
+ "set": "{{ True if additional_paths_send is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_additional_paths_send_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \sadditional-paths
+ \s(?P<additional_paths_send>send\sdisable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability additional-paths send disable",
+ "compval": "capability.additional_paths.send.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "additional_paths": {
+ "send": {
+ "disable": "{{ True if additional_paths_send is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_additional_paths_rcv",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \sadditional-paths
+ \s(?P<additional_paths_receive>receive)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability additional-paths receive",
+ "compval": "capability.additional_paths.receive.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "additional_paths": {
+ "receive": {
+ "set": "{{ True if additional_paths_receive is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_additional_paths_rcv_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \sadditional-paths
+ \s(?P<additional_paths_receive_disable>receive\sdisable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability additional-paths receive disable",
+ "compval": "capability.additional_paths.receive.disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "additional_paths": {
+ "receive": {
+ "disable": "{{ True if additional_paths_receive_disable is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_suppress_four_byte_AS",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \ssuppress
+ \s(?P<suppress_4_byte_as>4-byte-as)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability suppress 4-byte-as",
+ "compval": "capability.suppress.four_byte_AS.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "suppress": {
+ "four_byte_AS": {
+ "set": "{{ True if suppress_4_byte_as is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_suppress_all",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \ssuppress
+ \s(?P<all>all)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability suppress all",
+ "compval": "capability.suppress.all.set",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "suppress": {
+ "all": {
+ "set": "{{ True if all is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "neighbor_capability_suppress_all_inheritance_disable",
+ "getval": re.compile(
+ r"""
+ \s+neighbor-group\s(?P<nbr_address>\S+)
+ \scapability
+ \ssuppress
+ \s(?P<all>all\sinheritance-disable)
+ $""", re.VERBOSE,
+ ),
+ "setval": "capability suppress all inheritance-disable",
+ "compval": "capability.suppress.all.inheritance_disable",
+ "result": {
+ "neighbor": {
+ UNIQUE_NEIB_ADD: {
+ "capability": {
+ "suppress": {
+ "all": {
+ "inheritance_disable": "{{ True if all is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+
+ },
+
+ ]
+ # fmt: on
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv2.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv2.py
index e5a54a64f..68937f9bd 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv2.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv2.py
@@ -19,11 +19,11 @@ def _tmplt_ospf_default_information(config_data):
command += " metric {metric}".format(**config_data["default_information_originate"])
if "metric_type" in config_data["default_information_originate"]:
command += " metric-type {metric_type}".format(
- **config_data["default_information_originate"]
+ **config_data["default_information_originate"],
)
if "route_policy" in config_data["default_information_originate"]:
command += " route-policy {route_policy}".format(
- **config_data["default_information_originate"]
+ **config_data["default_information_originate"],
)
return command
@@ -35,7 +35,7 @@ def _tmplt_ospf_auto_cost(config_data):
command += " disable"
if "reference_bandwidth" in config_data["auto_cost"]:
command += " reference-bandwidth {reference_bandwidth}".format(
- **config_data["auto_cost"]
+ **config_data["auto_cost"],
)
return command
@@ -416,11 +416,11 @@ def _tmplt_ospf_area_nssa_def_info_origin(config_data):
)
if "metric" in def_info_origin:
command += " metric {metric}".format(
- **config_data["nssa"]["default_information_originate"]
+ **config_data["nssa"]["default_information_originate"],
)
if "metric_type" in def_info_origin:
command += " metric-type {metric_type}".format(
- **config_data["nssa"]["default_information_originate"]
+ **config_data["nssa"]["default_information_originate"],
)
return command
@@ -531,11 +531,11 @@ def _tmplt_timers_graceful_shutdown(config_data):
command = "timers graceful-shutdown"
if "initial_delay" in config_data["timers"]["graceful-shutdown"]:
command += " initial delay {initial_delay}".format(
- **config_data["timers"]["graceful-shutdown"]
+ **config_data["timers"]["graceful-shutdown"],
)
if "retain_routes" in config_data["timers"]["graceful-shutdown"]:
command += " retain routes {retain_routes}".format(
- **config_data["timers"]["graceful-shutdown"]
+ **config_data["timers"]["graceful-shutdown"],
)
return command
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv3.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv3.py
index 14e3720be..ea8807206 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv3.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/rm_templates/ospfv3.py
@@ -19,11 +19,11 @@ def _tmplt_ospf_default_information(config_data):
command += " metric {metric}".format(**config_data["default_information_originate"])
if "metric_type" in config_data["default_information_originate"]:
command += " metric-type {metric_type}".format(
- **config_data["default_information_originate"]
+ **config_data["default_information_originate"],
)
if "route_policy" in config_data["default_information_originate"]:
command += " route-policy {route_policy}".format(
- **config_data["default_information_originate"]
+ **config_data["default_information_originate"],
)
return command
@@ -35,7 +35,7 @@ def _tmplt_ospf_auto_cost(config_data):
command += " disable"
if "reference_bandwidth" in config_data["auto_cost"]:
command += " reference-bandwidth {reference_bandwidth}".format(
- **config_data["auto_cost"]
+ **config_data["auto_cost"],
)
return command
@@ -413,11 +413,11 @@ def _tmplt_ospf_area_nssa_def_info_origin(config_data):
)
if "metric" in def_info_origin:
command += " metric {metric}".format(
- **config_data["nssa"]["default_information_originate"]
+ **config_data["nssa"]["default_information_originate"],
)
if "metric_type" in def_info_origin:
command += " metric-type {metric_type}".format(
- **config_data["nssa"]["default_information_originate"]
+ **config_data["nssa"]["default_information_originate"],
)
return command
@@ -528,11 +528,11 @@ def _tmplt_timers_graceful_shutdown(config_data):
command = "timers graceful-shutdown"
if "initial_delay" in config_data["timers"]["graceful-shutdown"]:
command += " initial delay {initial_delay}".format(
- **config_data["timers"]["graceful-shutdown"]
+ **config_data["timers"]["graceful-shutdown"],
)
if "retain_routes" in config_data["timers"]["graceful-shutdown"]:
command += " retain routes {retain_routes}".format(
- **config_data["timers"]["graceful-shutdown"]
+ **config_data["timers"]["graceful-shutdown"],
)
return command
diff --git a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/utils/utils.py b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/utils/utils.py
index a4467a487..64c66ca4b 100644
--- a/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/utils/utils.py
+++ b/ansible_collections/cisco/iosxr/plugins/module_utils/network/iosxr/utils/utils.py
@@ -14,12 +14,11 @@ from functools import total_ordering
from ansible.module_utils._text import to_text
from ansible.module_utils.basic import missing_required_lib
+from ansible.module_utils.common.network import is_masklen, to_netmask
from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
dict_diff,
- is_masklen,
search_obj_in_list,
- to_netmask,
)
@@ -109,7 +108,7 @@ def filter_dict_having_none_value(want, have):
have_ip = have.get("ipv4")
for each in have_ip:
if len(want_ip) > 1 and each.get("secondary"):
- have_ip = each.get("address").split(" ")[0]
+ have_ip = each.get("address").split("/")[0]
if have_ip != want_ip[0]:
diff_ip = True
if each.get("secondary") and diff_ip is True:
@@ -286,7 +285,7 @@ def normalize_interface(name):
if_type = "GigabitEthernet"
elif name.lower().startswith("fa"):
if_type = "FastEthernet"
- elif name.lower().startswith("fo"):
+ elif name.lower().startswith("for"):
if_type = "FortyGigE"
elif name.lower().startswith("te"):
if_type = "TenGigE"
@@ -298,10 +297,16 @@ def normalize_interface(name):
if_type = "Vlan"
elif name.lower().startswith("lo"):
if_type = "Loopback"
- elif name.lower().startswith("be"):
+ elif name.lower().startswith("bundle-e"):
if_type = "Bundle-Ether"
- elif name.lower().startswith("bp"):
+ elif name.lower().startswith("bundle-p"):
if_type = "Bundle-POS"
+ elif name.lower().startswith("fif"):
+ if_type = "FiftyGigE"
+ elif name.lower().startswith("fou"):
+ if_type = "FourHundredGigE"
+ elif name.lower().startswith("two"):
+ if_type = "TwoHundredGigE"
else:
if_type = None
@@ -310,7 +315,6 @@ def normalize_interface(name):
number = number_list[-1].strip()
else:
number = _get_number(name)
-
if if_type:
proper_interface = if_type + number
else:
@@ -326,14 +330,16 @@ def get_interface_type(interface):
return "GigabitEthernet"
elif interface.upper().startswith("FA"):
return "FastEthernet"
- elif interface.upper().startswith("FO"):
+ elif interface.upper().startswith("FORT"):
return "FortyGigE"
elif interface.upper().startswith("ET"):
return "Ethernet"
elif interface.upper().startswith("LO"):
return "Loopback"
- elif interface.upper().startswith("BE"):
+ elif interface.upper().startswith("BUNDLE-E"):
return "Bundle-Ether"
+ elif interface.upper().startswith("BUNDLE-P"):
+ return "Bundle-POS"
elif interface.upper().startswith("NV"):
return "nve"
elif interface.upper().startswith("TE"):
@@ -344,6 +350,16 @@ def get_interface_type(interface):
return "HundredGigE"
elif interface.upper().startswith("PRE"):
return "preconfigure"
+ elif interface.upper().startswith("FIF"):
+ return "FiftyGigE"
+ elif interface.upper().startswith("FOU"):
+ return "FourHundredGigE"
+ elif interface.upper().startswith("TWO"):
+ return "TwoHundredGigE"
+ elif interface.upper().startswith("MG"):
+ return "management"
+ elif interface.upper().startswith("MA"):
+ return "management"
else:
return "unknown"
@@ -454,3 +470,8 @@ def _coerce(other):
if isinstance(other, (int, float)):
other = Version(str(other))
return other
+
+
+def netmask_to_cidr(netmask):
+ # convert netmask to cidr and returns the cidr notation
+ return str(sum([bin(int(x)).count("1") for x in netmask.split(".")]))