summaryrefslogtreecommitdiffstats
path: root/ansible_collections/cisco/ios/plugins/module_utils
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/cisco/ios/plugins/module_utils')
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_address_family/bgp_address_family.py18
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_global/bgp_global.py1
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/evpn_evi.py91
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/evpn_global.py93
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lacp/lacp.py10
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lldp_global/lldp_global.py10
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/ping/ping.py1
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/service/service.py1
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/snmp_server/snmp_server.py440
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vlans/vlans.py8
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/vxlan_vtep.py102
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/acls/acls.py105
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_address_family/bgp_address_family.py10
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_global/bgp_global.py2
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/evpn_evi.py103
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/evpn_global.py98
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lacp/lacp.py4
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lldp_global/lldp_global.py8
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/logging_global/logging_global.py2
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ospfv2/ospfv2.py278
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ping/ping.py2
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/prefix_lists/prefix_lists.py216
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/service/service.py6
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/snmp_server/snmp_server.py179
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/static_routes/static_routes.py4
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py194
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/vxlan_vtep.py190
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/acls/acls.py90
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/bgp_global/bgp_global.py11
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/evpn_evi.py67
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/evpn_global.py68
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py12
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/legacy/base.py48
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/logging_global/logging_global.py8
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/ospfv2/ospfv2.py63
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/prefix_lists/prefix_lists.py55
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/snmp_server/snmp_server.py37
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py223
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/__init__.py0
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/vxlan_vtep.py67
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/acls.py158
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_address_family.py28
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_global.py363
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_evi.py121
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_global.py115
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv2.py1541
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv3.py16
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ping.py1
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/prefix_lists.py84
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/route_maps.py33
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/snmp_server.py1736
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/static_routes.py4
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/vxlan_vtep.py131
-rw-r--r--ansible_collections/cisco/ios/plugins/module_utils/network/ios/utils/utils.py17
62 files changed, 5242 insertions, 2031 deletions
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_address_family/bgp_address_family.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_address_family/bgp_address_family.py
index a52e3787c..18fed7891 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_address_family/bgp_address_family.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_address_family/bgp_address_family.py
@@ -340,7 +340,7 @@ class Bgp_address_familyArgs(object): # pylint: disable=R0903
"type": "dict",
"options": {
"set": {"type": "bool"},
- "number": {"type": "int"},
+ "number": {"type": "str"},
"dual_as": {"type": "bool"},
"no_prepend": {
"type": "dict",
@@ -367,7 +367,6 @@ class Bgp_address_familyArgs(object): # pylint: disable=R0903
"warning_only": {"type": "bool"},
},
},
- "next_hop_self": {"type": "bool"},
"nexthop_self": {
"type": "dict",
"options": {"set": {"type": "bool"}, "all": {"type": "bool"}},
@@ -440,7 +439,7 @@ class Bgp_address_familyArgs(object): # pylint: disable=R0903
"out": {"type": "bool"},
},
},
- "remote_as": {"type": "int"},
+ "remote_as": {"type": "str"},
"remove_private_as": {
"type": "dict",
"options": {
@@ -814,6 +813,19 @@ class Bgp_address_familyArgs(object): # pylint: disable=R0903
"type": "dict",
"options": {"name": {"type": "str"}, "filter": {"type": "bool"}},
},
+ "advertise": {
+ "type": "dict",
+ "options": {
+ "afi": {
+ "type": "str",
+ "choices": ["l2vpn"],
+ },
+ "safi": {
+ "type": "str",
+ "choices": ["evpn"],
+ },
+ },
+ },
},
},
},
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_global/bgp_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_global/bgp_global.py
index 38c4e1ab3..21bb051c3 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_global/bgp_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/bgp_global/bgp_global.py
@@ -940,6 +940,7 @@ class Bgp_globalArgs(object): # pylint: disable=R0903
"choices": [
"merged",
"replaced",
+ "overridden",
"deleted",
"purged",
"gathered",
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/evpn_evi.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/evpn_evi.py
new file mode 100644
index 000000000..021e1ed81
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_evi/evpn_evi.py
@@ -0,0 +1,91 @@
+# -*- 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 ios_evpn_evi module
+"""
+
+
+class Evpn_eviArgs(object): # pylint: disable=R0903
+ """The arg spec for the ios_evpn_evi module"""
+
+ argument_spec = {
+ "config": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "evi": {"type": "int", "required": True},
+ "default_gateway": {
+ "type": "dict",
+ "options": {
+ "advertise": {
+ "type": "dict",
+ "options": {
+ "enable": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "ip": {
+ "type": "dict",
+ "options": {
+ "local_learning": {
+ "type": "dict",
+ "options": {
+ "enable": {"type": "bool"},
+ "disable": {"type": "bool"},
+ },
+ },
+ },
+ },
+ "encapsulation": {
+ "type": "str",
+ "choices": ["vxlan"],
+ "default": "vxlan",
+ },
+ "replication_type": {
+ "type": "str",
+ "choices": ["ingress", "static"],
+ },
+ "route_distinguisher": {"type": "str"},
+ },
+ },
+ "running_config": {"type": "str"},
+ "state": {
+ "type": "str",
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ } # pylint: disable=C0301
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/evpn_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/evpn_global.py
new file mode 100644
index 000000000..acdb0c759
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/evpn_global/evpn_global.py
@@ -0,0 +1,93 @@
+# -*- 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 ios_evpn_global module
+"""
+
+
+class Evpn_globalArgs(object): # pylint: disable=R0903
+ """The arg spec for the ios_evpn_global module"""
+
+ argument_spec = {
+ "config": {
+ "type": "dict",
+ "options": {
+ "default_gateway": {
+ "type": "dict",
+ "options": {"advertise": {"type": "bool"}},
+ },
+ "flooding_suppression": {
+ "type": "dict",
+ "options": {
+ "address_resolution": {
+ "type": "dict",
+ "options": {"disable": {"type": "bool"}},
+ },
+ },
+ },
+ "ip": {
+ "type": "dict",
+ "options": {
+ "local_learning": {
+ "type": "dict",
+ "options": {"disable": {"type": "bool"}},
+ },
+ },
+ },
+ "replication_type": {
+ "type": "str",
+ "choices": ["ingress", "static"],
+ },
+ "route_target": {
+ "type": "dict",
+ "options": {
+ "auto": {
+ "type": "dict",
+ "options": {"vni": {"type": "bool"}},
+ },
+ },
+ },
+ "router_id": {
+ "type": "str",
+ },
+ },
+ },
+ "running_config": {"type": "str"},
+ "state": {
+ "type": "str",
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "rendered",
+ "gathered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ } # pylint: disable=C0301
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lacp/lacp.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lacp/lacp.py
index 3e346db12..dff90d45f 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lacp/lacp.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lacp/lacp.py
@@ -50,7 +50,15 @@ class LacpArgs(object):
},
"running_config": {"type": "str"},
"state": {
- "choices": ["merged", "replaced", "deleted", "rendered", "parsed", "gathered"],
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "rendered",
+ "parsed",
+ "gathered",
+ ],
"default": "merged",
"type": "str",
},
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lldp_global/lldp_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lldp_global/lldp_global.py
index 841e34bed..f7b699826 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lldp_global/lldp_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/lldp_global/lldp_global.py
@@ -61,7 +61,15 @@ class Lldp_globalArgs(object):
},
"running_config": {"type": "str"},
"state": {
- "choices": ["merged", "replaced", "deleted", "rendered", "parsed", "gathered"],
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "rendered",
+ "parsed",
+ "gathered",
+ ],
"default": "merged",
"type": "str",
},
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/ping/ping.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/ping/ping.py
index f89779d06..8de060b50 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/ping/ping.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/ping/ping.py
@@ -37,6 +37,7 @@ class PingArgs(object): # pylint: disable=R0903
"dest": {"required": True, "type": "str"},
"df_bit": {"default": False, "type": "bool"},
"source": {"type": "str"},
+ "size": {"type": "int"},
"ingress": {"type": "str"},
"egress": {"type": "str"},
"timeout": {"type": "int"},
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/service/service.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/service/service.py
index 76d2a3e34..238fc64a2 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/service/service.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/service/service.py
@@ -110,6 +110,7 @@ class ServiceArgs(object): # pylint: disable=R0903
"choices": [
"merged",
"replaced",
+ "overridden",
"deleted",
"gathered",
"rendered",
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/snmp_server/snmp_server.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/snmp_server/snmp_server.py
index d0473cc97..446a8225b 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/snmp_server/snmp_server.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/snmp_server/snmp_server.py
@@ -13,15 +13,16 @@ __metaclass__ = type
#############################################
#
# This file is auto generated by the
-# cli_rm_builder.
+# ansible.content_builder.
#
# Manually editing this file is not advised.
#
# To update the argspec make the desired changes
-# in the module docstring and re-run
-# cli_rm_builder.
+# 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 ios_snmp_server module
@@ -34,7 +35,10 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
argument_spec = {
"config": {
"options": {
- "accounting": {"options": {"command": {"type": "str"}}, "type": "dict"},
+ "accounting": {
+ "options": {"command": {"type": "str"}},
+ "type": "dict",
+ },
"cache": {"type": "int"},
"chassis_id": {"type": "str"},
"communities": {
@@ -52,7 +56,10 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"contact": {"type": "str"},
"context": {"elements": "str", "type": "list"},
"drop": {
- "options": {"unknown_user": {"type": "bool"}, "vrf_traffic": {"type": "bool"}},
+ "options": {
+ "unknown_user": {"type": "bool"},
+ "vrf_traffic": {"type": "bool"},
+ },
"type": "dict",
},
"engine_id": {
@@ -82,7 +89,11 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"elements": "dict",
"options": {
"context": {"type": "str"},
- "version_option": {"choices": ["auth", "noauth", "priv"], "type": "str"},
+ "match": {"choices": ["exact", "prefix"], "type": "str"},
+ "version_option": {
+ "choices": ["auth", "noauth", "priv"],
+ "type": "str",
+ },
"group": {"type": "str"},
"notify": {"type": "str"},
"read": {"type": "str"},
@@ -101,7 +112,10 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"community_string": {"type": "str"},
"traps": {"type": "list", "elements": "str"},
"version": {"choices": ["1", "2c", "3"], "type": "str"},
- "version_option": {"choices": ["auth", "noauth", "priv"], "type": "str"},
+ "version_option": {
+ "choices": ["auth", "noauth", "priv"],
+ "type": "str",
+ },
"vrf": {"type": "str"},
},
"type": "list",
@@ -116,7 +130,10 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"type": "dict",
},
"ip": {
- "options": {"dscp": {"type": "int"}, "precedence": {"type": "int"}},
+ "options": {
+ "dscp": {"type": "int"},
+ "precedence": {"type": "int"},
+ },
"type": "dict",
},
"location": {"type": "str"},
@@ -145,6 +162,7 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"trap_timeout": {"type": "int"},
"traps": {
"options": {
+ "aaa_server": {"type": "bool"},
"auth_framework": {
"options": {
"sec_violation": {"type": "bool"},
@@ -188,6 +206,22 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "bulkstat": {
+ "options": {
+ "enable": {"type": "bool"},
+ "collection": {"type": "bool"},
+ "transfer": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "call_home": {
+ "options": {
+ "enable": {"type": "bool"},
+ "message_send_fail": {"type": "bool"},
+ "server_fail": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"casa": {"type": "bool"},
"cef": {
"options": {
@@ -204,7 +238,10 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"config_copy": {"type": "bool"},
"config_ctid": {"type": "bool"},
"cpu": {
- "options": {"enable": {"type": "bool"}, "threshold": {"type": "bool"}},
+ "options": {
+ "enable": {"type": "bool"},
+ "threshold": {"type": "bool"},
+ },
"type": "dict",
},
"dhcp": {"type": "bool"},
@@ -218,19 +255,39 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"eigrp": {"type": "bool"},
"entity": {"type": "bool"},
+ "entity_diag": {
+ "options": {
+ "boot_up_fail": {"type": "bool"},
+ "enable": {"type": "bool"},
+ "hm_test_recover": {"type": "bool"},
+ "hm_thresh_reached": {"type": "bool"},
+ "scheduled_test_fail": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "entity_perf": {
+ "options": {
+ "enable": {"type": "bool"},
+ "throughput_notif": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "entity_state": {"type": "bool"},
"energywise": {"type": "bool"},
"envmon": {
"options": {
+ "enable": {"type": "bool"},
"fan": {
"options": {
- "shutdown": {"type": "bool"},
"enable": {"type": "bool"},
+ "shutdown": {"type": "bool"},
"status": {"type": "bool"},
"supply": {"type": "bool"},
"temperature": {"type": "bool"},
},
"type": "dict",
},
+ "fan_enable": {"type": "bool"},
"shutdown": {"type": "bool"},
"status": {"type": "bool"},
"supply": {"type": "bool"},
@@ -238,6 +295,7 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "errdisable": {"type": "bool"},
"ethernet": {
"options": {
"cfm": {
@@ -275,8 +333,24 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "ether_oam": {"type": "bool"},
"event_manager": {"type": "bool"},
- "flowmon": {"type": "bool"},
+ "flash": {
+ "options": {
+ "enable": {"type": "bool"},
+ "insertion": {"type": "bool"},
+ "lowspace": {"type": "bool"},
+ "removal": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "flex_links": {
+ "options": {
+ "enable": {"type": "bool"},
+ "status": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"firewall": {
"options": {
"enable": {"type": "bool"},
@@ -284,6 +358,7 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "flowmon": {"type": "bool"},
"frame_relay": {
"options": {
"enable": {"type": "bool"},
@@ -343,6 +418,15 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"type": "dict",
},
"ipsla": {"type": "bool"},
+ "isis": {"type": "bool"},
+ "l2tc": {
+ "options": {
+ "enable": {"type": "bool"},
+ "sys_threshold": {"type": "bool"},
+ "threshold": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"l2tun": {
"options": {
"pseudowire_status": {"type": "bool"},
@@ -350,9 +434,141 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "license": {"type": "bool"},
+ "lisp": {"type": "bool"},
+ "local_auth": {"type": "bool"},
+ "mac_notification": {
+ "options": {
+ "enable": {"type": "bool"},
+ "change": {"type": "bool"},
+ "move": {"type": "bool"},
+ "threshold": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "memory": {
+ "options": {
+ "enable": {"type": "bool"},
+ "bufferpeak": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "mpls": {
+ "options": {
+ "fast_reroute": {
+ "options": {
+ "enable": {"type": "bool"},
+ "protected": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "ldp": {
+ "options": {
+ "enable": {"type": "bool"},
+ "pv_limit": {"type": "bool"},
+ "session_down": {"type": "bool"},
+ "session_up": {"type": "bool"},
+ "threshold": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "rfc": {
+ "options": {
+ "ldp": {
+ "options": {
+ "enable": {"type": "bool"},
+ "pv_limit": {"type": "bool"},
+ "session_down": {"type": "bool"},
+ "session_up": {"type": "bool"},
+ "threshold": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "traffic_eng": {
+ "options": {
+ "enable": {"type": "bool"},
+ "down": {"type": "bool"},
+ "reoptimized": {"type": "bool"},
+ "reroute": {"type": "bool"},
+ "up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "vpn": {
+ "options": {
+ "enable": {"type": "bool"},
+ "illegal_label": {"type": "bool"},
+ "max_thresh_cleared": {
+ "type": "bool",
+ },
+ "max_threshold": {"type": "bool"},
+ "mid_threshold": {"type": "bool"},
+ "vrf_down": {"type": "bool"},
+ "vrf_up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ },
+ "type": "dict",
+ },
+ "traffic_eng": {
+ "options": {
+ "enable": {"type": "bool"},
+ "down": {"type": "bool"},
+ "reroute": {"type": "bool"},
+ "up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "vpn": {
+ "options": {
+ "enable": {"type": "bool"},
+ "illegal_label": {"type": "bool"},
+ "max_thresh_cleared": {"type": "bool"},
+ "max_threshold": {"type": "bool"},
+ "mid_threshold": {"type": "bool"},
+ "vrf_down": {"type": "bool"},
+ "vrf_up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ },
+ "type": "dict",
+ },
+ "mpls_vpn": {"type": "bool"},
"msdp": {"type": "bool"},
"mvpn": {"type": "bool"},
- "mpls_vpn": {"type": "bool"},
+ "nhrp": {
+ "options": {
+ "enable": {"type": "bool"},
+ "nhc": {
+ "options": {
+ "enable": {"type": "bool"},
+ "down": {"type": "bool"},
+ "up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "nhp": {
+ "options": {
+ "enable": {"type": "bool"},
+ "down": {"type": "bool"},
+ "up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "nhs": {
+ "options": {
+ "enable": {"type": "bool"},
+ "down": {"type": "bool"},
+ "up": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "quota_exceeded": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"ospf": {
"options": {
"cisco_specific": {
@@ -362,11 +578,17 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"retransmit": {"type": "bool"},
"state_change": {
"options": {
- "nssa_trans_change": {"type": "bool"},
+ "nssa_trans_change": {
+ "type": "bool",
+ },
"shamlink": {
"options": {
- "interface": {"type": "bool"},
- "neighbor": {"type": "bool"},
+ "interface": {
+ "type": "bool",
+ },
+ "neighbor": {
+ "type": "bool",
+ },
},
"type": "dict",
},
@@ -383,6 +605,42 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "ospfv3": {
+ "options": {
+ "errors": {
+ "options": {
+ "enable": {"type": "bool"},
+ "bad_packet": {"type": "bool"},
+ "config_error": {"type": "bool"},
+ "virt_bad_packet": {"type": "bool"},
+ "virt_config_error": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "rate_limit": {"type": "int"},
+ "state_change": {
+ "options": {
+ "enable": {"type": "bool"},
+ "if_state_change": {"type": "bool"},
+ "neighbor_restart_helper_status_change": {
+ "type": "bool",
+ },
+ "neighbor_state_change": {"type": "bool"},
+ "nssa_translator_status_change": {
+ "type": "bool",
+ },
+ "restart_status_change": {"type": "bool"},
+ "virtif_state_change": {"type": "bool"},
+ "vn_restart_helper_status_change": {
+ "type": "bool",
+ },
+ "vn_state_change": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ },
+ "type": "dict",
+ },
"pim": {
"options": {
"invalid_pim_message": {"type": "bool"},
@@ -392,19 +650,35 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
- "vrfmib": {
+ "pki": {"type": "bool"},
+ "port_security": {"type": "bool"},
+ "power_ethernet": {
"options": {
- "vrf_up": {"type": "bool"},
- "vrf_down": {"type": "bool"},
- "vnet_trunk_up": {"type": "bool"},
- "vnet_trunk_down": {"type": "bool"},
+ "enable": {"type": "bool"},
+ "group": {
+ "options": {
+ "slot_id": {"type": "int"},
+ "threshold": {"type": "int"},
+ },
+ "elements": "dict",
+ "type": "list",
+ },
+ "police": {"type": "bool"},
},
"type": "dict",
},
- "pki": {"type": "bool"},
- "rsvp": {"type": "bool"},
- "isis": {"type": "bool"},
"pw_vc": {"type": "bool"},
+ "rep": {"type": "bool"},
+ "rsvp": {"type": "bool"},
+ "rf": {"type": "bool"},
+ "smart_license": {
+ "options": {
+ "enable": {"type": "bool"},
+ "entitlement": {"type": "bool"},
+ "global": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"snmp": {
"options": {
"authentication": {"type": "bool"},
@@ -415,10 +689,103 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
},
"type": "dict",
},
+ "stackwise": {"type": "bool"},
+ "stpx": {
+ "options": {
+ "enable": {"type": "bool"},
+ "inconsistency": {"type": "bool"},
+ "loop_inconsistency": {"type": "bool"},
+ "root_inconsistency": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"syslog": {"type": "bool"},
"transceiver_all": {"type": "bool"},
+ "trustsec": {
+ "options": {
+ "authz_file_error": {"type": "bool"},
+ "cache_file_error": {"type": "bool"},
+ "enable": {"type": "bool"},
+ "keystore_file_error": {"type": "bool"},
+ "keystore_sync_fail": {"type": "bool"},
+ "random_number_fail": {"type": "bool"},
+ "src_entropy_fail": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "trustsec_interface": {
+ "options": {
+ "enable": {"type": "bool"},
+ "authc_fail": {"type": "bool"},
+ "authz_fail": {"type": "bool"},
+ "sap_fail": {"type": "bool"},
+ "supplicant_fail": {"type": "bool"},
+ "unauthorized": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "trustsec_policy": {
+ "options": {
+ "enable": {"type": "bool"},
+ "authz_sgacl_fail": {"type": "bool"},
+ "peer_policy_updated": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "trustsec_server": {
+ "options": {
+ "enable": {"type": "bool"},
+ "provision_secret": {"type": "bool"},
+ "radius_server": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "trustsec_sxp": {
+ "options": {
+ "enable": {"type": "bool"},
+ "binding_conflict": {"type": "bool"},
+ "binding_err": {"type": "bool"},
+ "binding_expn_fail": {"type": "bool"},
+ "conn_config_err": {"type": "bool"},
+ "conn_down": {"type": "bool"},
+ "conn_srcaddr_err": {"type": "bool"},
+ "conn_up": {"type": "bool"},
+ "msg_parse_err": {"type": "bool"},
+ "oper_nodeid_change": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"tty": {"type": "bool"},
+ "udld": {
+ "options": {
+ "enable": {"type": "bool"},
+ "link_fail_rpt": {"type": "bool"},
+ "status_change": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "vlan_membership": {"type": "bool"},
+ "vlancreate": {"type": "bool"},
+ "vlandelete": {"type": "bool"},
+ "vrfmib": {
+ "options": {
+ "vrf_up": {"type": "bool"},
+ "vrf_down": {"type": "bool"},
+ "vnet_trunk_up": {"type": "bool"},
+ "vnet_trunk_down": {"type": "bool"},
+ },
+ "type": "dict",
+ },
"vrrp": {"type": "bool"},
+ "vswitch": {
+ "options": {
+ "dual_active": {"type": "bool"},
+ "enable": {"type": "bool"},
+ "vsl": {"type": "bool"},
+ },
+ "type": "dict",
+ },
+ "vtp": {"type": "bool"},
},
"type": "dict",
},
@@ -431,17 +798,29 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"no_log": False,
"type": "dict",
"options": {
- "algorithm": {"type": "str", "choices": ["md5", "sha"]},
- "password": {"type": "str", "no_log": True},
+ "algorithm": {
+ "type": "str",
+ "choices": ["md5", "sha"],
+ },
+ "password": {
+ "type": "str",
+ "no_log": True,
+ },
},
},
"encryption": {
"no_log": False,
"type": "dict",
"options": {
- "priv": {"type": "str", "choices": ["3des", "aes", "des"]},
+ "priv": {
+ "type": "str",
+ "choices": ["3des", "aes", "des"],
+ },
"priv_option": {"type": "str"},
- "password": {"type": "str", "no_log": True},
+ "password": {
+ "type": "str",
+ "no_log": True,
+ },
},
},
"group": {"type": "str"},
@@ -449,7 +828,10 @@ class Snmp_serverArgs(object): # pylint: disable=R0903
"udp_port": {"type": "int"},
"username": {"type": "str"},
"version": {"choices": ["v1", "v2c", "v3"], "type": "str"},
- "version_option": {"choices": ["encrypted"], "type": "str"},
+ "version_option": {
+ "choices": ["encrypted"],
+ "type": "str",
+ },
"vrf": {"type": "str"},
},
"type": "list",
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vlans/vlans.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vlans/vlans.py
index a3b0b6acd..9db593dcc 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vlans/vlans.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vlans/vlans.py
@@ -55,9 +55,17 @@ class VlansArgs(object):
"associated": {"type": "list", "elements": "int"},
},
},
+ "member": {
+ "type": "dict",
+ "options": {
+ "vni": {"type": "int", "required": True},
+ "evi": {"type": "int"},
+ },
+ },
},
"type": "list",
},
+ "configuration": {"type": "bool"},
"running_config": {"type": "str"},
"state": {
"choices": [
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/vxlan_vtep.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/vxlan_vtep.py
new file mode 100644
index 000000000..b5eb35c07
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/argspec/vxlan_vtep/vxlan_vtep.py
@@ -0,0 +1,102 @@
+# -*- 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 ios_vxlan_vtep module
+"""
+
+
+class Vxlan_vtepArgs(object): # pylint: disable=R0903
+ """The arg spec for the ios_vxlan_vtep module"""
+
+ argument_spec = {
+ "config": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "interface": {"type": "str", "required": True},
+ "source_interface": {"type": "str"},
+ "host_reachability_bgp": {
+ "type": "bool",
+ },
+ "member": {
+ "type": "dict",
+ "options": {
+ "vni": {
+ "type": "dict",
+ "options": {
+ "l2vni": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "vni": {"type": "int"},
+ "replication": {
+ "type": "dict",
+ "options": {
+ "type": {
+ "type": "str",
+ "choices": ["ingress", "static"],
+ },
+ "mcast_group": {
+ "type": "dict",
+ "options": {
+ "ipv4": {"type": "str"},
+ "ipv6": {"type": "str"},
+ },
+ },
+ },
+ },
+ },
+ },
+ "l3vni": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "vni": {"type": "int"},
+ "vrf": {"type": "str"},
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ "running_config": {"type": "str"},
+ "state": {
+ "type": "str",
+ "choices": [
+ "merged",
+ "replaced",
+ "overridden",
+ "deleted",
+ "rendered",
+ "gathered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ } # pylint: disable=C0301
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/acls/acls.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/acls/acls.py
index 9d29555cc..164c75c40 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/acls/acls.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/acls/acls.py
@@ -15,6 +15,7 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
+from ansible.module_utils._text import to_text
from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
ResourceModule,
@@ -149,11 +150,28 @@ class Acls(ResourceModule):
entry["afi"] = afi
return entry
+ def pop_remark(r_entry, afi):
+ """Takes out remarks from ace entry as remarks not same
+ does not mean the ace entry to be re-introduced
+ """
+ if r_entry.get("remarks"):
+ return r_entry.pop("remarks")
+ else:
+ return {}
+
for wseq, wentry in iteritems(want):
hentry = have.pop(wseq, {})
+ rem_hentry, rem_wentry = {}, {}
+
if hentry:
hentry = self.sanitize_protocol_options(wentry, hentry)
- if hentry != wentry:
+
+ if hentry != wentry: # will let in if ace is same but remarks is not same
+ if hentry:
+ rem_hentry["remarks"] = pop_remark(hentry, afi)
+ if wentry:
+ rem_wentry["remarks"] = pop_remark(wentry, afi)
+
if hentry:
if self.state == "merged":
self._module.fail_json(
@@ -164,24 +182,51 @@ class Acls(ResourceModule):
),
)
else: # other action states
- if hentry.get("remarks"): # remove remark if not in want
- for rems in hentry.get("remarks"):
- if rems not in wentry.get("remarks", {}):
- self.addcmd({"remarks": rems}, "remarks", negate=True)
- else: # remove ace if not in want
+ if rem_hentry.get("remarks"): # remove remark if not in want
+ for k_hrems, hrems in rem_hentry.get("remarks").items():
+ if k_hrems not in rem_wentry.get("remarks", {}).keys():
+ if self.state in ["replaced", "overridden"]:
+ self.addcmd(
+ {
+ "remarks": hrems,
+ "sequence": hentry.get("sequence", ""),
+ },
+ "remarks_no_data",
+ negate=True,
+ )
+ break
+ else:
+ self.addcmd(
+ {
+ "remarks": hrems,
+ "sequence": hentry.get("sequence", ""),
+ },
+ "remarks",
+ negate=True,
+ )
+ # remove ace if not in want
+ if hentry != wentry:
self.addcmd(add_afi(hentry, afi), "aces", negate=True)
- if wentry.get("remarks"): # add remark if not in have
- for rems in wentry.get("remarks"):
- if rems not in hentry.get("remarks", {}):
- self.addcmd({"remarks": rems}, "remarks")
- else: # add ace if not in have
+ if rem_wentry.get("remarks"): # add remark if not in have
+ for k_wrems, wrems in rem_wentry.get("remarks").items():
+ if k_wrems not in rem_hentry.get("remarks", {}).keys():
+ self.addcmd(
+ {"remarks": wrems, "sequence": hentry.get("sequence", "")},
+ "remarks",
+ )
+ # add ace if not in have
+ if hentry != wentry:
self.addcmd(add_afi(wentry, afi), "aces")
# remove remaining entries from have aces list
for hseq in have.values():
if hseq.get("remarks"): # remove remarks that are extra in have
- for rems in hseq.get("remarks"):
- self.addcmd({"remarks": rems}, "remarks", negate=True)
+ for krems, rems in hseq.get("remarks").items():
+ self.addcmd(
+ {"remarks": rems, "sequence": hseq.get("sequence", "")},
+ "remarks",
+ negate=True,
+ )
else: # remove extra aces
self.addcmd(add_afi(hseq, afi), "aces", negate=True)
@@ -192,6 +237,7 @@ class Acls(ResourceModule):
list(wace.get("protocol_options"))[0] == hace.get("protocol")
):
hace.pop("protocol")
+ hace["protocol_options"] = wace.get("protocol_options")
return hace
def acl_name_cmd(self, name, afi, acl_type):
@@ -224,11 +270,17 @@ class Acls(ResourceModule):
for acl in each.get("acls"): # check each acl for aces
temp_aces = {}
if acl.get("aces"):
- temp_rem = [] # remarks if defined in an ace
+ rem_idx = 0 # remarks if defined in an ace
for ace in acl.get("aces"): # each ace turned to dict
- if ace.get("destination") and ace.get("destination", {}).get(
- "port_protocol",
- {},
+ if (
+ ace.get("destination")
+ and ace.get("destination", {}).get(
+ "port_protocol",
+ {},
+ )
+ and not ace.get("destination", {})
+ .get("port_protocol", {})
+ .get("range")
):
for k, v in (
ace.get("destination", {}).get("port_protocol", {}).items()
@@ -251,18 +303,25 @@ class Acls(ResourceModule):
),
)
- if ace.get("remarks"):
- en_name = str(acl.get("name")) + "remark"
- temp_rem.extend(ace.pop("remarks"))
+ if ace.get(
+ "remarks",
+ ): # index aces inside of each ace don't cluster them all
+ rem_ace = {}
+ # en_name = str(acl.get("name")) + "remark"
+ # temp_rem.extend(ace.pop("remarks"))
+ for remks in ace.get("remarks"):
+ rem_ace[remks.replace(" ", "_")] = remks
+ rem_idx += 1
+ ace["remarks"] = rem_ace
if ace.get("sequence"):
temp_aces.update({ace.get("sequence"): ace})
elif ace:
count += 1
- temp_aces.update({"_" + str(count): ace})
+ temp_aces.update({"_" + to_text(count): ace})
- if temp_rem: # add remarks to the temp ace
- temp_aces.update({en_name: {"remarks": temp_rem}})
+ # if temp_rem: # add remarks to the temp ace
+ # temp_aces.update({en_name: {"remarks": temp_rem}})
if acl.get("acl_type"): # update acl dict with req info
temp_acls.update(
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_address_family/bgp_address_family.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_address_family/bgp_address_family.py
index 36ea3e963..17cdd11fc 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_address_family/bgp_address_family.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_address_family/bgp_address_family.py
@@ -39,6 +39,7 @@ class Bgp_address_family(ResourceModule):
"""
parsers = [
+ "advertise",
"as_number", # generic
"aggregate_addresses",
"auto_summary",
@@ -336,9 +337,6 @@ class Bgp_address_family(ResourceModule):
neib["neighbor_address"] = neib.pop("ipv6_address")
if neib.get("ipv6_adddress"):
neib["neighbor_address"] = neib.pop("ipv6_adddress")
- # next_hop_self deprecated added nexthop_self
- if neib.get("next_hop_self"):
- neib["nexthop_self"] = {"set": neib.pop("next_hop_self")}
# prefix_list and prefix_lists
if neib.get("prefix_list"): # deprecated made list
neib["prefix_lists"] = [neib.pop("prefix_list")]
@@ -356,6 +354,12 @@ class Bgp_address_family(ResourceModule):
# slow_peer to slow_peer_options
if neib.get("slow_peer"): # only one slow_peer is allowed
neib["slow_peer_options"] = neib.pop("slow_peer")[0]
+ # we can skip deprecating these by handling the int to str conversion here
+ # int to float is not considered considering the size of as numbers
+ if neib.get("remote_as"):
+ neib["remote_as"] = str(neib.get("remote_as"))
+ if neib.get("local_as") and neib.get("local_as", {}).get("number"):
+ neib["local_as"]["number"] = str(neib["local_as"]["number"])
# make dict neighbors dict
tmp[neib[p_key[k]]] = neib
_af["neighbors"] = tmp
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_global/bgp_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_global/bgp_global.py
index 59881d622..c48cac946 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_global/bgp_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/bgp_global/bgp_global.py
@@ -148,7 +148,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")
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/evpn_evi.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/evpn_evi.py
new file mode 100644
index 000000000..240906637
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_evi/evpn_evi.py
@@ -0,0 +1,103 @@
+#
+# -*- 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 ios_evpn_evi 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 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.ios.plugins.module_utils.network.ios.facts.facts import Facts
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.evpn_evi import (
+ Evpn_eviTemplate,
+)
+
+
+class Evpn_evi(ResourceModule):
+ """
+ The ios_evpn_evi config class
+ """
+
+ def __init__(self, module):
+ super(Evpn_evi, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="evpn_evi",
+ tmplt=Evpn_eviTemplate(),
+ )
+ self.parsers = [
+ "default_gateway.advertise.enable",
+ "default_gateway.advertise.disable",
+ "encapsulation",
+ "ip.local_learning.enable",
+ "ip.local_learning.disable",
+ "replication_type",
+ "route_distinguisher",
+ ]
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+ return self.result
+
+ def generate_commands(self):
+ """Generate configuration commands to send based on
+ want, have and desired state.
+ """
+ wantd = {entry["evi"]: entry for entry in self.want}
+ haved = {entry["evi"]: entry for entry in 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 = {}
+
+ # remove superfluous config for overridden and deleted
+ if self.state in ["overridden", "deleted"]:
+ for k, have in iteritems(haved):
+ if k not in wantd:
+ self.addcmd(have, "evi", negate=True)
+
+ for k, want in iteritems(wantd):
+ self._compare(want=want, have=haved.pop(k, {}))
+
+ def _compare(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 Evpn_evi network resource.
+ """
+ begin = len(self.commands)
+ self.compare(parsers=self.parsers, want=want, have=have)
+ if len(self.commands) != begin:
+ self.commands.insert(begin, self._tmplt.render(want or have, "evi", False))
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/evpn_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/evpn_global.py
new file mode 100644
index 000000000..bd6e10321
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/evpn_global/evpn_global.py
@@ -0,0 +1,98 @@
+#
+# -*- 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 ios_evpn_global 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 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.ios.plugins.module_utils.network.ios.facts.facts import Facts
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.evpn_global import (
+ Evpn_globalTemplate,
+)
+
+
+EVPN_GLOBAL_PARENT = "l2vpn evpn"
+
+
+class Evpn_global(ResourceModule):
+ """
+ The ios_evpn_global config class
+ """
+
+ def __init__(self, module):
+ super(Evpn_global, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="evpn_global",
+ tmplt=Evpn_globalTemplate(),
+ )
+ self.parsers = [
+ "default_gateway.advertise",
+ "flooding_suppression.address_resolution.disable",
+ "ip.local_learning.disable",
+ "replication_type",
+ "route_target.auto.vni",
+ "router_id",
+ ]
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+ return self.result
+
+ def generate_commands(self):
+ """Generate configuration commands to send based on
+ want, have and desired state.
+ """
+ wantd = self.want
+ haved = self.have
+
+ # if state is merged, merge want onto have and then compare
+ if self.state == "merged":
+ wantd = dict_merge(haved, wantd)
+
+ # remove superfluous config for deleted
+ if self.state == "deleted":
+ if haved:
+ self.commands.append("no " + EVPN_GLOBAL_PARENT)
+ wantd, haved = {}, {}
+
+ self._compare(want=wantd, have=haved)
+
+ def _compare(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 Evpn_global network resource.
+ """
+ begin = len(self.commands)
+ self.compare(parsers=self.parsers, want=want, have=have)
+ if len(self.commands) != begin:
+ self.commands.insert(begin, EVPN_GLOBAL_PARENT)
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lacp/lacp.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lacp/lacp.py
index 0420c347b..e09a53869 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lacp/lacp.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lacp/lacp.py
@@ -126,7 +126,7 @@ class Lacp(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
- if self.state in ("merged", "replaced", "rendered") and not want:
+ if self.state in ("merged", "replaced", "overridden", "rendered") and not want:
self._module.fail_json(
msg="value of config parameter must not be empty for state {0}".format(self.state),
)
@@ -135,7 +135,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/ios/plugins/module_utils/network/ios/config/lldp_global/lldp_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lldp_global/lldp_global.py
index c575bc7b0..34b466c52 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lldp_global/lldp_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/lldp_global/lldp_global.py
@@ -140,24 +140,22 @@ class Lldp_global(ConfigBase):
to the desired configuration
"""
commands = []
- if self.state in ("merged", "replaced", "rendered") and not want:
+ if self.state in ("merged", "replaced", "overridden", "rendered") and not want:
self._module.fail_json(
msg="value of config parameter must not be empty for state {0}".format(self.state),
)
- if self.state == "overridden":
- commands = self._state_overridden(want, have)
elif self.state == "deleted":
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
def _state_replaced(self, want, have):
- """The command generator when state is replaced
+ """The command generator when state is replaced/overridden
:param want: the desired configuration as a dictionary
:param have: the current configuration as a dictionary
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/logging_global/logging_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/logging_global/logging_global.py
index 4eb442a0c..bfaab013b 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/logging_global/logging_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/logging_global/logging_global.py
@@ -108,9 +108,9 @@ class Logging_global(ResourceModule):
the `want` and `have` data with the `parsers` defined
for the Logging_global network resource.
"""
+ self._compare_complex_attrs(want, have)
self.compare(parsers=self.parsers, want=want, have=have)
self._compare_lists_attrs(want, have)
- self._compare_complex_attrs(want, have)
def _compare_lists_attrs(self, want, have):
"""Compare list of dict"""
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ospfv2/ospfv2.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ospfv2/ospfv2.py
index 2cbc53e17..1dd26f356 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ospfv2/ospfv2.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ospfv2/ospfv2.py
@@ -33,10 +33,6 @@ class Ospfv2(ResourceModule):
The ios_ospfv2 class
"""
- gather_subset = ["!all", "!min"]
-
- gather_network_resources = ["ospfv2"]
-
def __init__(self, module):
super(Ospfv2, self).__init__(
empty_fact_val={},
@@ -46,39 +42,97 @@ class Ospfv2(ResourceModule):
tmplt=Ospfv2Template(),
)
+ self.parsers = [
+ "adjacency",
+ "address_family",
+ "auto_cost",
+ "bfd",
+ "capability.lls",
+ "capability.opaque",
+ "capability.transit",
+ "capability.vrf_lite",
+ "compatible",
+ "default_information",
+ "default_metric",
+ "discard_route",
+ "distance.admin_distance",
+ "distance.ospf",
+ "distribute_list.prefix",
+ "distribute_list.route_map",
+ "domain_id",
+ "domain_tag",
+ "event_log",
+ "help",
+ "ignore",
+ "interface_id",
+ "ispf",
+ "limit",
+ "local_rib_criteria",
+ "log_adjacency_changes",
+ "max_lsa",
+ "max_metric",
+ "maximum_paths",
+ "mpls.ldp.autoconfig",
+ "mpls.ldp.sync",
+ "mpls.traffic_eng",
+ "neighbor",
+ "nsf.cisco",
+ "nsf.ietf.disable",
+ "nsf.ietf.strict_lsa_checking",
+ "prefix_suppression",
+ "priority",
+ "queue_depth.hello.max_packets",
+ "queue_depth.hello.unlimited",
+ "queue_depth.update.max_packets",
+ "queue_depth.update.unlimited",
+ "router_id",
+ "shutdown",
+ "summary_address.not_advertise",
+ "summary_address.nssa_only",
+ "timers.throttle.lsa",
+ "timers.pacing.flood",
+ "timers.pacing.lsa_group",
+ "timers.pacing.retransmission",
+ "timers.throttle.spf",
+ "traffic_share",
+ "ttl_security",
+ ]
+
def execute_module(self):
"""Execute the module
:rtype: A dictionary
:returns: The result from module execution
"""
- self.gen_config()
- self.run_commands()
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
return self.result
- def gen_config(self):
+ def generate_commands(self):
"""Select the appropriate function based on the state provided
:rtype: A list
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
+ haved, wantd = dict(), dict()
+
if self.want:
- wantd = {}
for entry in self.want.get("processes", []):
+ entry = self._handle_deprecated(entry)
wantd.update({(entry["process_id"], entry.get("vrf")): entry})
- else:
- wantd = {}
+
if self.have:
- haved = {}
for entry in self.have.get("processes", []):
+ # entry = self._handle_deprecated(entry)
haved.update({(entry["process_id"], entry.get("vrf")): entry})
- else:
- haved = {}
# turn all lists of dicts into dicts prior to merge
for each in wantd, haved:
- self.list_to_dict(each)
+ if each:
+ self._list_to_dict(each)
+
# if state is merged, merge want onto have
if self.state == "merged":
wantd = dict_merge(haved, wantd)
@@ -103,61 +157,32 @@ class Ospfv2(ResourceModule):
self._compare(want=want, have=haved.pop(k, {}))
def _compare(self, want, have):
- parsers = [
- "adjacency",
- "address_family",
- "auto_cost",
- "bfd",
- "capability",
- "compatible",
- "default_information",
- "default_metric",
- "discard_route",
- "distance.admin_distance",
- "distance.ospf",
- "distribute_list.acls",
- "distribute_list.prefix",
- "distribute_list.route_map",
- "domain_id",
- "domain_tag",
- "event_log",
- "help",
- "ignore",
- "interface_id",
- "ispf",
- "limit",
- "local_rib_criteria",
- "log_adjacency_changes",
- "max_lsa",
- "max_metric",
- "maximum_paths",
- "mpls.ldp",
- "mpls.traffic_eng",
- "neighbor",
- "network",
- "nsf.cisco",
- "nsf.ietf",
- "passive_interface",
- "prefix_suppression",
- "priority",
- "queue_depth.hello",
- "queue_depth.update",
- "router_id",
- "shutdown",
- "summary_address",
- "timers.throttle.lsa",
- "timers.throttle.spf",
- "traffic_share",
- "ttl_security",
- ]
-
if want != have:
self.addcmd(want or have, "pid", False)
- self.compare(parsers, want, have)
+ self.compare(self.parsers, want, have)
self._areas_compare(want, have)
+ self._complex_compare(want, have)
if want.get("passive_interfaces"):
self._passive_interfaces_compare(want, have)
+ def _complex_compare(self, want, have):
+ complex_parsers = ["distribute_list.acls", "network"]
+ for _parser in complex_parsers:
+ if _parser == "distribute_list.acls":
+ wdist = want.get("distribute_list", {}).get("acls", {})
+ hdist = have.get("distribute_list", {}).get("acls", {})
+ else:
+ wdist = want.get(_parser, {})
+ hdist = have.get(_parser, {})
+ for key, wanting in iteritems(wdist):
+ haveing = hdist.pop(key, {})
+ if wanting != haveing:
+ if haveing and self.state in ["overridden", "replaced"]:
+ self.addcmd(haveing, _parser, negate=True)
+ self.addcmd(wanting, _parser, False)
+ for key, haveing in iteritems(hdist):
+ self.addcmd(haveing, _parser, negate=True)
+
def _areas_compare(self, want, have):
wareas = want.get("areas", {})
hareas = have.get("areas", {})
@@ -168,42 +193,40 @@ class Ospfv2(ResourceModule):
def _area_compare(self, want, have):
parsers = [
- "area.authentication",
- "area.capability",
- "area.default_cost",
- "area.nssa",
- "area.nssa.translate",
- "area.ranges",
- "area.sham_link",
- "area.stub",
+ "authentication",
+ "capability",
+ "default_cost",
+ "nssa",
+ "nssa.translate",
+ "sham_link",
+ "stub",
]
self.compare(parsers=parsers, want=want, have=have)
- self._area_compare_filters(want, have)
+ self._area_complex_compare(want, have, want.get("area_id"))
- def _area_compare_filters(self, wantd, haved):
- for name, entry in iteritems(wantd):
- h_item = haved.pop(name, {})
- if entry != h_item and name == "filter_list":
- filter_list_entry = {}
- filter_list_entry["area_id"] = wantd["area_id"]
- if h_item:
- li_diff = [
- item for item in entry + h_item if item not in entry or item not in h_item
- ]
- else:
- li_diff = entry
- filter_list_entry["filter_list"] = li_diff
- self.addcmd(filter_list_entry, "area.filter_list", False)
- for name, entry in iteritems(haved):
- if name == "filter_list":
- self.addcmd(entry, "area.filter_list", True)
+ def _area_complex_compare(self, want, have, area_id):
+ area_complex_parsers = ["filter_list", "ranges"]
+ for _parser in area_complex_parsers:
+ wantr = want.get(_parser, {})
+ haver = have.get(_parser, {})
+ for key, wanting in iteritems(wantr):
+ haveing = have.pop(key, {})
+ haveing["area_id"] = area_id
+ wanting["area_id"] = area_id
+ if wanting != haveing:
+ if haveing and self.state in ["overridden", "replaced"]:
+ self.addcmd(haveing, _parser, negate=True)
+ self.addcmd(wanting, _parser, False)
+ for key, haveing in iteritems(haver):
+ haveing["area_id"] = area_id
+ self.addcmd(haveing, _parser, negate=True)
def _passive_interfaces_compare(self, want, have):
- parsers = ["passive_interfaces"]
+ parsers = ["passive_interfaces.default", "passive_interfaces.interface"]
h_pi = None
for k, v in iteritems(want["passive_interfaces"]):
- h_pi = have.get("passive_interfaces", [])
- if h_pi and h_pi.get(k) and h_pi.get(k) != v:
+ h_pi = have.get("passive_interfaces", {})
+ if h_pi.get(k) and h_pi.get(k) != v:
for each in v["name"]:
h_interface_name = h_pi[k].get("name", [])
if each not in h_interface_name:
@@ -243,42 +266,51 @@ class Ospfv2(ResourceModule):
}
self.compare(
parsers=parsers,
- want={"passive_interface": temp},
+ want={"passive_interfaces": temp},
have=dict(),
)
elif k == "default":
self.compare(
parsers=parsers,
want=dict(),
- have={"passive_interface": {"default": True}},
+ have={"passive_interfaces": {"default": True}},
)
- def list_to_dict(self, param):
- if param:
- for _pid, proc in iteritems(param):
- for area in proc.get("areas", []):
- ranges = {}
- for entry in area.get("ranges", []):
- ranges.update({entry["address"]: entry})
- if bool(ranges):
- area["ranges"] = ranges
- filter_list = {}
- for entry in area.get("filter_list", []):
- filter_list.update({entry["direction"]: entry})
- if bool(filter_list):
- area["filter_list"] = filter_list
- temp = {}
- for entry in proc.get("areas", []):
- temp.update({entry["area_id"]: entry})
- proc["areas"] = temp
- if proc.get("distribute_list"):
- if "acls" in proc.get("distribute_list"):
- temp = {}
- for entry in proc["distribute_list"].get("acls", []):
- temp.update({entry["name"]: entry})
- proc["distribute_list"]["acls"] = temp
- if proc.get("passive_interfaces") and proc["passive_interfaces"].get("interface"):
- temp = {}
- for entry in proc["passive_interfaces"]["interface"].get("name", []):
- temp.update({entry: entry})
- proc["passive_interfaces"]["interface"]["name"] = temp
+ def _list_to_dict(self, param):
+ for _pid, proc in param.items():
+ # convert list to dict for areas
+ for area in proc.get("areas", []):
+ area["ranges"] = {entry["address"]: entry for entry in area.get("ranges", [])}
+ area["filter_list"] = {
+ entry["direction"]: entry for entry in area.get("filter_list", [])
+ }
+
+ proc["areas"] = {entry["area_id"]: entry for entry in proc.get("areas", [])}
+
+ # list to dict for distribute_list
+ distribute_list = proc.get("distribute_list", {})
+ if "acls" in distribute_list:
+ distribute_list["acls"] = {
+ entry["name"]: entry for entry in distribute_list["acls"]
+ }
+
+ # list to dict for passive_interfaces
+ passive_interfaces = proc.get("passive_interfaces", {}).get("interface", {})
+ if passive_interfaces.get("name"):
+ passive_interfaces["name"] = {entry: entry for entry in passive_interfaces["name"]}
+
+ # list to dict for network
+ if proc.get("network"):
+ proc["network"] = {entry["address"]: entry for entry in proc["network"]}
+
+ def _handle_deprecated(self, config):
+ if config.get("passive_interface"):
+ passive_interfaces = config.get("passive_interfaces", {})
+ interface = passive_interfaces.get("interface", {})
+ name_list = interface.get("name", [])
+ if not name_list:
+ name_list.append(config["passive_interface"])
+ else:
+ name_list.extend(config["passive_interface"])
+ del config["passive_interface"]
+ return config
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ping/ping.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ping/ping.py
index f2417f596..138cd5715 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ping/ping.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/ping/ping.py
@@ -81,7 +81,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/ios/plugins/module_utils/network/ios/config/prefix_lists/prefix_lists.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/prefix_lists/prefix_lists.py
index 7c4ebe5ec..210fb234d 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/prefix_lists/prefix_lists.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/prefix_lists/prefix_lists.py
@@ -63,12 +63,10 @@ class Prefix_lists(ResourceModule):
want, have and desired state.
"""
wantd = {entry["afi"]: entry for entry in self.want}
-
haved = {entry["afi"]: entry for entry in self.have}
- # Convert each of config list to dict
- for each in wantd, haved:
- self.list_to_dict(each)
+ self._prefix_list_transform(wantd)
+ self._prefix_list_transform(haved)
# if state is merged, merge want onto have and then compare
if self.state == "merged":
@@ -76,44 +74,24 @@ class Prefix_lists(ResourceModule):
# if state is deleted, empty out wantd and set haved to wantd
if self.state == "deleted":
- temp = None
- for k, v in iteritems(haved):
- if k in wantd:
- if wantd[k].get("prefix_lists"):
- want_afi_name = wantd[k].get("prefix_lists", {})
- haved[k]["prefix_lists"] = {
- key: val
- for key, val in iteritems(v.get("prefix_lists"))
- if key in want_afi_name
- }
- elif wantd:
- temp = k
- if temp:
- haved.pop(k)
- wantd = {}
- for k, have in iteritems(haved):
- for key, val in iteritems(have["prefix_lists"]):
- if k == "ipv4":
- k = "ip"
- self.commands.append("no {0} prefix-list {1}".format(k, key))
+ haved = {k: v for k, v in iteritems(haved) if k in wantd or not wantd}
+ for key, hvalue in iteritems(haved):
+ wvalue = wantd.pop(key, {})
+ if wvalue:
+ wplists = wvalue.get("prefix_lists", {})
+ hplists = hvalue.get("prefix_lists", {})
+ hvalue["prefix_lists"] = {
+ k: v for k, v in iteritems(hplists) if k in wplists or not wplists
+ }
# remove superfluous config for overridden and deleted
if self.state in ["overridden", "deleted"]:
for k, have in iteritems(haved):
- want_afi = wantd.get(k, {})
- for key, val in iteritems(have["prefix_lists"]):
- if k == "ipv4":
- k = "ip"
- if want_afi and key not in want_afi.get("prefix_lists"):
- self.commands.append("no {0} prefix-list {1}".format(k, key))
+ if k not in wantd:
+ self._compare(want={}, have=have)
for k, want in iteritems(wantd):
self._compare(want=want, have=haved.pop(k, {}))
- # alligning cmd with negate cmd 1st followed by config cmd
- if self.state in ["overridden", "replaced"]:
- self.commands = [each for each in self.commands if "no" in each] + [
- each for each in self.commands if "no" not in each
- ]
def _compare(self, want, have):
"""Leverages the base class `compare()` method and
@@ -121,130 +99,48 @@ class Prefix_lists(ResourceModule):
the `want` and `have` data with the `parsers` defined
for the Prefix_lists network resource.
"""
- if want != have and self.state != "deleted":
- for k, v in iteritems(want["prefix_lists"]):
- if have.get("prefix_lists") and have["prefix_lists"].get(k):
- have_prefix = have["prefix_lists"].pop(k, {})
- for key, val in iteritems(v.get("entries")):
- if have_prefix.get("entries"):
- have_prefix_param = have_prefix["entries"].pop(key, {})
- else:
- have_prefix_param = None
- if have_prefix.get("description"):
- self.compare(
- parsers=self.parsers,
- want={
- "afi": want["afi"],
- "name": k,
- "prefix_list": {"description": v["description"]},
- },
- have={
- "afi": want["afi"],
- "name": k,
- "prefix_list": {"description": have_prefix.pop("description")},
- },
- )
- if have_prefix_param and val != have_prefix_param:
- if key == "description":
- # Code snippet should be removed when Description param is removed from
- # entries level as this supports deprecated level of Description
- self.compare(
- parsers=self.parsers,
- want={"afi": want["afi"], "name": k, "prefix_list": {key: val}},
- have={
- "afi": have["afi"],
- "name": k,
- "prefix_list": {key: have_prefix_param},
- },
- )
- else:
- if self.state == "merged" and have_prefix_param.get(
- "sequence",
- ) == val.get("sequence"):
- self._module.fail_json(
- "Cannot update existing sequence {0} of Prefix Lists {1} with state merged.".format(
- val.get("sequence"),
- k,
- )
- + " Please use state replaced or overridden.",
- )
- self.compare(
- parsers=self.parsers,
- want=dict(),
- have={
- "afi": have["afi"],
- "name": k,
- "prefix_list": have_prefix_param,
- },
- )
- self.compare(
- parsers=self.parsers,
- want={"afi": want["afi"], "name": k, "prefix_list": val},
- have={
- "afi": have["afi"],
- "name": k,
- "prefix_list": have_prefix_param,
- },
- )
- elif val and val != have_prefix_param:
- self.compare(
- parsers=self.parsers,
- want={"afi": want["afi"], "name": k, "prefix_list": val},
- have=dict(),
- )
- if have_prefix and (self.state == "replaced" or self.state == "overridden"):
- if have_prefix.get("description"):
- # Code snippet should be removed when Description param is removed from
- # entries level as this supports deprecated level of Description
- self.compare(
- parsers=self.parsers,
- want=dict(),
- have={
- "afi": want["afi"],
- "name": k,
- "prefix_list": {"description": have_prefix["description"]},
- },
- )
- for key, val in iteritems(have_prefix.get("entries")):
- self.compare(
- parsers=self.parsers,
- want=dict(),
- have={"afi": have["afi"], "name": k, "prefix_list": val},
- )
- elif v:
- if v.get("description"):
- self.compare(
- parsers=self.parsers,
- want={
- "afi": want["afi"],
- "name": k,
- "prefix_list": {"description": v["description"]},
- },
- have=dict(),
- )
- for key, val in iteritems(v.get("entries")):
- self.compare(
- parsers=self.parsers,
- want={"afi": want["afi"], "name": k, "prefix_list": val},
- have=dict(),
- )
+ wplists = want.get("prefix_lists", {})
+ hplists = have.get("prefix_lists", {})
+ for wk, wentry in iteritems(wplists):
+ hentry = hplists.pop(wk, {})
+ self.compare(["description"], want=wentry, have=hentry)
+ # compare sequences
+ self._compare_seqs(wentry.pop("entries", {}), hentry.pop("entries", {}))
- def list_to_dict(self, param):
- if param:
- for key, val in iteritems(param):
- if val.get("prefix_lists"):
- temp_prefix_list = {}
- for each in val["prefix_lists"]:
- temp_entries = dict()
- if each.get("entries"):
- for every in each["entries"]:
- temp_entries.update({str(every["sequence"]): every})
- temp_prefix_list.update(
- {
- each["name"]: {
- "description": each.get("description"),
- "entries": temp_entries,
- },
- },
+ if self.state in ["overridden", "deleted"]:
+ # remove remaining prefix lists
+ for h in hplists.values():
+ self.commands.append(
+ "no {0} prefix-list {1}".format(h["afi"].replace("ipv4", "ip"), h["name"]),
+ )
+
+ def _compare_seqs(self, want, have):
+ for wseq, wentry in iteritems(want):
+ hentry = have.pop(wseq, {})
+ if hentry != wentry:
+ if hentry:
+ if self.state == "merged":
+ self._module.fail_json(
+ msg="Cannot update existing sequence {0} of prefix list {1} with state merged."
+ " Please use state replaced or overridden.".format(
+ hentry["sequence"],
+ hentry["name"],
+ ),
)
- val["prefix_lists"] = temp_prefix_list
+ else:
+ self.addcmd(hentry, "entry", negate=True)
+ self.addcmd(wentry, "entry")
+ # remove remaining entries from have prefix list
+ for hseq in have.values():
+ self.addcmd(hseq, "entry", negate=True)
+
+ def _prefix_list_transform(self, entry):
+ for afi, value in iteritems(entry):
+ if "prefix_lists" in value:
+ for plist in value["prefix_lists"]:
+ plist.update({"afi": afi})
+ if "entries" in plist:
+ for seq in plist["entries"]:
+ seq.update({"afi": afi, "name": plist["name"]})
+ plist["entries"] = {x["sequence"]: x for x in plist["entries"]}
+ value["prefix_lists"] = {entry["name"]: entry for entry in value["prefix_lists"]}
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/service/service.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/service/service.py
index 23e3329be..6a4c8a1ff 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/service/service.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/service/service.py
@@ -103,9 +103,11 @@ class Service(ResourceModule):
"prompt": True,
"slave_log": True,
"password_recovery": True,
- "private_config_encryption": True,
}
+ if "private_config_encryption" in haved:
+ service_default["private_config_encryption"] = True
+
# if state is merged, merge want onto have and then compare
if self.state == "merged":
wantd = dict_merge(haved, wantd)
@@ -115,7 +117,7 @@ class Service(ResourceModule):
wantd = self._service_list_to_dict(service_default)
# if state is replaced
- elif self.state == "replaced":
+ elif self.state in ["replaced", "overridden"]:
wantd = dict_merge(self._service_list_to_dict(service_default), wantd)
self._compare(want=wantd, have=haved)
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/snmp_server/snmp_server.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/snmp_server/snmp_server.py
index ff45f7b5f..187d0779d 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/snmp_server/snmp_server.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/snmp_server/snmp_server.py
@@ -77,72 +77,121 @@ class Snmp_server(ResourceModule):
"views",
]
self.complex_parsers = [
+ "traps.aaa_server",
"traps.auth_framework",
"traps.bfd",
"traps.bgp",
+ "traps.bgp.cbgp2",
"traps.bridge",
+ "traps.bulkstat",
+ "traps.call_home",
"traps.casa",
+ "traps.cef",
"traps.cnpd",
"traps.config",
"traps.config_copy",
"traps.config_ctid",
+ "traps.cpu",
"traps.dhcp",
+ "traps.dlsw",
"traps.eigrp",
- "traps.entity",
"traps.energywise",
+ "traps.entity",
+ "traps.entity_diag",
+ "traps.entity_perf",
+ "traps.entity_state",
+ "traps.envmon",
+ "traps.errdisable",
+ "traps.ether_oam",
+ "traps.ethernet.cfm.alarm",
+ "traps.ethernet.cfm.cc",
+ "traps.ethernet.cfm.crosscheck",
+ "traps.ethernet.evc",
"traps.event_manager",
+ "traps.flash",
+ "traps.flex_links",
+ "traps.firewall",
"traps.flowmon",
+ "traps.frame_relay",
+ "traps.frame_relay.subif",
"traps.fru_ctrl",
"traps.hsrp",
- "traps.ipsla",
- "traps.isis",
- "traps.msdp",
- "traps.mvpn",
- "traps.mpls_vpn",
- "traps.pki",
- "traps.pw_vc",
- "traps.rsvp",
- "traps.syslog",
- "traps.transceiver_all",
- "traps.tty",
- "traps.vrrp",
- "traps.vrfmib",
- "traps.ipmulticast",
"traps.ike.policy.add",
"traps.ike.policy.delete",
"traps.ike.tunnel.start",
"traps.ike.tunnel.stop",
+ "traps.ipmulticast",
"traps.ipsec.cryptomap.add",
- "traps.ipsec.cryptomap.delete",
"traps.ipsec.cryptomap.attach",
+ "traps.ipsec.cryptomap.delete",
"traps.ipsec.cryptomap.detach",
+ "traps.ipsec.too_many_sas",
"traps.ipsec.tunnel.start",
"traps.ipsec.tunnel.stop",
- "traps.ipsec.too_many_sas",
+ "traps.ipsla",
+ "traps.isis",
+ "traps.l2tc",
+ "traps.l2tun.pseudowire_status",
+ "traps.l2tun.session",
+ "traps.lisp",
+ "traps.license",
+ "traps.local_auth",
+ "traps.mac_notification",
+ "traps.memory",
+ "traps.mpls.fast_reroute",
+ "traps.mpls.ldp",
+ "traps.mpls.rfc.ldp",
+ "traps.mpls.rfc.traffic_eng",
+ "traps.mpls.rfc.vpn",
+ "traps.mpls.traffic_eng",
+ "traps.mpls.vpn",
+ "traps.msdp",
+ "traps.mvpn",
+ "traps.nhrp.nhc",
+ "traps.nhrp.nhp",
+ "traps.nhrp.nhs",
+ "traps.nhrp.quota_exceeded",
"traps.ospf.cisco_specific.error",
- "traps.ospf.cisco_specific.retransmit",
"traps.ospf.cisco_specific.lsa",
+ "traps.ospf.cisco_specific.retransmit",
"traps.ospf.cisco_specific.state_change.nssa_trans_change",
"traps.ospf.cisco_specific.state_change.shamlink.interface",
"traps.ospf.cisco_specific.state_change.shamlink.neighbor",
"traps.ospf.error",
- "traps.ospf.retransmit",
"traps.ospf.lsa",
+ "traps.ospf.retransmit",
"traps.ospf.state_change",
- "traps.l2tun.pseudowire_status",
- "traps.l2tun.session",
- "traps.cpu",
- "traps.firewall",
+ "traps.ospfv3.errors",
+ "traps.ospfv3.rate_limit",
+ "traps.ospfv3.state_change",
"traps.pim",
+ "traps.pki",
+ "traps.port_security",
+ "traps.power_ethernet",
+ "traps.pw_vc",
+ "traps.rep",
+ "traps.rsvp",
+ "traps.rf",
+ "traps.smart_license",
"traps.snmp",
- "traps.frame_relay",
- "traps.frame_relay.subif",
- "traps.cef",
- "traps.dlsw",
- "traps.ethernet.evc",
- "traps.ethernet.cfm.alarm",
- "traps.ethernet.cfm.cc",
- "traps.ethernet.cfm.crosscheck",
+ "traps.stackwise",
+ "traps.stpx",
+ "traps.syslog",
+ "traps.transceiver_all",
+ "traps.trustsec",
+ "traps.trustsec_interface",
+ "traps.trustsec_policy",
+ "traps.trustsec_server",
+ "traps.trustsec_sxp",
+ "traps.tty",
+ "traps.udld",
+ "traps.vlan_membership",
+ "traps.vlancreate",
+ "traps.vlandelete",
+ "traps.vrfmib",
+ "traps.vrrp",
+ "traps.vswitch",
+ "traps.vtp",
]
def execute_module(self):
@@ -163,6 +212,8 @@ class Snmp_server(ResourceModule):
wantd = self._snmp_list_to_dict(self.want)
haved = self._snmp_list_to_dict(self.have)
+ wantd = self._handle_deprecates(want=wantd)
+
# if state is merged, merge want onto have and then compare
if self.state == "merged":
wantd = dict_merge(haved, wantd)
@@ -186,16 +237,39 @@ class Snmp_server(ResourceModule):
def _compare_lists_attrs(self, want, have):
"""Compare list of dict"""
for _parser in self.list_parsers:
- i_want = want.get(_parser, {})
- i_have = have.get(_parser, {})
- for key, wanting in iteritems(i_want):
- haveing = i_have.pop(key, {})
- if wanting != haveing:
- if haveing and self.state in ["overridden", "replaced"]:
- self.addcmd(haveing, _parser, negate=True)
- self.addcmd(wanting, _parser)
- for key, haveing in iteritems(i_have):
- self.addcmd(haveing, _parser, negate=True)
+ if _parser == "users":
+ i_want = want.get(_parser, {})
+ i_have = have.get(_parser, {})
+ for key, wanting in iteritems(i_want):
+ wanting_compare = deepcopy(wanting)
+ if (
+ "authentication" in wanting_compare
+ and "password" in wanting_compare["authentication"]
+ ):
+ wanting_compare["authentication"].pop("password")
+ if (
+ "encryption" in wanting_compare
+ and "password" in wanting_compare["encryption"]
+ ):
+ wanting_compare["encryption"].pop("password")
+ haveing = i_have.pop(key, {})
+ if wanting_compare != haveing:
+ if haveing and self.state in ["overridden", "replaced"]:
+ self.addcmd(haveing, _parser, negate=True)
+ self.addcmd(wanting, _parser)
+ for key, haveing in iteritems(i_have):
+ self.addcmd(haveing, _parser, negate=True)
+ else:
+ i_want = want.get(_parser, {})
+ i_have = have.get(_parser, {})
+ for key, wanting in iteritems(i_want):
+ haveing = i_have.pop(key, {})
+ if wanting != haveing:
+ if haveing and self.state in ["overridden", "replaced"]:
+ self.addcmd(haveing, _parser, negate=True)
+ self.addcmd(wanting, _parser)
+ for key, haveing in iteritems(i_have):
+ self.addcmd(haveing, _parser, negate=True)
def _snmp_list_to_dict(self, data):
"""Convert all list of dicts to dicts of dicts"""
@@ -242,7 +316,8 @@ class Snmp_server(ResourceModule):
tmp_data[k]["protocol"] = tmp
elif k == "groups":
tmp_data[k] = {
- str(i[p_key.get(k)] + i.get("version_option", "")): i for i in tmp_data[k]
+ str(i[p_key.get(k)] + i.get("version_option", "") + i.get("context", "")): i
+ for i in tmp_data[k]
}
elif k == "views":
tmp_data[k] = {
@@ -251,3 +326,23 @@ class Snmp_server(ResourceModule):
else:
tmp_data[k] = {str(i[p_key.get(k)]): i for i in tmp_data[k]}
return tmp_data
+
+ def _handle_deprecates(self, want):
+ """Remove deprecated attributes and set the replacment"""
+
+ # Take in count the traps config mpls_vpn which is DEPRECATED and replaced by mpls.vpn
+ if "traps" in want:
+ if "mpls_vpn" in want["traps"]:
+ want["traps"] = dict_merge(
+ want["traps"],
+ {"mpls": {"vpn": {"enable": want["traps"]["mpls_vpn"]}}},
+ )
+ want["traps"].pop("mpls_vpn")
+ if "envmon" in want["traps"] and "fan" in want["traps"]["envmon"]:
+ want["traps"]["envmon"]["fan_enable"] = want["traps"]["envmon"]["fan"].get(
+ "enable",
+ False,
+ )
+ want["traps"]["envmon"].pop("fan")
+
+ return want
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/static_routes/static_routes.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/static_routes/static_routes.py
index 79b63c8fe..e6c1336d6 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/static_routes/static_routes.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/static_routes/static_routes.py
@@ -71,7 +71,7 @@ class Static_routes(ResourceModule):
if delete_spcl and haved and self.state == "deleted":
for pk, to_rem in delete_spcl.items():
if pk in ["ipv4", "ipv6"]:
- _afis = haved.get("_afis_")
+ _afis = haved.get("(_afis_)")
for k, v in _afis.get(pk, {}).items():
for each_dest in to_rem:
if k.split("_")[0] == each_dest:
@@ -184,5 +184,5 @@ class Static_routes(ResourceModule):
_routes[_key] = dummy_sr
_srts[_afi] = _routes
- _static_rts[_vrf if _vrf else "_afis_"] = _srts
+ _static_rts[_vrf if _vrf else "(_afis_)"] = _srts
return _static_rts, _delete_spc
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py
index 9d206f509..ad95b680a 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vlans/vlans.py
@@ -20,7 +20,10 @@ __metaclass__ = type
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base import (
ConfigBase,
)
-from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import to_list
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ remove_empties,
+ to_list,
+)
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.facts import Facts
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.utils.utils import dict_to_set
@@ -44,6 +47,7 @@ class Vlans(ConfigBase):
:rtype: A dictionary
:returns: The current configuration as a dictionary
"""
+
facts, _warnings = Facts(self._module).get_facts(
self.gather_subset,
self.gather_network_resources,
@@ -63,7 +67,12 @@ class Vlans(ConfigBase):
result = {"changed": False}
commands = list()
warnings = list()
-
+ self.have_now = list()
+ self.configuration = self._module.params["configuration"]
+ if not self.configuration:
+ self.vlan_parent = "vlan {0}"
+ else:
+ self.vlan_parent = "vlan configuration {0}"
if self.state in self.ACTION_STATES:
existing_vlans_facts = self.get_vlans_facts()
else:
@@ -110,7 +119,10 @@ class Vlans(ConfigBase):
:returns: the commands necessary to migrate the current configuration
to the desired configuration
"""
- want = self._module.params["config"]
+ want = []
+ if self._module.params.get("config"):
+ for cfg in self._module.params["config"]:
+ want.append(remove_empties(cfg))
have = existing_vlans_facts
resp = self.set_state(want, have)
return to_list(resp)
@@ -173,6 +185,7 @@ class Vlans(ConfigBase):
commands = []
want_local = want
+ self.have_now = have.copy()
for each in have:
count = 0
for every in want_local:
@@ -264,7 +277,8 @@ class Vlans(ConfigBase):
def _set_config(self, want, have):
# Set the interface config based on the want and have config
commands = []
- vlan = "vlan {0}".format(want.get("vlan_id"))
+
+ vlan = self.vlan_parent.format(want.get("vlan_id"))
def negate_have_config(want_diff, have_diff, vlan, commands):
name = dict(have_diff).get("name")
@@ -294,8 +308,9 @@ class Vlans(ConfigBase):
self.remove_command_from_config_list(vlan, "private-vlan association", commands)
# Get the diff b/w want n have
- want_dict = dict_to_set(want)
- have_dict = dict_to_set(have)
+
+ want_dict = dict_to_set(want, sort_dictionary=True)
+ have_dict = dict_to_set(have, sort_dictionary=True)
diff = want_dict - have_dict
have_diff = have_dict - want_dict
@@ -303,69 +318,140 @@ class Vlans(ConfigBase):
if have_diff and (self.state == "replaced" or self.state == "overridden"):
negate_have_config(diff, have_diff, vlan, commands)
- name = dict(diff).get("name")
- state = dict(diff).get("state")
- shutdown = dict(diff).get("shutdown")
- mtu = dict(diff).get("mtu")
- remote_span = dict(diff).get("remote_span")
- private_vlan = dict(diff).get("private_vlan")
-
- if name:
- self.add_command_to_config_list(vlan, "name {0}".format(name), commands)
- if state:
- self.add_command_to_config_list(vlan, "state {0}".format(state), commands)
- if mtu:
- self.add_command_to_config_list(vlan, "mtu {0}".format(mtu), commands)
- if remote_span:
- self.add_command_to_config_list(vlan, "remote-span", commands)
-
- if private_vlan:
- private_vlan_type = dict(private_vlan).get("type")
- private_vlan_associated = dict(private_vlan).get("associated")
- if private_vlan_type:
- self.add_command_to_config_list(
- vlan,
- "private-vlan {0}".format(private_vlan_type),
- commands,
+ if not self.configuration:
+ name = dict(diff).get("name")
+ state = dict(diff).get("state")
+ shutdown = dict(diff).get("shutdown")
+ mtu = dict(diff).get("mtu")
+ remote_span = dict(diff).get("remote_span")
+ private_vlan = dict(diff).get("private_vlan")
+
+ if name:
+ self.add_command_to_config_list(vlan, "name {0}".format(name), commands)
+ if state:
+ self.add_command_to_config_list(vlan, "state {0}".format(state), commands)
+ if mtu:
+ self.add_command_to_config_list(vlan, "mtu {0}".format(mtu), commands)
+ if remote_span:
+ self.add_command_to_config_list(vlan, "remote-span", commands)
+
+ if private_vlan:
+ private_vlan_type = dict(private_vlan).get("type")
+ private_vlan_associated = dict(private_vlan).get("associated")
+ if private_vlan_type:
+ self.add_command_to_config_list(
+ vlan,
+ "private-vlan {0}".format(private_vlan_type),
+ commands,
+ )
+ if private_vlan_associated:
+ associated_list = ",".join(
+ str(e) for e in private_vlan_associated
+ ) # Convert python list to string with elements separated by a comma
+ self.add_command_to_config_list(
+ vlan,
+ "private-vlan association {0}".format(associated_list),
+ commands,
+ )
+ if shutdown == "enabled":
+ self.add_command_to_config_list(vlan, "shutdown", commands)
+ elif shutdown == "disabled":
+ self.add_command_to_config_list(vlan, "no shutdown", commands)
+ else:
+ member_dict = dict(diff).get("member")
+ if member_dict:
+ member_dict = dict(member_dict)
+ member_vni = member_dict.get("vni")
+ member_evi = member_dict.get("evi")
+ commands.extend(
+ self._remove_vlan_vni_evi_mapping(
+ want,
+ ),
)
- if private_vlan_associated:
- associated_list = ",".join(
- str(e) for e in private_vlan_associated
- ) # Convert python list to string with elements separated by a comma
- self.add_command_to_config_list(
- vlan,
- "private-vlan association {0}".format(associated_list),
- commands,
+ commands.extend(
+ [
+ vlan,
+ self._get_member_cmds(member_dict),
+ ],
)
- if shutdown == "enabled":
- self.add_command_to_config_list(vlan, "shutdown", commands)
- elif shutdown == "disabled":
- self.add_command_to_config_list(vlan, "no shutdown", commands)
elif have_diff and (self.state == "replaced" or self.state == "overridden"):
negate_have_config(diff, have_diff, vlan, commands)
-
return commands
def _clear_config(self, want, have):
# Delete the interface config based on the want and have config
commands = []
- vlan = "vlan {0}".format(have.get("vlan_id"))
+ vlan = self.vlan_parent.format(have.get("vlan_id"))
if (
have.get("vlan_id")
- and "default" not in have.get("name")
+ and "default" not in have.get("name", "")
and (have.get("vlan_id") != want.get("vlan_id") or self.state == "deleted")
):
self.remove_command_from_config_list(vlan, "vlan", commands)
- elif "default" not in have.get("name"):
- if have.get("mtu") != want.get("mtu"):
- self.remove_command_from_config_list(vlan, "mtu", commands)
- if have.get("remote_span") != want.get("remote_span") and want.get("remote_span"):
- self.remove_command_from_config_list(vlan, "remote-span", commands)
- if have.get("shutdown") != want.get("shutdown") and want.get("shutdown"):
- self.remove_command_from_config_list(vlan, "shutdown", commands)
- if have.get("state") != want.get("state") and want.get("state"):
- self.remove_command_from_config_list(vlan, "state", commands)
+ if self.configuration and self.state == "overridden":
+ self.have_now.remove(have)
+ elif "default" not in have.get("name", ""):
+ if not self.configuration:
+ if have.get("mtu") != want.get("mtu"):
+ self.remove_command_from_config_list(vlan, "mtu", commands)
+ if have.get("remote_span") != want.get("remote_span") and want.get("remote_span"):
+ self.remove_command_from_config_list(vlan, "remote-span", commands)
+ if have.get("shutdown") != want.get("shutdown") and want.get("shutdown"):
+ self.remove_command_from_config_list(vlan, "shutdown", commands)
+ if have.get("state") != want.get("state") and want.get("state"):
+ self.remove_command_from_config_list(vlan, "state", commands)
+ return commands
+ def _remove_vlan_vni_evi_mapping(self, want_dict):
+ commands = []
+ have_copy = self.have_now.copy()
+ vlan = want_dict["vlan_id"]
+ for vlan_dict in have_copy:
+ if vlan_dict["vlan_id"] == vlan:
+ if "member" in vlan_dict:
+ commands.extend(
+ [
+ self.vlan_parent.format(vlan),
+ self._get_member_cmds(
+ vlan_dict.get("member", {}),
+ prefix="no",
+ ),
+ ],
+ )
+ vlan_dict.pop("member")
+ if vlan_dict["vlan_id"] != vlan:
+ delete_member = False
+ have_vni = vlan_dict.get("member", {}).get("vni")
+ have_evi = vlan_dict.get("member", {}).get("evi")
+ if have_vni and (have_vni == want_dict["member"].get("vni")):
+ delete_member = True
+ if have_evi and (have_evi == want_dict["member"].get("evi")):
+ delete_member = True
+ if delete_member:
+ commands.extend(
+ [
+ self.vlan_parent.format(vlan_dict["vlan_id"]),
+ self._get_member_cmds(
+ vlan_dict.get("member", {}),
+ prefix="no",
+ ),
+ ],
+ )
+ self.have_now.remove(vlan_dict)
return commands
+
+ def _get_member_cmds(self, member_dict, prefix=""):
+ cmd = ""
+ if prefix:
+ prefix = prefix + " "
+ member_vni = member_dict.get("vni")
+ member_evi = member_dict.get("evi")
+
+ if member_evi:
+ cmd = prefix + "member evpn-instance {0} vni {1}".format(member_evi, member_vni)
+ elif member_vni:
+ cmd = prefix + "member vni {0}".format(member_vni)
+
+ return cmd
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/vxlan_vtep.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/vxlan_vtep.py
new file mode 100644
index 000000000..bb35b04e4
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/config/vxlan_vtep/vxlan_vtep.py
@@ -0,0 +1,190 @@
+#
+# -*- 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 ios_vxlan_vtep 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 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,
+ param_list_to_dict,
+)
+
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.facts import Facts
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.vxlan_vtep import (
+ Vxlan_vtepTemplate,
+)
+
+
+class Vxlan_vtep(ResourceModule):
+ """
+ The ios_vxlan_vtep config class
+ """
+
+ def __init__(self, module):
+ super(Vxlan_vtep, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="vxlan_vtep",
+ tmplt=Vxlan_vtepTemplate(),
+ )
+ self.parsers = [
+ "source_interface",
+ "host_reachability_bgp",
+ ]
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+ return self.result
+
+ def generate_commands(self):
+ """Generate configuration commands to send based on
+ want, have and desired state.
+ """
+
+ wantd, haved = self._interface_list_to_dict(self.want, 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_copy = wantd.copy()
+ wantd = {}
+
+ # remove superfluous config for deleted
+ if self.state in ["overridden", "deleted"]:
+ for k, have in iteritems(haved):
+ if k not in wantd:
+ have = self._filtered_dict(wantd_copy.get(k), have)
+ self._compare(want={}, have=have)
+
+ for k, want in iteritems(wantd):
+ self._compare(want=want, have=haved.pop(k, {}))
+
+ def _compare(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 Vxlan_vtep network resource.
+ """
+
+ begin = len(self.commands)
+ self.compare(parsers=self.parsers, want=want, have=have)
+
+ self._compare_member_vnis(
+ want.pop("member", {}).get("vni", {}),
+ have.pop("member", {}).get("vni", {}),
+ )
+
+ if len(self.commands) != begin:
+ self.commands.insert(
+ begin,
+ self._tmplt.render(want or have, "interface", False),
+ )
+
+ def _compare_member_vnis(self, wantmv, havemv):
+ """Compare member VNIs dict"""
+
+ PARSER_DICT = {
+ "l2vni": "replication",
+ "l3vni": "vrf",
+ }
+
+ for vni_type in ["l2vni", "l3vni"]:
+ wantd = wantmv.get(vni_type, {})
+ haved = havemv.get(vni_type, {})
+ undel_vnis = haved.copy()
+
+ for wvni, want in wantd.items():
+ have = haved.pop(wvni, {})
+ if want != have:
+ # remove exiting config of the member VNI
+ self.addcmd(undel_vnis.pop(wvni, {}), PARSER_DICT[vni_type], True)
+ if vni_type == "l3vni":
+ undel_vnis = self._remove_existing_vnis_vrfs(want["vrf"], undel_vnis)
+ self.addcmd(want, PARSER_DICT[vni_type])
+
+ # remove remaining configs in have for replaced state
+ for hvni, have in haved.items():
+ if hvni in undel_vnis:
+ self.addcmd(have, PARSER_DICT[vni_type], True)
+
+ def _interface_list_to_dict(self, want, have):
+ """Convert all list of dicts to dicts of dicts"""
+
+ wantd = {entry["interface"]: entry for entry in want}
+ haved = {entry["interface"]: entry for entry in have}
+
+ for each in wantd, haved:
+ if each:
+ for nvi, nvid in each.items():
+ member_vni = nvid.get("member", {}).get("vni")
+ if member_vni:
+ for vni_type in member_vni:
+ member_vni[vni_type] = param_list_to_dict(
+ member_vni[vni_type],
+ unique_key="vni",
+ remove_key=False,
+ )
+
+ return wantd, haved
+
+ def _remove_existing_vnis_vrfs(self, want_vrf, haved):
+ """Remove member VNIs of corresponding VRF"""
+
+ vrf_haved = next(
+ (h for h in haved.values() if h["vrf"] == want_vrf),
+ None,
+ )
+ if vrf_haved:
+ self.addcmd(haved.pop(vrf_haved["vni"]), "vrf", True)
+ return haved
+
+ def _filtered_dict(self, want, have):
+ """Remove other config from 'have' if 'member' key is present"""
+
+ if "member" in want:
+ have_member = {}
+ want_vni_dict = want.get("member", {}).get("vni", {})
+ have_vni_dict = have.get("member", {}).get("vni", {})
+
+ for vni_type, have_vnis in have_vni_dict.items():
+ want_vnis = want_vni_dict.get(vni_type, {})
+ have_member[vni_type] = {
+ vni: have_vni_dict[vni_type].get(vni) for vni in have_vnis if vni in want_vnis
+ }
+ have = {
+ "interface": have["interface"],
+ "member": {"vni": have_member},
+ }
+
+ return have
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/acls/acls.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/acls/acls.py
index 6037d99e1..2be369a7a 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/acls/acls.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/acls/acls.py
@@ -17,6 +17,7 @@ __metaclass__ = type
import re
+from ansible.module_utils._text import to_text
from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
@@ -34,28 +35,49 @@ from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates
class AclsFacts(object):
"""The ios_acls fact class"""
- def __init__(self, module, subspec="config", options="options"):
+ def __init__(self, module):
self._module = module
self.argument_spec = AclsArgs.argument_spec
def get_acl_data(self, connection):
- # Get the access-lists from the ios router
- # Get the remarks on access-lists from the ios router
- # alternate command 'sh run partition access-list' but has a lot of ordering issues
- # and incomplete ACLs are not viewed correctly
- _acl_data = connection.get("show access-list")
- _remarks_data = connection.get("show running-config | include ip(v6)* access-list|remark")
- if _remarks_data:
- _acl_data += "\n" + _remarks_data
- return _acl_data
+ # Removed the show access-list
+ # Removed the show running-config | include ip(v6)* access-list|remark
+ return connection.get("show running-config | section access-list")
+
+ def get_acl_names(self, connection):
+ # this information is required to scoop out the access lists which has no aces
+ return connection.get("show access-lists | include access list")
+
+ def populate_empty_acls(self, raw_acls, raw_acls_name):
+ # this would update empty acls to the full acls entry
+ if raw_acls and raw_acls_name:
+ for aclnames, acldata in raw_acls_name.get("acls").items():
+ if aclnames not in raw_acls.get("acls").keys():
+ if not raw_acls.get("acls"):
+ raw_acls["acls"] = {}
+ raw_acls["acls"][aclnames] = acldata
+ elif raw_acls_name and not raw_acls:
+ for aclnames, acldata in raw_acls_name.get("acls").items():
+ if not raw_acls.get("acls"):
+ raw_acls["acls"] = {}
+ raw_acls["acls"][aclnames] = acldata
+ return raw_acls
def sanitize_data(self, data):
"""removes matches or extra config info that is added on acl match"""
re_data = ""
+ remarks_idx = 0
for da in data.split("\n"):
if "match" in da:
mod_da = re.sub(r"\([^()]*\)", "", da)
re_data += mod_da[:-1] + "\n"
+ elif re.match(r"\s*\d+\sremark.+", da, re.IGNORECASE) or re.match(
+ r"\s*remark.+",
+ da,
+ re.IGNORECASE,
+ ):
+ remarks_idx += 1
+ re_data += to_text(remarks_idx) + " " + da + "\n"
else:
re_data += da + "\n"
return re_data
@@ -68,21 +90,30 @@ class AclsFacts(object):
:rtype: dictionary
:returns: facts
"""
+ namedata = ""
if not data:
data = self.get_acl_data(connection)
+ namedata = self.get_acl_names(connection)
if data:
data = self.sanitize_data(data)
- rmmod = NetworkTemplate(lines=data.splitlines(), tmplt=AclsTemplate())
- current = rmmod.parse()
+ # parse main information
+ templateObjMain = NetworkTemplate(lines=data.splitlines(), tmplt=AclsTemplate())
+ raw_acls = templateObjMain.parse()
+
+ if namedata:
+ # parse just names to update empty acls
+ templateObjName = NetworkTemplate(lines=namedata.splitlines(), tmplt=AclsTemplate())
+ raw_acl_names = templateObjName.parse()
+ raw_acls = self.populate_empty_acls(raw_acls, raw_acl_names)
temp_v4 = []
temp_v6 = []
- if current.get("acls"):
- for k, v in iteritems(current.get("acls")):
+ if raw_acls.get("acls"):
+ for k, v in iteritems(raw_acls.get("acls")):
if v.get("afi") == "ipv4" and v.get("acl_type") in ["standard", "extended"]:
del v["afi"]
temp_v4.append(v)
@@ -99,6 +130,14 @@ class AclsFacts(object):
_temp_addr = temp.get("address", "")
ace[typ]["address"] = _temp_addr.split(" ")[0]
ace[typ]["wildcard_bits"] = _temp_addr.split(" ")[1]
+ if temp.get("ipv6_address"):
+ _temp_addr = temp.get("ipv6_address", "")
+ if len(_temp_addr.split(" ")) == 2:
+ ipv6_add = ace[typ].pop("ipv6_address")
+ ace[typ]["address"] = ipv6_add.split(" ")[0]
+ ace[typ]["wildcard_bits"] = ipv6_add.split(" ")[1]
+ else:
+ ace[typ]["address"] = ace[typ].pop("ipv6_address")
def process_protocol_options(each):
for each_ace in each.get("aces"):
@@ -131,14 +170,25 @@ class AclsFacts(object):
def collect_remarks(aces):
"""makes remarks list per ace"""
ace_entry = []
- rem = []
+ ace_rem = []
+ rem = {}
for i in aces:
- if i.get("remarks"):
- rem.append(i.pop("remarks"))
+ if i.get("is_remark_for"):
+ if not rem.get(i.get("is_remark_for")):
+ rem[i.get("is_remark_for")] = {"remarks": []}
+ rem[i.get("is_remark_for")]["remarks"].append(i.get("the_remark"))
+ else:
+ rem[i.get("is_remark_for")]["remarks"].append(i.get("the_remark"))
else:
+ if rem:
+ if rem.get(i.get("sequence")):
+ ace_rem = rem.pop(i.get("sequence"))
+ i["remarks"] = ace_rem.get("remarks")
ace_entry.append(i)
- if rem:
- ace_entry.append({"remarks": rem})
+
+ if rem: # pending remarks
+ pending_rem = rem.get("remark")
+ ace_entry.append({"remarks": pending_rem.get("remarks")})
return ace_entry
for each in temp_v4:
@@ -148,7 +198,7 @@ class AclsFacts(object):
for each in temp_v6:
if each.get("aces"):
- each["aces"] = collect_remarks(each.get("aces"))
+ # each["aces"] = collect_remarks(each.get("aces"))
process_protocol_options(each)
objs = []
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/bgp_global/bgp_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/bgp_global/bgp_global.py
index 68ff93636..37bbfabfd 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/bgp_global/bgp_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/bgp_global/bgp_global.py
@@ -51,7 +51,10 @@ class Bgp_globalFacts(object):
data = self.get_bgp_global_data(connection)
# parse native config using the Bgp_global template
- bgp_global_parser = Bgp_globalTemplate(lines=data.splitlines(), module=self._module)
+ bgp_global_parser = Bgp_globalTemplate(
+ lines=data.splitlines(),
+ module=self._module,
+ )
objs = bgp_global_parser.parse()
neighbor_list = objs.get("neighbors", {})
if neighbor_list:
@@ -64,7 +67,11 @@ class Bgp_globalFacts(object):
ansible_facts["ansible_network_resources"].pop("bgp_global", None)
params = utils.remove_empties(
- bgp_global_parser.validate_config(self.argument_spec, {"config": obj}, redact=True),
+ bgp_global_parser.validate_config(
+ self.argument_spec,
+ {"config": obj},
+ redact=True,
+ ),
)
facts["bgp_global"] = params.get("config", {})
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/evpn_evi.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/evpn_evi.py
new file mode 100644
index 000000000..be6cfb3bf
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_evi/evpn_evi.py
@@ -0,0 +1,67 @@
+# -*- 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 ios evpn_evi 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.ios.plugins.module_utils.network.ios.argspec.evpn_evi.evpn_evi import (
+ Evpn_eviArgs,
+)
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.evpn_evi import (
+ Evpn_eviTemplate,
+)
+
+
+class Evpn_eviFacts(object):
+ """The ios evpn_evi facts class"""
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = Evpn_eviArgs.argument_spec
+
+ def get_evpn_evi_data(self, connection):
+ return connection.get("show running-config | section ^l2vpn evpn instance .+$")
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Evpn_evi 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_evpn_evi_data(connection)
+
+ # parse native config using the Evpn_evi template
+ evpn_evi_parser = Evpn_eviTemplate(lines=data.splitlines(), module=self._module)
+ objs = list(evpn_evi_parser.parse().values())
+
+ ansible_facts["ansible_network_resources"].pop("evpn_evi", None)
+
+ params = utils.remove_empties(
+ evpn_evi_parser.validate_config(self.argument_spec, {"config": objs}, redact=True),
+ )
+
+ facts["evpn_evi"] = params.get("config", [])
+ ansible_facts["ansible_network_resources"].update(facts)
+
+ return ansible_facts
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/evpn_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/evpn_global.py
new file mode 100644
index 000000000..68ecfc711
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/evpn_global/evpn_global.py
@@ -0,0 +1,68 @@
+# -*- 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 ios evpn_global fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.argspec.evpn_global.evpn_global import (
+ Evpn_globalArgs,
+)
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.evpn_global import (
+ Evpn_globalTemplate,
+)
+
+
+class Evpn_globalFacts(object):
+ """The ios evpn_global facts class"""
+
+ def __init__(self, module):
+ self._module = module
+ self.argument_spec = Evpn_globalArgs.argument_spec
+
+ def get_evpn_global_data(self, connection):
+ return connection.get("show running-config | section ^l2vpn evpn$")
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Evpn_global 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_evpn_global_data(connection)
+
+ # parse native config using the Evpn_global template
+ evpn_global_parser = Evpn_globalTemplate(lines=data.splitlines(), module=self._module)
+ objs = evpn_global_parser.parse()
+ obj = utils.remove_empties(objs)
+
+ ansible_facts["ansible_network_resources"].pop("evpn_global", None)
+
+ params = utils.remove_empties(
+ evpn_global_parser.validate_config(self.argument_spec, {"config": obj}, redact=True),
+ )
+
+ facts["evpn_global"] = params.get("config", {})
+ ansible_facts["ansible_network_resources"].update(facts)
+
+ return ansible_facts
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py
index 6a28043bf..7718b474d 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/facts.py
@@ -29,6 +29,12 @@ from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.bgp_ad
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.bgp_global.bgp_global import (
Bgp_globalFacts,
)
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.evpn_evi.evpn_evi import (
+ Evpn_eviFacts,
+)
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.evpn_global.evpn_global import (
+ Evpn_globalFacts,
+)
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.hostname.hostname import (
HostnameFacts,
)
@@ -93,6 +99,9 @@ from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.static
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.vlans.vlans import (
VlansFacts,
)
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.facts.vxlan_vtep.vxlan_vtep import (
+ Vxlan_vtepFacts,
+)
FACT_LEGACY_SUBSETS = dict(default=Default, hardware=Hardware, interfaces=Interfaces, config=Config)
@@ -122,6 +131,9 @@ FACT_RESOURCE_SUBSETS = dict(
service=ServiceFacts,
snmp_server=Snmp_serverFacts,
hostname=HostnameFacts,
+ vxlan_vtep=Vxlan_vtepFacts,
+ evpn_global=Evpn_globalFacts,
+ evpn_evi=Evpn_eviFacts,
)
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/legacy/base.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/legacy/base.py
index de92f1ed5..5344ca627 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/legacy/base.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/legacy/base.py
@@ -125,26 +125,31 @@ class Default(FactsBase):
class Hardware(FactsBase):
- COMMANDS = ["dir", "show memory statistics"]
+ COMMANDS = ["dir", "show memory statistics", "show processes cpu | include CPU utilization"]
def populate(self):
warnings = list()
super(Hardware, self).populate()
+
data = self.responses[0]
if data:
self.facts["filesystems"] = self.parse_filesystems(data)
self.facts["filesystems_info"] = self.parse_filesystems_info(data)
+ self.facts["cpu_utilization"] = self.parse_cpu_utilization(self.responses[2])
data = self.responses[1]
if data:
if "Invalid input detected" in data:
warnings.append("Unable to gather memory statistics")
else:
- processor_line = [line for line in data.splitlines() if "Processor" in line].pop()
- match = re.findall(r"\s(\d+)\s", processor_line)
- if match:
- self.facts["memtotal_mb"] = int(match[0]) / 1048576
- self.facts["memfree_mb"] = int(match[2]) / 1048576
+ for line in data.splitlines():
+ match = re.match(
+ r"Processor\s+(\S+|\d+)\s+(?P<total>\d+)\s+\d+\s+(?P<free>\d+)",
+ line,
+ )
+ if match:
+ self.facts["memtotal_mb"] = int(match.group("total")) / 1048576
+ self.facts["memfree_mb"] = int(match.group("free")) / 1048576
def parse_filesystems(self, data):
return re.findall(r"^Directory of (\S+)/", data, re.M)
@@ -164,6 +169,37 @@ class Hardware(FactsBase):
facts[fs]["spacefree_kb"] = int(match.group(2)) / 1024
return facts
+ def parse_cpu_utilization(self, data):
+ facts = {}
+ regex_cpu_utilization = re.compile(
+ r"""
+ (^Core\s(?P<core>\d+)?:)?
+ (^|\s)CPU\sutilization\sfor\sfive\sseconds:
+ (\s(?P<f_sec>\d+)?%)?
+ (\s(?P<f_se_nom>\d+)%/(?P<f_s_denom>\d+)%\)?)?
+ ;\sone\sminute:\s(?P<a_min>\d+)?%
+ ;\sfive\sminutes:\s(?P<f_min>\d+)?%
+ """,
+ re.VERBOSE,
+ )
+ for line in data.split("\n"):
+ match_cpu_utilization = regex_cpu_utilization.match(line)
+ if match_cpu_utilization:
+ _core = "core"
+ if match_cpu_utilization.group("core"):
+ _core = "core_" + str(match_cpu_utilization.group("core"))
+ facts[_core] = {}
+ facts[_core]["five_seconds"] = int(
+ match_cpu_utilization.group("f_se_nom") or match_cpu_utilization.group("f_sec"),
+ )
+ facts[_core]["one_minute"] = int(match_cpu_utilization.group("a_min"))
+ facts[_core]["five_minutes"] = int(match_cpu_utilization.group("f_min"))
+ if match_cpu_utilization.group("f_s_denom"):
+ facts[_core]["five_seconds_interrupt"] = int(
+ match_cpu_utilization.group("f_s_denom"),
+ )
+ return facts
+
class Config(FactsBase):
COMMANDS = ["show running-config"]
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/logging_global/logging_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/logging_global/logging_global.py
index 639d43dba..5e955217c 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/logging_global/logging_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/logging_global/logging_global.py
@@ -58,17 +58,17 @@ class Logging_globalFacts(object):
if objFinal:
for k, v in iteritems(objFinal):
- if type(v) == list and k not in ["hosts", "source_interface", "filter"]:
+ if isinstance(v, list) and k not in ["hosts", "source_interface", "filter"]:
v.sort()
objFinal[k] = v
- elif type(v) == list and k == "hosts":
+ elif isinstance(v, list) and k == "hosts":
objFinal[k] = sorted(
objFinal[k],
key=lambda item: item["host"] if item.get("host") else item.get("ipv6"),
)
- elif type(v) == list and k == "source_interface":
+ elif isinstance(v, list) and k == "source_interface":
objFinal[k] = sorted(objFinal[k], key=lambda item: item["interface"])
- elif type(v) == list and k == "filter":
+ elif isinstance(v, list) and k == "filter":
objFinal[k] = sorted(objFinal[k], key=lambda item: item["url"])
ansible_facts["ansible_network_resources"].pop("logging_global", None)
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/ospfv2/ospfv2.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/ospfv2/ospfv2.py
index 48a77de99..66fc35d2c 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/ospfv2/ospfv2.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/ospfv2/ospfv2.py
@@ -37,6 +37,27 @@ class Ospfv2Facts(object):
def get_ospfv2_data(self, connection):
return connection.get("show running-config | section ^router ospf")
+ def dict_to_list(self, ospf_data):
+ """Converts areas, interfaces in each process to list
+ :param ospf_data: ospf data
+ :rtype: dictionary
+ :returns: facts_output
+ """
+
+ facts_output = {"processes": []}
+
+ for process in ospf_data.get("processes", []):
+ if "passive_interfaces" in process and process["passive_interfaces"].get("default"):
+ if process.get("passive_interfaces", {}).get("interface"):
+ process["passive_interfaces"]["interface"]["name"] = [
+ each for each in process["passive_interfaces"]["interface"]["name"] if each
+ ]
+ if "areas" in process:
+ process["areas"] = list(process["areas"].values())
+ facts_output["processes"].append(process)
+
+ return facts_output
+
def populate_facts(self, connection, ansible_facts, data=None):
"""Populate the facts for ospfv2
:param connection: the device connection
@@ -45,42 +66,28 @@ class Ospfv2Facts(object):
:rtype: dictionary
:returns: facts
"""
+
+ facts = {}
+
if not data:
data = self.get_ospfv2_data(connection)
- ipv4 = {"processes": []}
- rmmod = NetworkTemplate(lines=data.splitlines(), tmplt=Ospfv2Template())
- current = rmmod.parse()
+ ospf_temp_obj = NetworkTemplate(lines=data.splitlines(), tmplt=Ospfv2Template())
+ ospf_parsed = ospf_temp_obj.parse()
- # convert some of the dicts to lists
- for key, sortv in [("processes", "process_id")]:
- if key in current and current[key]:
- current[key] = current[key].values()
- current[key] = sorted(current[key], key=lambda k, sk=sortv: k[sk])
+ # Convert dict to list
+ ospf_parsed["processes"] = (
+ ospf_parsed["processes"].values() if "processes" in ospf_parsed else []
+ )
- for process in current.get("processes", []):
- if "passive_interfaces" in process and process["passive_interfaces"].get("default"):
- if process["passive_interfaces"].get("interface"):
- temp = []
- for each in process["passive_interfaces"]["interface"]["name"]:
- if each:
- temp.append(each)
- process["passive_interfaces"]["interface"]["name"] = temp
- if "areas" in process:
- process["areas"] = list(process["areas"].values())
- process["areas"] = sorted(process["areas"], key=lambda k, sk="area_id": k[sk])
- for area in process["areas"]:
- if "filters" in area:
- area["filters"].sort()
- ipv4["processes"].append(process)
+ # converts areas, interfaces in each process to list
+ facts_output = self.dict_to_list(ospf_parsed)
ansible_facts["ansible_network_resources"].pop("ospfv2", None)
- facts = {}
- if current:
- params = utils.validate_config(self.argument_spec, {"config": ipv4})
- params = utils.remove_empties(params)
+ if ospf_parsed["processes"]:
+ params = utils.validate_config(self.argument_spec, {"config": facts_output})
+ params = utils.remove_empties(params)
facts["ospfv2"] = params["config"]
-
ansible_facts["ansible_network_resources"].update(facts)
return ansible_facts
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/prefix_lists/prefix_lists.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/prefix_lists/prefix_lists.py
index 167f68c73..80a73e18c 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/prefix_lists/prefix_lists.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/prefix_lists/prefix_lists.py
@@ -15,9 +15,6 @@ for a given resource, parsed, and the facts tree is populated
based on the configuration.
"""
-from copy import copy
-
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.argspec.prefix_lists.prefix_lists import (
@@ -59,50 +56,18 @@ class Prefix_listsFacts(object):
objs = prefix_lists_parser.parse()
final_objs = []
- temp = {}
- temp["afi"] = None
- temp["prefix_lists"] = []
+
+ _prefix_list = {"ipv4": [], "ipv6": []}
if objs:
- for k, v in iteritems(objs):
- temp_prefix_list = {}
- temp_prefix_list["entries"] = []
- if not temp["afi"] or v["afi"] != temp["afi"]:
- if temp and temp["afi"]:
- temp["prefix_lists"] = sorted(
- temp["prefix_lists"],
- key=lambda k, sk="name": str(k[sk]),
- )
- # additional check for py3.5
- if len(final_objs) == 2:
- for each in final_objs:
- if v["afi"] == each["afi"]:
- each["prefix_lists"].extend(temp["prefix_lists"])
- else:
- final_objs.append(copy(temp))
- temp["prefix_lists"] = []
- temp["afi"] = v["afi"]
- for each in v["prefix_lists"]:
- if not temp_prefix_list.get("name"):
- temp_prefix_list["name"] = each["name"]
- if not temp_prefix_list.get("description") and each.get("description"):
- temp_prefix_list["description"] = each["description"]
- if each["entries"] and not each["entries"].get("description"):
- temp_prefix_list["entries"].append(each["entries"])
- temp["prefix_lists"].append(temp_prefix_list)
- if temp and temp["afi"]:
- temp["prefix_lists"] = sorted(
- temp["prefix_lists"],
- key=lambda k, sk="name": str(k[sk]),
+ for prefixes in list(objs.values()):
+ _afi = prefixes.pop("afi")
+ _prefix_list[_afi].append(
+ prefixes,
)
- # additional check for py3.5
- if len(final_objs) == 2:
- for each in final_objs:
- if v["afi"] == each["afi"]:
- each["prefix_lists"].extend(temp["prefix_lists"])
- else:
- final_objs.append(copy(temp))
-
- final_objs = sorted(final_objs, key=lambda k, sk="afi": k[sk])
+ if _prefix_list.get("ipv4"):
+ final_objs.append({"afi": "ipv4", "prefix_lists": _prefix_list.pop("ipv4")})
+ if _prefix_list.get("ipv6"):
+ final_objs.append({"afi": "ipv6", "prefix_lists": _prefix_list.pop("ipv6")})
ansible_facts["ansible_network_resources"].pop("prefix_lists", None)
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/snmp_server/snmp_server.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/snmp_server/snmp_server.py
index 2fc1042e7..a153ac0a8 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/snmp_server/snmp_server.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/snmp_server/snmp_server.py
@@ -15,6 +15,8 @@ for a given resource, parsed, and the facts tree is populated
based on the configuration.
"""
+import re
+
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
from ansible_collections.cisco.ios.plugins.module_utils.network.ios.argspec.snmp_server.snmp_server import (
@@ -33,7 +35,7 @@ class Snmp_serverFacts(object):
self.argument_spec = Snmp_serverArgs.argument_spec
def get_snmp_data(self, connection):
- _get_snmp_data = connection.get("show running-config | section ^snmp-server")
+ _get_snmp_data = connection.get("show running-config | section ^snmp")
return _get_snmp_data
def get_snmpv3_user_data(self, connection):
@@ -46,7 +48,12 @@ class Snmp_serverFacts(object):
Note: The seperate method is needed because the snmpv3 user data is not returned within the snmp-server config
"""
- _get_snmpv3_user = connection.get("show snmp user")
+ try:
+ _get_snmpv3_user = connection.get("show snmp user")
+ except Exception as e:
+ if "agent not enabled" in str(e):
+ return ""
+ raise Exception("Unable to get snmp user data: %s" % str(e))
return _get_snmpv3_user
def sort_list_dicts(self, objs):
@@ -87,18 +94,36 @@ class Snmp_serverFacts(object):
"""
user_sets = snmpv3_user.split("User ")
user_list = []
+ re_snmp_auth = re.compile(r"^Authentication Protocol:\s*(MD5|SHA)")
+ re_snmp_priv = re.compile(r"^Privacy Protocol:\s*(3DES|AES|DES)([0-9]*)")
+ re_snmp_acl = re.compile(r"^.*active\s+(access-list: (\S+)|)\s*(IPv6 access-list: (\S+)|)")
for user_set in user_sets:
one_set = {}
lines = user_set.splitlines()
for line in lines:
if line.startswith("name"):
one_set["username"] = line.split(": ")[1]
+ continue
if line.startswith("Group-name:"):
one_set["group"] = line.split(": ")[1]
- if "IPv6 access-list:" in line:
- one_set["acl_v6"] = line.split(": ")[-1]
- if "active\taccess-list:" in line:
- one_set["acl_v4"] = line.split(": ")[-1]
+ continue
+ re_match = re_snmp_auth.search(line)
+ if re_match:
+ one_set["authentication"] = {"algorithm": re_match.group(1).lower()}
+ continue
+ re_match = re_snmp_priv.search(line)
+ if re_match:
+ one_set["encryption"] = {"priv": re_match.group(1).lower()}
+ if re_match.group(2):
+ one_set["encryption"]["priv_option"] = re_match.group(2)
+ continue
+ re_match = re_snmp_acl.search(line)
+ if re_match:
+ if re_match.group(2):
+ one_set["acl_v4"] = re_match.group(2)
+ if re_match.group(4):
+ one_set["acl_v6"] = re_match.group(4)
+ continue
one_set["version"] = "v3" # defaults to version 3 data
if len(one_set):
user_list.append(one_set)
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py
index 73f73a5a2..9b506fa90 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vlans/vlans.py
@@ -16,6 +16,8 @@ from __future__ import absolute_import, division, print_function
__metaclass__ = type
+import re
+
from copy import deepcopy
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
@@ -42,14 +44,18 @@ class VlansFacts(object):
self.generated_spec = utils.generate_dict(facts_argument_spec)
- def get_vlans_data(self, connection):
+ def get_vlans_data(self, connection, configuration):
"""Checks device is L2/L3 and returns
facts gracefully. Does not fail module.
"""
+ if configuration:
+ cmd = "show running-config | sec ^vlan configuration .+"
+ else:
+ cmd = "show vlan"
check_os_type = connection.get_device_info()
if check_os_type.get("network_os_type") == "L3":
return ""
- return connection.get("show vlan")
+ return connection.get(cmd)
def populate_facts(self, connection, ansible_facts, data=None):
"""Populate the facts for vlans
@@ -59,14 +65,134 @@ class VlansFacts(object):
:rtype: dictionary
:returns: facts
"""
+ configuration = self._module.params["configuration"]
+ objs = []
+
+ if not data:
+ data = self.get_vlans_data(connection, configuration)
+ if not configuration:
+ objs = self.parse_vlan(data)
+ else:
+ objs = self.parse_vlan_config(data)
+
+ facts = {}
+ if objs:
+ facts["vlans"] = []
+ params = utils.validate_config(self.argument_spec, {"config": objs})
+
+ for cfg in params["config"]:
+ facts["vlans"].append(utils.remove_empties(cfg))
+ ansible_facts["ansible_network_resources"].update(facts)
+ return ansible_facts
+
+ def render_config(self, spec, conf, vlan_info):
+ """
+ Render config as dictionary structure and delete keys
+ from spec for null values
+
+ :param spec: The facts tree, generated from the argspec
+ :param conf: The configuration
+ :rtype: dictionary
+ :returns: The generated config
+ """
+ config = deepcopy(spec)
+
+ if vlan_info == "Name" and "VLAN Name" not in conf:
+ conf = list(filter(None, conf.split(" ")))
+ config["vlan_id"] = int(conf[0])
+ config["name"] = conf[1]
+ state_idx = 2
+ for i in range(2, len(conf)): # check for index where state starts
+ if conf[i] in ["suspended", "active"]:
+ state_idx = i
+ break
+ elif conf[i].split("/")[0] in ["sus", "act"]:
+ state_idx = i
+ break
+ config["name"] += " " + conf[i]
+ try:
+ if len(conf[state_idx].split("/")) > 1:
+ _state = conf[state_idx].split("/")[0]
+ if _state == "sus":
+ config["state"] = "suspend"
+ elif _state == "act":
+ config["state"] = "active"
+ config["shutdown"] = "enabled"
+ else:
+ if conf[state_idx] == "suspended":
+ config["state"] = "suspend"
+ elif conf[state_idx] == "active":
+ config["state"] = "active"
+ config["shutdown"] = "disabled"
+ except IndexError:
+ pass
+ elif vlan_info == "Type" and "VLAN Type" not in conf:
+ conf = list(filter(None, conf.split(" ")))
+ config["mtu"] = int(conf[3])
+ elif vlan_info == "Remote":
+ if len(conf.split(",")) > 1 or conf.isdigit():
+ remote_span_vlan = []
+ if len(conf.split(",")) > 1:
+ remote_span_vlan = conf.split(",")
+ else:
+ remote_span_vlan.append(conf)
+ remote_span = []
+ for each in remote_span_vlan:
+ split_sp_list = each.split("-")
+ if len(split_sp_list) > 1: # break range
+ for r_sp in range(int(split_sp_list[0]), int(split_sp_list[1]) + 1):
+ remote_span.append(r_sp)
+ else:
+ remote_span.append(int(each))
+ config["remote_span"] = remote_span
+
+ elif vlan_info == "Private" and "Primary Secondary" not in conf:
+ conf = list(filter(None, conf.split(" ")))
+
+ pri_idx = 0
+ sec_idx = 1
+ priv_type_idx = 2
+
+ config["tmp_pvlans"] = {
+ "primary": conf[pri_idx],
+ "secondary": conf[sec_idx],
+ "sec_type": conf[priv_type_idx],
+ }
+ return utils.remove_empties(config)
+
+ def parse_vlan_config(self, vlan_conf):
+ vlan_list = list()
+
+ re1 = re.compile(r"^vlan configuration +(?P<vlan>\d+)$")
+ re2 = re.compile(r"^member +(evpn\-instance +(?P<evi>\d+) )?vni (?P<vni>[\d\-]+)$")
+
+ for line in vlan_conf.splitlines():
+ line = line.strip()
+ m = re1.match(line)
+ if m:
+ vlan = m.groupdict()["vlan"]
+ vlan_dict = {"vlan_id": vlan}
+ continue
+
+ m = re2.match(line)
+ if m:
+ group = m.groupdict()
+ vlan_dict.update({"member": {}})
+ vlan_dict["member"].update({"vni": group["vni"]})
+ if group["evi"]:
+ vlan_dict["member"].update({"evi": group["evi"]})
+ vlan_list.append(vlan_dict)
+
+ return vlan_list
+
+ def parse_vlan(self, data):
objs = []
mtu_objs = []
remote_objs = []
final_objs = []
pvlan_objs = []
- if not data:
- data = self.get_vlans_data(connection)
+
# operate on a collection of resource x
config = data.split("\n")
# Get individual vlan configs separately
@@ -124,6 +250,7 @@ class VlansFacts(object):
pvlan_final = {}
if len(pvlan_objs) > 0:
# Sanitize and structure everything
+
for data in pvlan_objs:
pvdata = data.get("tmp_pvlans")
privlan = pvdata.get("primary")
@@ -151,89 +278,7 @@ class VlansFacts(object):
if vlan_id == every.get("vlan_id"):
every.update(data)
- facts = {}
if final_objs:
- facts["vlans"] = []
- params = utils.validate_config(self.argument_spec, {"config": objs})
-
- for cfg in params["config"]:
- facts["vlans"].append(utils.remove_empties(cfg))
- ansible_facts["ansible_network_resources"].update(facts)
-
- return ansible_facts
-
- def render_config(self, spec, conf, vlan_info):
- """
- Render config as dictionary structure and delete keys
- from spec for null values
-
- :param spec: The facts tree, generated from the argspec
- :param conf: The configuration
- :rtype: dictionary
- :returns: The generated config
- """
- config = deepcopy(spec)
-
- if vlan_info == "Name" and "VLAN Name" not in conf:
- conf = list(filter(None, conf.split(" ")))
- config["vlan_id"] = int(conf[0])
- config["name"] = conf[1]
- state_idx = 2
- for i in range(2, len(conf)): # check for index where state starts
- if conf[i] in ["suspended", "active"]:
- state_idx = i
- break
- elif conf[i].split("/")[0] in ["sus", "act"]:
- state_idx = i
- break
- config["name"] += " " + conf[i]
- try:
- if len(conf[state_idx].split("/")) > 1:
- _state = conf[state_idx].split("/")[0]
- if _state == "sus":
- config["state"] = "suspend"
- elif _state == "act":
- config["state"] = "active"
- config["shutdown"] = "enabled"
- else:
- if conf[state_idx] == "suspended":
- config["state"] = "suspend"
- elif conf[state_idx] == "active":
- config["state"] = "active"
- config["shutdown"] = "disabled"
- except IndexError:
- pass
- elif vlan_info == "Type" and "VLAN Type" not in conf:
- conf = list(filter(None, conf.split(" ")))
- config["mtu"] = int(conf[3])
- elif vlan_info == "Remote":
- if len(conf.split(",")) > 1 or conf.isdigit():
- remote_span_vlan = []
- if len(conf.split(",")) > 1:
- remote_span_vlan = conf.split(",")
- else:
- remote_span_vlan.append(conf)
- remote_span = []
- for each in remote_span_vlan:
- split_sp_list = each.split("-")
- if len(split_sp_list) > 1: # break range
- for r_sp in range(int(split_sp_list[0]), int(split_sp_list[1]) + 1):
- remote_span.append(r_sp)
- else:
- remote_span.append(int(each))
- config["remote_span"] = remote_span
-
- elif vlan_info == "Private" and "Primary Secondary" not in conf:
- conf = list(filter(None, conf.split(" ")))
-
- pri_idx = 0
- sec_idx = 1
- priv_type_idx = 2
-
- config["tmp_pvlans"] = {
- "primary": conf[pri_idx],
- "secondary": conf[sec_idx],
- "sec_type": conf[priv_type_idx],
- }
-
- return utils.remove_empties(config)
+ return objs
+ else:
+ return {}
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/__init__.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/__init__.py
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/vxlan_vtep.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/vxlan_vtep.py
new file mode 100644
index 000000000..0027504e4
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/facts/vxlan_vtep/vxlan_vtep.py
@@ -0,0 +1,67 @@
+# -*- 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 ios vxlan_vtep 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.ios.plugins.module_utils.network.ios.argspec.vxlan_vtep.vxlan_vtep import (
+ Vxlan_vtepArgs,
+)
+from ansible_collections.cisco.ios.plugins.module_utils.network.ios.rm_templates.vxlan_vtep import (
+ Vxlan_vtepTemplate,
+)
+
+
+class Vxlan_vtepFacts(object):
+ """The ios vxlan_vtep facts class"""
+
+ def __init__(self, module):
+ self._module = module
+ self.argument_spec = Vxlan_vtepArgs.argument_spec
+
+ def get_vxlan_vtep_data(self, connection):
+ return connection.get("show running-config | section ^interface nve")
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Vxlan_vtep 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_vxlan_vtep_data(connection)
+
+ # parse native config using the Vxlan_vtep template
+ vxlan_vtep_parser = Vxlan_vtepTemplate(lines=data.splitlines(), module=self._module)
+ objs = list(vxlan_vtep_parser.parse().values())
+
+ ansible_facts["ansible_network_resources"].pop("vxlan_vtep", None)
+
+ params = utils.remove_empties(
+ vxlan_vtep_parser.validate_config(self.argument_spec, {"config": objs}, redact=True),
+ )
+
+ facts["vxlan_vtep"] = params.get("config", {})
+ ansible_facts["ansible_network_resources"].update(facts)
+
+ return ansible_facts
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/acls.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/acls.py
index 164c93caf..b3afd65f9 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/acls.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/acls.py
@@ -16,11 +16,21 @@ the given network resource.
"""
import re
+from ansible.module_utils._text import to_text
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
+def remarks_with_sequence(remarks_data):
+ cmd = "remark "
+ if remarks_data.get("remarks"):
+ cmd += remarks_data.get("remarks")
+ if remarks_data.get("sequence"):
+ cmd = to_text(remarks_data.get("sequence")) + " " + cmd
+ return cmd
+
+
def _tmplt_access_list_entries(aces):
def source_destination_common_config(config_data, command, attr):
if config_data[attr].get("address"):
@@ -63,7 +73,9 @@ def _tmplt_access_list_entries(aces):
command += " {protocol_number}".format(**aces["protocol_options"])
else:
command += " {0}".format(list(aces["protocol_options"])[0])
- proto_option = aces["protocol_options"].get(list(aces["protocol_options"])[0])
+ proto_option = aces["protocol_options"].get(
+ list(aces["protocol_options"])[0],
+ )
elif aces.get("protocol"):
command += " {protocol}".format(**aces)
if aces.get("source"):
@@ -120,7 +132,7 @@ class AclsTemplate(NetworkTemplate):
PARSERS = [
{
- "name": "acls_name",
+ "name": "only_acls_name",
"getval": re.compile(
r"""^(?P<acl_type>Standard|Extended|Reflexive)*
\s*(?P<afi>IP|IPv6)*
@@ -130,8 +142,7 @@ class AclsTemplate(NetworkTemplate):
$""",
re.VERBOSE,
),
- "compval": "name",
- "setval": "name",
+ "setval": "",
"result": {
"acls": {
"{{ acl_name|d() }}": {
@@ -141,80 +152,95 @@ class AclsTemplate(NetworkTemplate):
},
},
},
- "shared": True,
},
{
- "name": "_acls_name",
+ "name": "acls_name",
"getval": re.compile(
- r"""^(ip|ipv6)
+ r"""^(?P<afi>ip|ipv6|mac)
(\s(access-list))
- (\s(standard|extended))
- (\s(?P<acl_name_r>\S+))?
+ (\s(?P<acl_type>standard|extended|reflexive))?
+ (\s(?P<acl_name>\S+))
$""",
re.VERBOSE,
),
- "compval": "name",
- "setval": "ip access-list",
- "result": {},
+ "setval": "name",
+ "result": {
+ "acls": {
+ "{{ acl_name|d() }}": {
+ "name": "{{ acl_name }}",
+ "acl_type": "{{ acl_type.lower() if acl_type is defined }}",
+ "afi": "{{ 'ipv4' if afi == 'ip' else 'ipv6' }}",
+ },
+ },
+ },
"shared": True,
},
{
- "name": "_mac_acls_name", #
+ "name": "remarks",
"getval": re.compile(
- r"""^(?P<acl_type>Standard|Extended|Reflexive)*
- \s*(?P<afi>MAC)*
- \s*access
- \s*list*
- \s*(?P<acl_name>.+)*
+ r"""((?P<order>^\d+))
+ (\s*(?P<sequence>\d+))
+ (\sremark\s(?P<remarks>.+))
$""",
re.VERBOSE,
),
- "compval": "name",
- "setval": "",
+ "setval": remarks_with_sequence,
"result": {
"acls": {
"{{ acl_name|d() }}": {
"name": "{{ acl_name }}",
- "acl_type": "{{ acl_type.lower() if acl_type is defined }}",
- "afi": "{{ afi }}",
+ "aces": [
+ {
+ "the_remark": "{{ remarks }}",
+ "order": "{{ order }}",
+ "is_remark_for": "{{ sequence }}",
+ },
+ ],
},
},
},
- "shared": True,
},
{
- "name": "remarks",
+ "name": "remarks_no_data",
"getval": re.compile(
- r"""\s+remark
- (\s(?P<remarks>.+))?
- $""",
+ r"""(?P<order>^\d+)\s*remark\s(?P<remarks>.+)$""",
re.VERBOSE,
),
- "setval": "remark {{ remarks }}",
+ "setval": "{{ sequence }} remark",
"result": {
"acls": {
- "{{ acl_name_r|d() }}": {
- "name": "{{ acl_name_r }}",
- "aces": [{"remarks": "{{ remarks }}"}],
+ "{{ acl_name|d() }}": {
+ "name": "{{ acl_name }}",
+ "aces": [
+ {
+ "the_remark": "{{ remarks }}",
+ "order": "{{ order }}",
+ "is_remark_for": "remark",
+ },
+ ],
},
},
},
},
{
- "name": "remarks_type_linear",
+ "name": "remarks_ipv6",
"getval": re.compile(
- r"""^(access-list)
- (\s(?P<acl_name_linear>\S+))?
- (\sremark\s(?P<remarks>.+))?
+ r"""\s*(sequence\s(?P<sequence>\d+))
+ (\sremark\s(?P<remarks>.+))
$""",
re.VERBOSE,
),
"setval": "remark {{ remarks }}",
"result": {
"acls": {
- "{{ acl_name_linear|d() }}": {
- "name": "{{ acl_name_linear }}",
- "aces": [{"remarks": "{{ remarks }}"}],
+ "{{ acl_name|d() }}": {
+ "name": "{{ acl_name }}",
+ "aces": [
+ {
+ "sequence": "{{ sequence }}",
+ "remarks": ["{{ remarks }}"],
+ },
+ ],
},
},
},
@@ -222,12 +248,11 @@ class AclsTemplate(NetworkTemplate):
{
"name": "aces_ipv4_standard",
"getval": re.compile(
- r"""\s*(?P<sequence>\d+)*
- \s(?P<grant>deny|permit)?
- (\s+(?P<address>(?!ahp|eigrp|esp|gre|icmp|igmp|ipv6|ipinip|ip|nos|object-group|ospf|pcp|pim|sctp|tcp|udp)\S+|\S+,))?
+ r"""(\s*(?P<sequence>\d+))?
+ (\s(?P<grant>deny|permit))
+ (\s+(?P<address>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))?
+ (\s(?P<wildcard>((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)))?
(\s*(?P<any>any))?
- (\swildcard\sbits\s(?P<wildcard>\S+))?
- (\shost\s(?P<host>\S+))?
(\s(?P<log>log))?
$""",
re.VERBOSE,
@@ -245,7 +270,6 @@ class AclsTemplate(NetworkTemplate):
"address": "{{ address }}",
"wildcard_bits": "{{ wildcard }}",
"any": "{{ not not any }}",
- "host": "{{ host }}",
},
"log": {"set": "{{ not not log }}"},
},
@@ -257,28 +281,39 @@ class AclsTemplate(NetworkTemplate):
{
"name": "aces",
"getval": re.compile(
- r"""\s*((?P<sequence>\d+))?
+ r"""(\s*(?P<sequence>\d+))?
+ (\s*sequence\s(?P<sequence_ipv6>\d+))?
(\s*(?P<grant>deny|permit))
(\sevaluate\s(?P<evaluate>\S+))?
(\s(?P<protocol_num>\d+))?
- (\s(?P<protocol>ahp|eigrp|esp|gre|icmp|igmp|ipv6|ipinip|ip|nos|ospf|pcp|pim|sctp|tcp|udp))?
+ (\s*(?P<protocol>ahp|eigrp|esp|gre|icmp|igmp|ipinip|ipv6|ip|nos|ospf|pcp|pim|sctp|tcp|ip|udp))?
((\s(?P<source_any>any))|
(\sobject-group\s(?P<source_obj_grp>\S+))|
(\shost\s(?P<source_host>\S+))|
+ (\s(?P<ipv6_source_address>\S+/\d+))|
(\s(?P<source_address>(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s\S+)))?
- (\s(?P<source_port_protocol>(eq|gts|gt|lt|neq)\s(\S+|\d+)))?
+ (\seq\s(?P<seq>(\S+|\d+)))?
+ (\sgt\s(?P<sgt>(\S+|\d+)))?
+ (\slt\s(?P<slt>(\S+|\d+)))?
+ (\sneq\s(?P<sneq>(\S+|\d+)))?
(\srange\s(?P<srange_start>\d+)\s(?P<srange_end>\d+))?
(\s(?P<dest_any>any))?
(\sobject-group\s(?P<dest_obj_grp>\S+))?
(\shost\s(?P<dest_host>\S+))?
+ (\s(?P<ipv6_dest_address>\S+/\d+))?
(\s(?P<dest_address>(\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3})\s\S+))?
- (\s(?P<dest_port_protocol>(eq|gts|lt|neq)\s(\S+|\d+)))?
+ (\seq\s(?P<deq>(\S+|\d+)))?
+ (\sgt\s(?P<dgt>(\S+|\d+)))?
+ (\slt\s(?P<dlt>(\S+|\d+)))?
+ (\sneq\s(?P<dneq>(\S+|\d+)))?
(\srange\s(?P<drange_start>\d+)\s(?P<drange_end>\d+))?
(\s(?P<icmp_igmp_tcp_protocol>administratively-prohibited|alternate-address|conversion-error|dod-host-prohibited|dod-net-prohibited|echo-reply|echo|general-parameter-problem|host-isolated|host-precedence-unreachable|host-redirect|host-tos-redirect|host-tos-unreachable|host-unknown|host-unreachable|information-reply|information-request|mask-reply|mask-request|mobile-redirect|net-redirect|net-tos-redirect|net-tos-unreachable|net-unreachable|network-unknown|no-room-for-option|option-missing|packet-too-big|parameter-problem|port-unreachable|precedence-unreachable|protocol-unreachable|reassembly-timeout|redirect|router-advertisement|router-solicitation|source-quench|source-route-failed|time-exceeded|timestamp-reply|timestamp-request|traceroute|ttl-exceeded|unreachable|dvmrp|host-query|mtrace-resp|mtrace-route|pim|trace|v1host-report|v2host-report|v2leave-group|v3host-report|ack|established|fin|psh|rst|syn|urg))?
(\sdscp\s(?P<dscp>\S+))?
(\s(?P<enable_fragments>fragments))?
- (\s(?P<log_input>log-input\s\(tag\s=\s\S+\)|log-input))?
- (\s(?P<log>log\s\(tag\s=\s\S+\)|log))?
+ (\slog-input\s\(tag\s=\s(?P<log_input>\S+\)|log-input))?
+ (\s(?P<log_input_only>log-input))?
+ (\slog\s\(tag\s=\s(?P<log>\S+\)|log))?
+ (\s(?P<log_only>log))?
(\soption\s(?P<option>\S+|\d+))?
(\sprecedence\s(?P<precedence>\S+))?
(\stime-range\s(?P<time_range>\S+))?
@@ -287,7 +322,6 @@ class AclsTemplate(NetworkTemplate):
(\sttl\sgt\s(?P<ttl_gt>\d+))?
(\sttl\slt\s(?P<ttl_lt>\d+))?
(\sttl\sneg\s(?P<ttl_neg>\d+))?
- (\ssequence\s(?P<sequence_ipv6>\d+))?
""",
re.VERBOSE,
),
@@ -308,12 +342,15 @@ class AclsTemplate(NetworkTemplate):
"icmp_igmp_tcp_protocol": "{{ icmp_igmp_tcp_protocol }}",
"source": {
"address": "{{ source_address }}",
+ "ipv6_address": "{{ ipv6_source_address }}",
"any": "{{ not not source_any }}",
"host": "{{ source_host }}",
"object_group": "{{ source_obj_grp }}",
"port_protocol": {
- "{{ source_port_protocol.split(' ')[0] if source_port_protocol is defined else None }}": "{{\
- source_port_protocol.split(' ')[1] if source_port_protocol is defined else None }}",
+ "eq": "{{ seq }}",
+ "gt": "{{ sgt }}",
+ "lt": "{{ slt }}",
+ "neq": "{{ sneq }}",
"range": {
"start": "{{ srange_start if srange_start is defined else None }}",
"end": "{{ srange_end if srange_end is defined else None }}",
@@ -322,12 +359,15 @@ class AclsTemplate(NetworkTemplate):
},
"destination": {
"address": "{{ dest_address }}",
+ "ipv6_address": "{{ ipv6_dest_address }}",
"any": "{{ not not dest_any }}",
"host": "{{ dest_host }}",
"object_group": "{{ dest_obj_grp }}",
"port_protocol": {
- "{{ dest_port_protocol.split(' ')[0] if dest_port_protocol is defined else None }}": "{{\
- dest_port_protocol.split(' ')[1] if dest_port_protocol is defined else None }}",
+ "eq": "{{ deq }}",
+ "gt": "{{ dgt }}",
+ "lt": "{{ dlt }}",
+ "neq": "{{ dneq }}",
"range": {
"start": "{{ drange_start if drange_start is defined else None }}",
"end": "{{ drange_end if drange_end is defined else None }}",
@@ -337,12 +377,12 @@ class AclsTemplate(NetworkTemplate):
"dscp": "{{ dscp }}",
"enable_fragments": "{{ True if enable_fragments is defined else None }}",
"log": {
- "set": "{{ True if log is defined and 'tag' not in log else '' }}",
- "user_cookie": "{{ log.split(' ')[-1].split(')')[0] if log is defined and 'tag' in log else '' }}",
+ "set": "{{ True if log_only is defined or log is defined }}",
+ "user_cookie": "{{ log.split(')')[0] if log is defined }}",
},
"log_input": {
- "set": "{{ True if log_input is defined and 'tag' not in log_input else '' }}",
- "user_cookie": "{{ log_input.split(' ')[-1].split(')')[0] if log_input is defined and 'tag' in log_input }}",
+ "set": "{{ True if log_input_only is defined or log_input is defined }}",
+ "user_cookie": "{{ log_input.split(')')[0] if log_input is defined }}",
},
"option": {
"{{ option if option is defined else None }}": "{{ True if option is defined else None }}",
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_address_family.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_address_family.py
index b9654956c..ca85440b2 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_address_family.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_address_family.py
@@ -1145,7 +1145,7 @@ class Bgp_address_familyTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "neighbor {{ neighbor_address }} filter-list"
- "{{ (' ' + filter_list.as_path_acl) if filter_list.as_path_acl is defined else '' }}"
+ "{{ (' ' + filter_list.as_path_acl|string) if filter_list.as_path_acl is defined else '' }}"
"{{ (' in') if filter_list.in|d(False) else '' }}"
"{{ (' out') if filter_list.out|d(False) else '' }}",
"result": {
@@ -1251,12 +1251,12 @@ class Bgp_address_familyTemplate(NetworkTemplate):
"name": "inherit",
"getval": re.compile(
r"""
- \s\sneighbor\s(?P<neighbor_address>\S+)\sinherit\speer-session
+ \s\sneighbor\s(?P<neighbor_address>\S+)\sinherit\speer-policy
\s(?P<inherit>\S+)
$""",
re.VERBOSE,
),
- "setval": "neighbor {{ neighbor_address }} inherit peer-session"
+ "setval": "neighbor {{ neighbor_address }} inherit peer-policy"
"{{ (' ' + inherit) if inherit is defined else '' }}",
"result": {
"address_family": {
@@ -2670,4 +2670,26 @@ class Bgp_address_familyTemplate(NetworkTemplate):
},
},
# redistribute ends
+ {
+ "name": "advertise",
+ "getval": re.compile(
+ r"""
+ \s\sadvertise\s(?P<ad_afi>l2vpn)
+ (\s(?P<ad_safi>evpn))?
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "advertise {{ advertise.afi }}"
+ "{{ (' ' + advertise.safi ) if advertise.safi is defined else '' }}",
+ "result": {
+ "address_family": {
+ UNIQUE_AFI: {
+ "advertise": {
+ "afi": "{{ ad_afi }}",
+ "safi": "{{ ad_safi }}",
+ },
+ },
+ },
+ },
+ },
]
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_global.py
index 477cbc679..39fd548bc 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_global.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/bgp_global.py
@@ -160,7 +160,9 @@ class Bgp_globalTemplate(NetworkTemplate):
"{{ bmp.server_options.address.host }} port-number {{ bmp.server_options.address.port|string }}\nexit-bmp-server-mode",
"result": {
"bmp": {
- "server_options": {"address": {"host": "{{ host }}", "port": "{{ port }}"}},
+ "server_options": {
+ "address": {"host": "{{ host }}", "port": "{{ port }}"},
+ },
},
},
},
@@ -449,7 +451,10 @@ class Bgp_globalTemplate(NetworkTemplate):
},
{
"name": "synchronization",
- "getval": re.compile(r"""\s(?P<synchronization>synchronization)""", re.VERBOSE),
+ "getval": re.compile(
+ r"""\s(?P<synchronization>synchronization)""",
+ re.VERBOSE,
+ ),
"setval": "synchronization",
"result": {"synchronization": "{{ not not synchronization }}"},
},
@@ -466,7 +471,9 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "table-map"
"{{ (' ' + name) if name is defined else '' }}"
"{{ (' filter' ) if filter|d(False) else '' }}",
- "result": {"table_map": {"name": "{{ name }}", "filter": "{{ not not filter }}"}},
+ "result": {
+ "table_map": {"name": "{{ name }}", "filter": "{{ not not filter }}"},
+ },
},
{
"name": "timers",
@@ -558,19 +565,28 @@ class Bgp_globalTemplate(NetworkTemplate):
},
{
"name": "bgp.bestpath_options.compare_routerid",
- "getval": re.compile(r"""\s(bgp\sbestpath\scompare-routerid)""", re.VERBOSE),
+ "getval": re.compile(
+ r"""\s(bgp\sbestpath\scompare-routerid)""",
+ re.VERBOSE,
+ ),
"setval": "{{ ('bgp bestpath compare-routerid' ) if bgp.bestpath_options.compare_routerid|d(False) else '' }}",
"result": {"bgp": {"bestpath_options": {"compare_routerid": True}}},
},
{
"name": "bgp.bestpath_options.cost_community",
- "getval": re.compile(r"""\s(bgp\sbestpath\scost-community\signore)""", re.VERBOSE),
+ "getval": re.compile(
+ r"""\s(bgp\sbestpath\scost-community\signore)""",
+ re.VERBOSE,
+ ),
"setval": "{{ ('bgp bestpath cost-community ignore' ) if bgp.bestpath_options.cost_community|d(False) else '' }}",
"result": {"bgp": {"bestpath_options": {"cost_community": True}}},
},
{
"name": "bgp.bestpath_options.igp_metric",
- "getval": re.compile(r"""\s(bgp\sbestpath\sigp-metric\signore)""", re.VERBOSE),
+ "getval": re.compile(
+ r"""\s(bgp\sbestpath\sigp-metric\signore)""",
+ re.VERBOSE,
+ ),
"setval": "bgp bestpath igp-metric ignore",
"result": {"bgp": {"bestpath_options": {"igp_metric": True}}},
},
@@ -790,7 +806,9 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "bgp graceful-restart restart-time {{ bgp.graceful_restart.restart_time|string }}",
- "result": {"bgp": {"graceful_restart": {"restart_time": "{{ restart_time }}"}}},
+ "result": {
+ "bgp": {"graceful_restart": {"restart_time": "{{ restart_time }}"}},
+ },
},
{
"name": "bgp.graceful_restart.stalepath_time",
@@ -802,7 +820,9 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "bgp graceful-restart stalepath-time {{ bgp.graceful_restart.stalepath_time|string }}",
- "result": {"bgp": {"graceful_restart": {"stalepath_time": "{{ stalepath_time }}"}}},
+ "result": {
+ "bgp": {"graceful_restart": {"stalepath_time": "{{ stalepath_time }}"}},
+ },
},
{
"name": "bgp.graceful_shutdown.neighbors",
@@ -824,7 +844,10 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"bgp": {
"graceful_shutdown": {
- "neighbors": {"time": "{{ time }}", "activate": "{{ not not activate }}"},
+ "neighbors": {
+ "time": "{{ time }}",
+ "activate": "{{ not not activate }}",
+ },
"community": "{{ community }}",
"local_preference": "{{ local_preference }}",
},
@@ -851,7 +874,10 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"bgp": {
"graceful_shutdown": {
- "vrfs": {"time": "{{ time }}", "activate": "{{ not not activate }}"},
+ "vrfs": {
+ "time": "{{ time }}",
+ "activate": "{{ not not activate }}",
+ },
"community": "{{ community }}",
"local_preference": "{{ local_preference }}",
},
@@ -1008,7 +1034,9 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "bgp nopeerup-delay cold-boot {{ bgp.nopeerup_delay_options.cold_boot|string }}",
- "result": {"bgp": {"nopeerup_delay_options": {"cold_boot": "{{ cold_boot }}"}}},
+ "result": {
+ "bgp": {"nopeerup_delay_options": {"cold_boot": "{{ cold_boot }}"}},
+ },
},
{
"name": "bgp.nopeerup_delay_options.post_boot",
@@ -1020,7 +1048,9 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "bgp nopeerup-delay post-boot {{ bgp.nopeerup_delay_options.post_boot|string }}",
- "result": {"bgp": {"nopeerup_delay_options": {"post_boot": "{{ post_boot }}"}}},
+ "result": {
+ "bgp": {"nopeerup_delay_options": {"post_boot": "{{ post_boot }}"}},
+ },
},
{
"name": "bgp.nopeerup_delay_options.nsf_switchover",
@@ -1033,7 +1063,9 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "bgp nopeerup-delay nsf-switchover {{ bgp.nopeerup_delay_options.nsf_switchover|string }}",
"result": {
- "bgp": {"nopeerup_delay_options": {"nsf_switchover": "{{ nsf_switchover }}"}},
+ "bgp": {
+ "nopeerup_delay_options": {"nsf_switchover": "{{ nsf_switchover }}"},
+ },
},
},
{
@@ -1047,7 +1079,9 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "bgp nopeerup-delay user-initiated {{ bgp.nopeerup_delay_options.user_initiated|string }}",
"result": {
- "bgp": {"nopeerup_delay_options": {"user_initiated": "{{ user_initiated }}"}},
+ "bgp": {
+ "nopeerup_delay_options": {"user_initiated": "{{ user_initiated }}"},
+ },
},
},
{
@@ -1165,7 +1199,9 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "bgp slow-peer detection threshold {{ bgp.slow_peer.detection.threshold|string }}",
- "result": {"bgp": {"slow_peer": {"detection": {"threshold": "{{ threshold }}"}}}},
+ "result": {
+ "bgp": {"slow_peer": {"detection": {"threshold": "{{ threshold }}"}}},
+ },
},
{
"name": "bgp.slow_peer.split_update_group",
@@ -1356,7 +1392,10 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }} bmp-activate",
"result": {
"neighbors": {
- "{{ neighbor_address }}": {"bmp_activate": "{{ not not bmp_activate }}"},
+ "{{ neighbor_address }}": {
+ "bmp_activate": "{{ not not bmp_activate }}",
+ "neighbor_address": "{{ neighbor_address }}",
+ },
},
},
},
@@ -1371,7 +1410,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }} cluster-id",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"cluster_id": "{{ not not cluster_id }}"}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "cluster_id": "{{ not not cluster_id }}",
+ "neighbor_address": "{{ neighbor_address }}",
+ },
+ },
},
},
{
@@ -1408,6 +1452,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"neighbors": {
"{{ neighbor_address }}": {
"disable_connected_check": "{{ not not disable_connected_check }}",
+ "neighbor_address": "{{ neighbor_address }}",
},
},
},
@@ -1431,6 +1476,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"enable": "{{ not not enable }}",
"hop_count": "{{ hop_count }}",
},
+ "neighbor_address": "{{ neighbor_address }}",
},
},
},
@@ -1460,6 +1506,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"single_hop": "{{ not not single_hop }}",
},
},
+ "neighbor_address": "{{ neighbor_address }}",
},
},
},
@@ -1477,7 +1524,10 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
- "fall_over": {"route_map": "{{ not not route_map }}"},
+ "fall_over": {
+ "route_map": "{{ not not route_map }}",
+ "neighbor_address": "{{ neighbor_address }}",
+ },
},
},
},
@@ -1498,7 +1548,11 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
- "ha_mode": {"set": "{{ not not set }}", "disable": "{{ not not disable }}"},
+ "ha_mode": {
+ "set": "{{ not not set }}",
+ "disable": "{{ not not disable }}",
+ },
+ "neighbor_address": "{{ neighbor_address }}",
},
},
},
@@ -1514,7 +1568,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }} inherit peer-session"
"{{ (' ' + inherit) if inherit is defined else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"inherit": "{{ inherit }}"}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "inherit": "{{ inherit }}",
+ "neighbor_address": "{{ neighbor_address }}",
+ },
+ },
+ },
},
{
"name": "local_as",
@@ -1536,6 +1597,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"local_as": {
"set": "{{ not not local_as }}",
"number": "{{ number }}",
@@ -1618,6 +1680,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"path_attribute": {
"discard": {
"type": "{{ type }}",
@@ -1648,6 +1711,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"path_attribute": {
"treat_as_withdraw": {
"type": "{{ type }}",
@@ -1678,6 +1742,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"shutdown": {
"set": True,
"graceful": "{{ graceful }}",
@@ -1698,7 +1763,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }}"
"{{ (' soft-reconfiguration inbound') if soft_reconfiguration|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"soft_reconfiguration": True}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "soft_reconfiguration": True,
+ },
+ },
+ },
},
{
"name": "ntimers",
@@ -1718,6 +1790,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"timers": {
"interval": "{{ interval }}",
"holdtime": "{{ holdtime }}",
@@ -1743,6 +1816,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"transport": {
"connection_mode": {
"active": "{{ not not active }}",
@@ -1786,8 +1860,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"transport": {
- "path_mtu_discovery": {"set": True, "disable": "{{ not not disable }}"},
+ "path_mtu_discovery": {
+ "set": True,
+ "disable": "{{ not not disable }}",
+ },
},
},
},
@@ -1805,7 +1883,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }} ttl-security"
"{{ (' hops '+ ttl_security|string) if ttl_security is defined else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"ttl_security": "{{ ttl_security }}"}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "ttl_security": "{{ ttl_security }}",
+ },
+ },
},
},
{
@@ -1820,7 +1903,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }} unsuppress-map"
"{{ (' ' + unsuppress_map) if unsuppress_map is defined else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"unsuppress_map": "{{ unsuppress_map }}"}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "unsuppress_map": "{{ unsuppress_map }}",
+ },
+ },
},
},
{
@@ -1874,7 +1962,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }} weight"
"{{ (' ' + weight|string) if weight is defined else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"weight": "{{ weight }}"}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "weight": "{{ weight }}",
+ },
+ },
+ },
},
# neighbor remote-as ends
# neighbor peer-group starts
@@ -1915,6 +2010,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"additional_paths": {
"disable": "{{ not not disable }}",
"receive": "{{ not not receive }}",
@@ -1942,6 +2038,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"advertise": {
"additional_paths": {
"all": "{{ not not all }}",
@@ -1964,7 +2061,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }}"
"{{ (' advertise best-external') if advertise.best_external|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"advertise": {"best-external": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "advertise": {"best-external": True},
+ },
+ },
},
},
{
@@ -1983,6 +2085,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"advertise": {
"diverse_path": {
"backup": "{{ not not backup }}",
@@ -2011,6 +2114,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"advertise_map": {
"name": "{{ name }}",
"exist_map": "{{ exist_map }}",
@@ -2034,6 +2138,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"advertisement_interval": "{{ advertisement_interval }}",
},
},
@@ -2048,7 +2153,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' aigp') if aigp.enable|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"aigp": {"enable": True}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "aigp": {"enable": True},
+ },
+ },
+ },
},
{
"name": "aigp.send.cost_community",
@@ -2070,6 +2182,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"aigp": {
"send": {
"cost_community": {
@@ -2096,7 +2209,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }}"
"{{ (' aigp send med') if aigp.send.med|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"aigp": {"send": {"med": True}}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "aigp": {"send": {"med": True}},
+ },
+ },
+ },
},
{
"name": "allow_policy",
@@ -2107,7 +2227,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' allow-policy') if allow_policy|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"allow_policy": True}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "allow_policy": True,
+ },
+ },
+ },
},
{
"name": "allowas_in",
@@ -2120,7 +2247,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }}"
"{{ (' allowas-in ' + allowas_in|string) if allowas_in is defined else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"allowas_in": "{{ allowas_in }}"}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "allowas_in": "{{ allowas_in }}",
+ },
+ },
+ },
},
{
"name": "as_override",
@@ -2132,7 +2266,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }}"
"{{ (' as-override') if as_override|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"as_override": True}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "as_override": True,
+ },
+ },
+ },
},
{
"name": "bmp_activate",
@@ -2151,7 +2292,10 @@ class Bgp_globalTemplate(NetworkTemplate):
"neighbors": {
"{{ neighbor_address }}": {
"neighbor_address": "{{ neighbor_address }}",
- "bmp_activate": {"server": "{{ server }}", "all": "{{ not not all }}"},
+ "bmp_activate": {
+ "server": "{{ server }}",
+ "all": "{{ not not all }}",
+ },
},
},
},
@@ -2174,6 +2318,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"capability": {
"both": "{{ not not both }}",
"receive": "{{ not not receive }}",
@@ -2193,7 +2338,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' default-originate') if default_originate.set|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"default_originate": {"set": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "default_originate": {"set": True},
+ },
+ },
},
},
{
@@ -2210,6 +2360,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"default-originate": {"route_map": "{{ route_map }}"},
},
},
@@ -2233,6 +2384,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"distribute_list": {
"acl": "{{ acl }}",
"in": "{{ not not in }}",
@@ -2251,7 +2403,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' dmzlink-bw') if dmzlink_bw|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"dmzlink_bw": True}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "dmzlink_bw": True,
+ },
+ },
+ },
},
{
"name": "filter_list",
@@ -2271,6 +2430,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"filter_list": {
"path_acl": "{{ acl }}",
"in": "{{ not not in }}",
@@ -2300,6 +2460,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"maximum_prefix": {
"max_no": "{{ max_no }}",
"threshold_val": "{{ threshold_val }}",
@@ -2319,7 +2480,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' next-hop-self') if next_hop_self.set|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"next_hop_self": {"set": True}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "next_hop_self": {"set": True},
+ },
+ },
+ },
},
{
"name": "next_hop_self.all",
@@ -2330,7 +2498,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' next-hop-self all') if next_hop_self.all|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"next_hop_self": {"all": True}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "next_hop_self": {"all": True},
+ },
+ },
+ },
},
{
"name": "next_hop_unchanged.set",
@@ -2342,7 +2517,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' next-hop-unchanged') if next_hop_unchanged.set|d(False) else ''}}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"next_hop_unchanged": {"set": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "next_hop_unchanged": {"set": True},
+ },
+ },
},
},
{
@@ -2355,7 +2535,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' next-hop-unchanged allpaths') if next_hop_unchanged.allpaths|d(False) else ''}}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"next_hop_unchanged": {"allpaths": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "next_hop_unchanged": {"allpaths": True},
+ },
+ },
},
},
{
@@ -2368,7 +2553,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' remove-private-as') if remove_private_as.set|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"remove_private_as": {"set": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "remove_private_as": {"set": True},
+ },
+ },
},
},
{
@@ -2381,7 +2571,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' remove-private-as all') if remove_private_as.all|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"remove_private_as": {"all": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "remove_private_as": {"all": True},
+ },
+ },
},
},
{
@@ -2395,7 +2590,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "{{ ('neighbor ' + neighbor_address + ' remove-private-as replace-as') if remove_private_as.replace_as|d(False) else ''}}",
"result": {
"neighbors": {
- "{{ neighbor_address }}": {"remove_private_as": {"replace_as": True}},
+ "{{ neighbor_address }}": {
+ "remove_private_as": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "replace_as": True,
+ },
+ },
},
},
},
@@ -2456,7 +2656,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' route-server-client') if route_server_client.set|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"route_server_client": {"set": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "route_server_client": {"set": True},
+ },
+ },
},
},
{
@@ -2472,7 +2677,10 @@ class Bgp_globalTemplate(NetworkTemplate):
"{{ (' context ' + route_server_client.context) if route_server_client.context is defined else '' }}",
"result": {
"neighbors": {
- "{{ neighbor_address }}": {"route_server_client": {"context": "{{ context }}"}},
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "route_server_client": {"context": "{{ context }}"},
+ },
},
},
},
@@ -2485,7 +2693,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' send-community') if send_community.set|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"send_community": {"set": True}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "send_community": {"set": True},
+ },
+ },
+ },
},
{
"name": "send_community.both",
@@ -2497,7 +2712,14 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "neighbor {{ neighbor_address }} send-community"
"{{ (' both') if send_community.both|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"send_community": {"both": True}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "send_community": {"both": True},
+ },
+ },
+ },
},
{
"name": "send_community.extended",
@@ -2510,7 +2732,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }} send-community"
"{{ (' extended') if send_community.extended|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"send_community": {"extended": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "send_community": {"extended": True},
+ },
+ },
},
},
{
@@ -2524,7 +2751,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }} send-community"
"{{ (' standard') if send_community.standard|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"send_community": {"standard": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "send_community": {"standard": True},
+ },
+ },
},
},
{
@@ -2536,7 +2768,14 @@ class Bgp_globalTemplate(NetworkTemplate):
re.VERBOSE,
),
"setval": "{{ ('neighbor ' + neighbor_address + ' send-label') if send_label.set|d(False) else '' }}",
- "result": {"neighbors": {"{{ neighbor_address }}": {"send_label": {"set": True}}}},
+ "result": {
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "send_label": {"set": True},
+ },
+ },
+ },
},
{
"name": "send_label.explicit_null",
@@ -2549,7 +2788,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"setval": "neighbor {{ neighbor_address }} send-label"
"{{ (' explicit-null') if send_label.explicit_null|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"send_label": {"explicit_null": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "send_label": {"explicit_null": True},
+ },
+ },
},
},
{
@@ -2570,6 +2814,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"slow_peer": {
"detection": {
"enable": "{{ not not enable }}",
@@ -2601,6 +2846,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"slow_peer": {
"split_update_group": {
"static": "{{ not not static }}",
@@ -2625,7 +2871,12 @@ class Bgp_globalTemplate(NetworkTemplate):
),
"setval": "{{ ('neighbor ' + neighbor_address + ' translate_update') if translate_update.set|d(False) else '' }}",
"result": {
- "neighbors": {"{{ neighbor_address }}": {"translate_update": {"set": True}}},
+ "neighbors": {
+ "{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
+ "translate_update": {"set": True},
+ },
+ },
},
},
{
@@ -2644,6 +2895,7 @@ class Bgp_globalTemplate(NetworkTemplate):
"result": {
"neighbors": {
"{{ neighbor_address }}": {
+ "neighbor_address": "{{ neighbor_address }}",
"translate_update": {
"nlri": {
"multicast": "{{ not not multicast }}",
@@ -2806,7 +3058,12 @@ class Bgp_globalTemplate(NetworkTemplate):
"remval": "redistribute iso-igrp {{ iso_igrp.area_tag }}",
"result": {
"redistribute": [
- {"iso_igrp": {"area_tag": "{{ name }}", "route_map": "{{ route_map }}"}},
+ {
+ "iso_igrp": {
+ "area_tag": "{{ name }}",
+ "route_map": "{{ route_map }}",
+ },
+ },
],
},
},
@@ -3049,7 +3306,9 @@ class Bgp_globalTemplate(NetworkTemplate):
"{{ (' global') if vrf.global|d(False) else '' }}",
"remval": "redistribute vrf {{ vrf.name }}",
"result": {
- "redistribute": [{"vrf": {"name": "{{ name }}", "global": "{{ not not global }}"}}],
+ "redistribute": [
+ {"vrf": {"name": "{{ name }}", "global": "{{ not not global }}"}},
+ ],
},
},
# redistribute ends
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_evi.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_evi.py
new file mode 100644
index 000000000..e58445ba3
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_evi.py
@@ -0,0 +1,121 @@
+# -*- 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 Evpn_evi parser templates file. This contains
+a list of parser definitions and associated functions that
+facilitates both facts gathering and native command generation for
+the given network resource.
+"""
+
+import re
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
+ NetworkTemplate,
+)
+
+
+class Evpn_eviTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ super(Evpn_eviTemplate, self).__init__(lines=lines, tmplt=self, module=module)
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "evi",
+ "getval": re.compile(
+ r"""^l2vpn\sevpn\sinstance\s
+ (?P<evi>\d+)\svlan-based
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "l2vpn evpn instance {{ evi }} vlan-based",
+ "result": {"{{ evi }}": {"evi": "{{ evi }}"}},
+ "shared": True,
+ },
+ {
+ "name": "default_gateway.advertise.enable",
+ "getval": re.compile(
+ r"""
+ \s+default-gateway\sadvertise\senable
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "default-gateway advertise enable",
+ "result": {"{{ evi }}": {"default_gateway": {"advertise": {"enable": True}}}},
+ },
+ {
+ "name": "default_gateway.advertise.disable",
+ "getval": re.compile(
+ r"""
+ \s+default-gateway\sadvertise\sdisable
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "default-gateway advertise disable",
+ "result": {"{{ evi }}": {"default_gateway": {"advertise": {"disable": True}}}},
+ },
+ {
+ "name": "encapsulation",
+ "getval": re.compile(
+ r"""
+ \s+encapsulation\s(?P<encapsulation>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "encapsulation {{encapsulation}}",
+ "result": {"{{ evi }}": {"encapsulation": "{{ encapsulation }}"}},
+ },
+ {
+ "name": "ip.local_learning.enable",
+ "getval": re.compile(
+ r"""
+ \s+ip\slocal-learning\senable
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "ip local-learning enable",
+ "result": {"{{ evi }}": {"ip": {"local_learning": {"enable": True}}}},
+ },
+ {
+ "name": "ip.local_learning.disable",
+ "getval": re.compile(
+ r"""
+ \s+ip\slocal-learning\sdisable
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "ip local-learning disable",
+ "result": {"{{ evi }}": {"ip": {"local_learning": {"disable": True}}}},
+ },
+ {
+ "name": "replication_type",
+ "getval": re.compile(
+ r"""
+ \s+replication-type\s(?P<replication_type>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "replication-type {{ replication_type }}",
+ "result": {"{{ evi }}": {"replication_type": "{{ replication_type }}"}},
+ },
+ {
+ "name": "route_distinguisher",
+ "getval": re.compile(
+ r"""
+ \s+rd\s(?P<route_distinguisher>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "rd {{ route_distinguisher }}",
+ "result": {"{{ evi }}": {"route_distinguisher": "{{ route_distinguisher }}"}},
+ },
+ ]
+ # fmt: on
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_global.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_global.py
new file mode 100644
index 000000000..2dfae2a11
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/evpn_global.py
@@ -0,0 +1,115 @@
+# -*- 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 Evpn_global parser templates file. This contains
+a list of parser definitions and associated functions that
+facilitates both facts gathering and native command generation for
+the given network resource.
+"""
+
+import re
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
+ NetworkTemplate,
+)
+
+
+class Evpn_globalTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ super(Evpn_globalTemplate, self).__init__(lines=lines, tmplt=self, module=module)
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "default_gateway.advertise",
+ "getval": re.compile(
+ r"""
+ \sdefault-gateway\sadvertise
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "default-gateway advertise",
+ "result": {"default_gateway": {"advertise": True}},
+ },
+ {
+ "name": "flooding_suppression.address_resolution.disable",
+ "getval": re.compile(
+ r"""
+ \sflooding-suppression\saddress-resolution\sdisable
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "flooding-suppression address-resolution disable",
+ "result": {
+ "flooding_suppression": {
+ "address_resolution": {
+ "disable": True,
+ },
+ },
+ },
+ "shared": True,
+ },
+ {
+ "name": "ip.local_learning.disable",
+ "getval": re.compile(
+ r"""
+ \sip\slocal-learning\sdisable
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "ip local-learning disable",
+ "result": {
+ "ip": {
+ "local_learning": {
+ "disable": True,
+ },
+ },
+ },
+ "shared": True,
+ },
+ {
+ "name": "replication_type",
+ "getval": re.compile(
+ r"""
+ \sreplication-type\s(?P<replication_type>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "replication-type {{replication_type}}",
+ "result": {"replication_type": "{{replication_type}}"},
+ "shared": True,
+ },
+ {
+ "name": "route_target.auto.vni",
+ "getval": re.compile(
+ r"""
+ \sroute-target\sauto\svni
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "route-target auto vni",
+ "result": {"route_target": {"auto": {"vni": True}}},
+ "shared": True,
+ },
+ {
+ "name": "router_id",
+ "getval": re.compile(
+ r"""
+ \srouter-id\s(?P<router_id>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "router-id {{ router_id }}",
+ "result": {"router_id": "{{router_id}}"},
+ "shared": True,
+ },
+ ]
+ # fmt: on
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv2.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv2.py
index 5b746e507..74b380cc5 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv2.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv2.py
@@ -5,31 +5,11 @@ __metaclass__ = type
import re
-from ansible.module_utils.six import iteritems
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
NetworkTemplate,
)
-def _tmplt_ospf_vrf_cmd(process):
- command = "router ospf {process_id}".format(**process)
- if "vrf" in process:
- command += " vrf {vrf}".format(**process)
- return command
-
-
-def _tmplt_ospf_adjacency_cmd(config_data):
- if "adjacency" in config_data:
- command = "adjacency stagger "
- if "none" in config_data["adjacency"]:
- command += " none"
- else:
- command += " {min_adjacency}".format(**config_data["adjacency"])
- if "max_adjacency" in config_data["adjacency"]:
- command += " {min_adjacency}".format(**config_data["adjacency"])
- return command
-
-
def _tmplt_ospf_address_family_cmd(config_data):
if "address_family" in config_data:
command = ["address-family ipv4 multicast", "exit-address-family"]
@@ -44,207 +24,30 @@ def _tmplt_ospf_address_family_cmd(config_data):
return command
-def _tmplt_ospf_area_authentication(config_data):
- if "authentication" in config_data:
- command = "area {area_id} authentication".format(**config_data)
- if config_data["authentication"].get("message_digest"):
- command += " message-digest"
- return command
-
-
-def _tmplt_ospf_area_filter(config_data):
- if "filter_list" in config_data:
- command = []
- for key, value in iteritems(config_data.get("filter_list")):
- cmd = "area {area_id}".format(**config_data)
- if value.get("name") and value.get("direction"):
- cmd += " filter-list prefix {name} {direction}".format(**value)
- command.append(cmd)
- return command
-
-
def _tmplt_ospf_area_nssa(config_data):
if "nssa" in config_data:
+ nssa_data = config_data["nssa"]
command = "area {area_id} nssa".format(**config_data)
- if "default_information_originate" in config_data["nssa"]:
+ if "default_information_originate" in nssa_data:
+ default_info = nssa_data["default_information_originate"]
command += " default-information-originate"
- if "metric" in config_data["nssa"]["default_information_originate"]:
- command += " metric {metric}".format(
- **config_data["nssa"]["default_information_originate"]
- )
- if "metric_type" in config_data["nssa"]["default_information_originate"]:
- command += " metric-type {metric_type}".format(
- **config_data["nssa"]["default_information_originate"]
- )
- if "nssa_only" in config_data["nssa"]["default_information_originate"]:
+ metric = default_info.get("metric")
+ if metric is not None:
+ command += " metric {metric}".format(metric=metric)
+ metric_type = default_info.get("metric_type")
+ if metric_type is not None:
+ command += " metric-type {metric_type}".format(metric_type=metric_type)
+ if default_info.get("nssa_only"):
command += " nssa-only"
- if config_data["nssa"].get("no_ext_capability"):
+ if nssa_data.get("no_ext_capability"):
command += " no-ext-capability"
- if config_data["nssa"].get("no_redistribution"):
+ if nssa_data.get("no_redistribution"):
command += " no-redistribution"
- if config_data["nssa"].get("no_summary"):
- command += " no-summary"
- return command
-
-
-def _tmplt_ospf_area_nssa_translate(config_data):
- if "nssa" in config_data:
- command = "area {area_id} nssa".format(**config_data)
- if "translate" in config_data["nssa"]:
- command += " translate type7 {translate}".format(**config_data["nssa"])
- return command
-
-
-def _tmplt_ospf_area_ranges(config_data):
- if "ranges" in config_data:
- commands = []
- for k, v in iteritems(config_data["ranges"]):
- cmd = "area {area_id} range".format(**config_data)
- temp_cmd = " {address} {netmask}".format(**v)
- if "advertise" in v:
- temp_cmd += " advertise"
- elif "not_advertise" in v:
- temp_cmd += " not-advertise"
- if "cost" in v:
- temp_cmd += " cost {cost}".format(**v)
- cmd += temp_cmd
- commands.append(cmd)
- return commands
-
-
-def _tmplt_ospf_area_sham_link(config_data):
- if "sham_link" in config_data:
- command = "area {area_id} sham-link".format(**config_data)
- if "source" in config_data["sham_link"]:
- command += " {source} {destination}".format(**config_data["sham_link"])
- if "cost" in config_data["sham_link"]:
- command += " cost {cost}".format(**config_data["sham_link"])
- if "ttl_security" in config_data["sham_link"]:
- command += " ttl-security hops {ttl_security}".format(**config_data["sham_link"])
- return command
-
-
-def _tmplt_ospf_area_stub_link(config_data):
- if "stub" in config_data:
- command = "area {area_id} stub".format(**config_data)
- if "no_ext_capability" in config_data["stub"]:
- command += " no-ext-capability"
- if "no_summary" in config_data["stub"]:
+ if nssa_data.get("no_summary"):
command += " no-summary"
return command
-def _tmplt_ospf_auto_cost(config_data):
- if "auto_cost" in config_data:
- command = "auto-cost"
- if "reference_bandwidth" in config_data["auto_cost"]:
- command += " reference-bandwidth {reference_bandwidth}".format(
- **config_data["auto_cost"]
- )
- return command
-
-
-def _tmplt_ospf_capability(config_data):
- if "capability" in config_data:
- if "lls" in config_data["capability"]:
- command = "capability lls"
- elif "opaque" in config_data["capability"]:
- command = "capability opaque"
- elif "transit" in config_data["capability"]:
- command = "capability transit"
- elif "vrf_lite" in config_data["capability"]:
- command = "capability vrf-lite"
- return command
-
-
-def _tmplt_ospf_compatible(config_data):
- if "compatible" in config_data:
- if "rfc1583" in config_data["compatible"]:
- command = "compatible rfc1583"
- elif "rfc1587" in config_data["compatible"]:
- command = "compatible rfc1587"
- elif "rfc5243" in config_data["compatible"]:
- command = "compatible rfc5243"
- return command
-
-
-def _tmplt_ospf_default_information(config_data):
- if "default_information" in config_data:
- command = "default-information"
- if "originate" in config_data["default_information"]:
- command += " originate"
- if "always" in config_data["default_information"]:
- command += " always"
- if "metric" in config_data["default_information"]:
- command += " metric {metric}".format(**config_data["default_information"])
- if "metric_type" in config_data["default_information"]:
- command += " metric-type {metric_type}".format(**config_data["default_information"])
- if "metric" in config_data["default_information"]:
- command += " route-map {route_map}".format(**config_data["default_information"])
- return command
-
-
-def _tmplt_ospf_discard_route(config_data):
- if "discard_route" in config_data:
- command = "discard-route"
- if "external" in config_data["discard_route"]:
- command += " external {external}".format(**config_data["discard_route"])
- if "internal" in config_data["discard_route"]:
- command += " internal {internal}".format(**config_data["discard_route"])
- return command
-
-
-def _tmplt_ospf_distance_admin_distance(config_data):
- if "admin_distance" in config_data["distance"]:
- command = "distance {distance}".format(**config_data["distance"]["admin_distance"])
- if "address" in config_data["distance"]["admin_distance"]:
- command += " {address} {wildcard_bits}".format(
- **config_data["distance"]["admin_distance"]
- )
- if "acl" in config_data["distance"]["admin_distance"]:
- command += " {acl}".format(**config_data["distance"]["admin_distance"])
- return command
-
-
-def _tmplt_ospf_distance_ospf(config_data):
- if "ospf" in config_data["distance"]:
- command = "distance ospf"
- if "inter_area" in config_data["distance"]["ospf"]:
- command += " inter-area {inter_area}".format(**config_data["distance"]["ospf"])
- if config_data["distance"].get("ospf").get("intra_area"):
- command += " intra-area {intra_area}".format(**config_data["distance"]["ospf"])
- if config_data["distance"].get("ospf").get("external"):
- command += " external {external}".format(**config_data["distance"]["ospf"])
- return command
-
-
-def _tmplt_ospf_distribute_list_acls(config_data):
- if "acls" in config_data.get("distribute_list"):
- command = []
- for k, v in iteritems(config_data["distribute_list"]["acls"]):
- cmd = "distribute-list {name} {direction}".format(**v)
- if "interface" in v:
- cmd += " {interface}".format(**v)
- if "protocol" in v:
- cmd += " {protocol}".format(**v)
- command.append(cmd)
- return command
-
-
-def _tmplt_ospf_distribute_list_prefix(config_data):
- if "prefix" in config_data.get("distribute_list"):
- command = "distribute-list prefix {name}".format(**config_data["distribute_list"]["prefix"])
- if "gateway_name" in config_data["distribute_list"]["prefix"]:
- command += " gateway {gateway_name}".format(**config_data["distribute_list"]["prefix"])
- if "direction" in config_data["distribute_list"]["prefix"]:
- command += " {direction}".format(**config_data["distribute_list"]["prefix"])
- if "interface" in config_data["distribute_list"]["prefix"]:
- command += " {interface}".format(**config_data["distribute_list"]["prefix"])
- if "protocol" in config_data["distribute_list"]["prefix"]:
- command += " {protocol}".format(**config_data["distribute_list"]["prefix"])
- return command
-
-
def _tmplt_ospf_domain_id(config_data):
if "domain_id" in config_data:
command = "domain-id"
@@ -252,76 +55,12 @@ def _tmplt_ospf_domain_id(config_data):
if "address" in config_data["domain_id"]["ip_address"]:
command += " {address}".format(**config_data["domain_id"]["ip_address"])
if "secondary" in config_data["domain_id"]["ip_address"]:
- command += " {secondary}".format(**config_data["domain_id"]["ip_address"])
+ command += " secondary".format(**config_data["domain_id"]["ip_address"])
elif "null" in config_data["domain_id"]:
command += " null"
return command
-def _tmplt_ospf_event_log(config_data):
- if "event_log" in config_data:
- command = "event-log"
- if "one_shot" in config_data["event_log"]:
- command += " one-shot"
- if "pause" in config_data["event_log"]:
- command += " pause"
- if "size" in config_data["event_log"]:
- command += " size {size}".format(**config_data["event_log"])
- return command
-
-
-def _tmplt_ospf_limit(config_data):
- if "limit" in config_data:
- command = "limit retransmissions"
- if "dc" in config_data["limit"]:
- if "number" in config_data["limit"]["dc"]:
- command += " dc {number}".format(**config_data["limit"]["dc"])
- if "disable" in config_data["limit"]["dc"]:
- command += " dc disable"
- if "non_dc" in config_data["limit"]:
- if "number" in config_data["limit"]["non_dc"]:
- command += " non-dc {number}".format(**config_data["limit"]["non_dc"])
- if "disable" in config_data["limit"]["dc"]:
- command += " non-dc disable"
- return command
-
-
-def _tmplt_ospf_vrf_local_rib_criteria(config_data):
- if "local_rib_criteria" in config_data:
- command = "local-rib-criteria"
- if "forwarding_address" in config_data["local_rib_criteria"]:
- command += " forwarding-address"
- if "inter_area_summary" in config_data["local_rib_criteria"]:
- command += " inter-area-summary"
- if "nssa_translation" in config_data["local_rib_criteria"]:
- command += " nssa-translation"
- return command
-
-
-def _tmplt_ospf_log_adjacency_changes(config_data):
- if "log_adjacency_changes" in config_data:
- command = "log-adjacency-changes"
- if "detail" in config_data["log_adjacency_changes"]:
- command += " detail"
- return command
-
-
-def _tmplt_ospf_max_lsa(config_data):
- if "max_lsa" in config_data:
- command = "max-lsa {number}".format(**config_data["max_lsa"])
- if "threshold_value" in config_data["max_lsa"]:
- command += " {threshold_value}".format(**config_data["max_lsa"])
- if "ignore_count" in config_data["max_lsa"]:
- command += " ignore-count {ignore_count}".format(**config_data["max_lsa"])
- if "ignore_time" in config_data["max_lsa"]:
- command += " ignore-time {ignore_time}".format(**config_data["max_lsa"])
- if "reset_time" in config_data["max_lsa"]:
- command += " reset-time {reset_time}".format(**config_data["max_lsa"])
- if "warning_only" in config_data["max_lsa"]:
- command += " warning-only"
- return command
-
-
def _tmplt_ospf_max_metric(config_data):
if "max_metric" in config_data:
command = "max-metric"
@@ -341,18 +80,6 @@ def _tmplt_ospf_max_metric(config_data):
return command
-def _tmplt_ospf_mpls_ldp(config_data):
- if "ldp" in config_data["mpls"]:
- command = "mpls ldp"
- if "autoconfig" in config_data["mpls"]["ldp"]:
- command += " autoconfig"
- if "area" in config_data["mpls"]["ldp"]["autoconfig"]:
- command += " area {area}".format(**config_data["mpls"]["ldp"]["autoconfig"])
- elif "sync" in config_data["mpls"]["ldp"]:
- command += " sync"
- return command
-
-
def _tmplt_ospf_mpls_traffic_eng(config_data):
if "traffic_eng" in config_data["mpls"]:
command = "mpls traffic-eng"
@@ -360,17 +87,17 @@ def _tmplt_ospf_mpls_traffic_eng(config_data):
command += " area {area}".format(**config_data["mpls"]["traffic_eng"])
elif "autoroute_exclude" in config_data["mpls"]["traffic_eng"]:
command += " autoroute-exclude prefix-list {autoroute_exclude}".format(
- **config_data["mpls"]["traffic_eng"]
+ **config_data["mpls"]["traffic_eng"],
)
elif "interface" in config_data["mpls"]["traffic_eng"]:
command += " interface {int_type}".format(
- **config_data["mpls"]["traffic_eng"]["interface"]
+ **config_data["mpls"]["traffic_eng"]["interface"],
)
if "area" in config_data["mpls"]["traffic_eng"]["interface"]:
command += " area {area}".format(**config_data["mpls"]["traffic_eng"]["interface"])
elif "mesh_group" in config_data["mpls"]["traffic_eng"]:
command += " mesh-group {id} {interface}".format(
- **config_data["mpls"]["traffic_eng"]["mesh_group"]
+ **config_data["mpls"]["traffic_eng"]["mesh_group"],
)
if "area" in config_data["mpls"]["traffic_eng"]["mesh_group"]:
command += " area {area}".format(**config_data["mpls"]["traffic_eng"]["mesh_group"])
@@ -378,7 +105,7 @@ def _tmplt_ospf_mpls_traffic_eng(config_data):
command += " multicast-intact"
elif "router_id_interface" in config_data["mpls"]["traffic_eng"]:
command += " router-id {router_id_interface}".format(
- **config_data["mpls"]["traffic_eng"]
+ **config_data["mpls"]["traffic_eng"],
)
return command
@@ -399,61 +126,8 @@ def _tmplt_ospf_neighbor(config_data):
return command
-def _tmplt_ospf_network(config_data):
- if "network" in config_data:
- command = []
- for each in config_data["network"]:
- cmd = "network"
- if "address" in each:
- cmd += " {address} {wildcard_bits}".format(**each)
- if "area" in each:
- cmd += " area {area}".format(**each)
- command.append(cmd)
- return command
-
-
-def _tmplt_ospf_nsf_cisco(config_data):
- if "cisco" in config_data["nsf"]:
- command = "nsf cisco helper"
- if "disable" in config_data["nsf"]["cisco"]:
- command += " disable"
- return command
-
-
-def _tmplt_ospf_nsf_ietf(config_data):
- if "ietf" in config_data["nsf"]:
- command = "nsf ietf helper"
- if "disable" in config_data["nsf"]["ietf"]:
- command += " disable"
- elif "strict_lsa_checking" in config_data["nsf"]["ietf"]:
- command += " strict-lsa-checking"
- return command
-
-
-def _tmplt_ospf_queue_depth_hello(config_data):
- if "hello" in config_data["queue_depth"]:
- command = "queue-depth hello"
- if "max_packets" in config_data["queue_depth"]["hello"]:
- command += " {max_packets}".format(**config_data["queue_depth"]["hello"])
- elif "unlimited" in config_data["queue_depth"]["hello"]:
- command += " unlimited"
- return command
-
-
-def _tmplt_ospf_queue_depth_update(config_data):
- if "update" in config_data["queue_depth"]:
- command = "queue-depth update"
- if "max_packets" in config_data["queue_depth"]["update"]:
- command += " {max_packets}".format(**config_data["queue_depth"]["update"])
- elif "unlimited" in config_data["queue_depth"]["update"]:
- command += " unlimited"
- return command
-
-
def _tmplt_ospf_passive_interfaces(config_data):
if "passive_interfaces" in config_data:
- if config_data["passive_interfaces"].get("default"):
- cmd = "passive-interface default"
if config_data["passive_interfaces"].get("interface"):
if config_data["passive_interfaces"].get("set_interface"):
for each in config_data["passive_interfaces"]["interface"]:
@@ -464,38 +138,6 @@ def _tmplt_ospf_passive_interfaces(config_data):
return cmd
-def _tmplt_ospf_summary_address(config_data):
- if "summary_address" in config_data:
- command = "summary-address {address} {mask}".format(**config_data["summary_address"])
- if "not_advertise" in config_data["summary_address"]:
- command += " not-advertise"
- elif "nssa_only" in config_data["summary_address"]:
- command += " nssa-only"
- if "tag" in config_data["summary_address"]:
- command += " tag {tag}".format(**config_data["summary_address"])
- return command
-
-
-def _tmplt_ospf_timers_pacing(config_data):
- if "pacing" in config_data["timers"]:
- command = "timers pacing"
- if "flood" in config_data["timers"]["pacing"]:
- command += " flood {flood}".format(**config_data["timers"]["pacing"])
- elif "lsa_group" in config_data["timers"]["pacing"]:
- command += " lsa-group {lsa_group}".format(**config_data["timers"]["pacing"])
- elif "retransmission" in config_data["timers"]["pacing"]:
- command += " retransmission {retransmission}".format(**config_data["timers"]["pacing"])
- return command
-
-
-def _tmplt_ospf_ttl_security(config_data):
- if "ttl_security" in config_data:
- command = "ttl-security all-interfaces"
- if "hops" in config_data["ttl_security"]:
- command += " hops {hops}".format(**config_data["ttl_security"])
- return command
-
-
class Ospfv2Template(NetworkTemplate):
def __init__(self, lines=None):
super(Ospfv2Template, self).__init__(lines=lines, tmplt=self)
@@ -505,52 +147,40 @@ class Ospfv2Template(NetworkTemplate):
"name": "pid",
"getval": re.compile(
r"""
- ^router\s
- ospf*
- \s(?P<pid>\S+)
- \svrf
- \s(?P<vrf>\S+)
- $""",
+ ^router\sospf
+ (\s(?P<pid>\d+))
+ (\s(vrf\s(?P<vrf_value>\S+)))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_vrf_cmd,
+ "setval": "router ospf {{ process_id }}"
+ "{{ (' vrf ' + vrf ) if vrf is defined else '' }}",
"result": {
- "processes": {"{{ pid }}": {"process_id": "{{ pid|int }}", "vrf": "{{ vrf }}"}},
+ "processes": {
+ "{{ pid }}": {"process_id": "{{ pid|int }}", "vrf": "{{ vrf_value }}"},
+ },
},
"shared": True,
},
{
- "name": "pid",
- "getval": re.compile(
- r"""
- ^router\s
- ospf*
- \s(?P<pid>\S+)
- $""",
- re.VERBOSE,
- ),
- "setval": _tmplt_ospf_vrf_cmd,
- "result": {"processes": {"{{ pid }}": {"process_id": "{{ pid|int }}"}}},
- "shared": True,
- },
- {
"name": "adjacency",
"getval": re.compile(
- r"""\s+adjacency
- \sstagger*
- \s*((?P<min>\d+)|(?P<none_adj>none))*
- \s*(?P<max>\S+)
- *$""",
+ r"""
+ \sadjacency\sstagger
+ (\s(?P<min>\d+))?
+ (\s(?P<none>none))?
+ (\s(?P<max>\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_adjacency_cmd,
+ "setval": "adjacency stagger {{ 'none' if adjacency.none else adjacency.min_adjacency }} {{ adjacency.max_adjacency }}",
"result": {
"processes": {
"{{ pid }}": {
"adjacency": {
"min_adjacency": "{{ min|int }}",
"max_adjacency": "{{ max|int }}",
- "none": "{{ True if none_adj is defined else None }}",
+ "none": "{{ True if none_adj is defined else False }}",
},
},
},
@@ -559,11 +189,12 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "address_family",
"getval": re.compile(
- r"""\s+topology
- \s(?P<base>base)*
- \s*(?P<name>\S+)*
- \s*(?P<tid>tid\s\d+)
- *$""",
+ r"""
+ \stopology
+ (\s(?P<base>base))?
+ (\s(?P<name>\S+))?
+ (\stid\s(?P<tid>\S+))?
+ $""",
re.VERBOSE,
),
"setval": _tmplt_ospf_address_family_cmd,
@@ -574,7 +205,7 @@ class Ospfv2Template(NetworkTemplate):
"topology": {
"base": "{{ True if base is defined }}",
"name": "{{ name }}",
- "tid": "{{ tid.split(" ")[1] }}",
+ "tid": "{{ tid }}",
},
},
},
@@ -582,17 +213,18 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.authentication",
+ "name": "authentication",
"getval": re.compile(
- r"""\s+area
- \s(?P<area_id>\S+)*
- \s*(?P<auth>authentication)*
- \s*(?P<md>message-digest)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ (\s(?P<auth>authentication))?
+ (\s(?P<md>message-digest))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_authentication,
- "compval": "authentication",
+ "setval": "area {{ area_id }} authentication"
+ "{{ ' message-digest' if authentication.message_digest else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -610,17 +242,17 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.capability",
+ "name": "capability",
"getval": re.compile(
- r"""\s+area
- \s(?P<area_id>\S+)*
- \s*(?P<capability>capability)*
- \s*(?P<df>default-exclusion)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ (\s(?P<capability>capability))?
+ \sdefault-exclusion
+ $""",
re.VERBOSE,
),
"setval": "area {{ area_id }} capability default-exclusion",
- "compval": "capability",
"result": {
"processes": {
"{{ pid }}": {
@@ -635,17 +267,17 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.default_cost",
+ "name": "default_cost",
"getval": re.compile(
- r"""\s+area
- \s(?P<area_id>\S+)*
- \sdefault-cost*
- \s*(?P<default_cost>\S+)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ \sdefault-cost
+ (\s(?P<default_cost>\S+))?
+ $""",
re.VERBOSE,
),
"setval": "area {{ area_id }} default-cost {{ default_cost }}",
- "compval": "default_cost",
"result": {
"processes": {
"{{ pid }}": {
@@ -660,25 +292,30 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.filter_list",
+ "name": "filter_list",
"getval": re.compile(
- r"""\s+area
- \s*(?P<area_id>\S+)*
- \s*filter-list\sprefix*
- \s*(?P<name>\S+)*
- \s*(?P<dir>\S+)
- *$""",
+ r"""
+ \s+area
+ (\s(?P<area_id>\S+))?
+ \sfilter-list\sprefix
+ (\s(?P<name>\S+))?
+ (\s(?P<dir>\S+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_filter,
- "compval": "filter_list",
+ "setval": "area {{ area_id }}" " filter-list prefix {{ name }} {{ direction }}",
"result": {
"processes": {
"{{ pid }}": {
"areas": {
"{{ area_id }}": {
"area_id": "{{ area_id }}",
- "filter_list": [{"name": "{{ name }}", "direction": "{{ dir }}"}],
+ "filter_list": [
+ {
+ "name": "{{ name }}",
+ "direction": "{{ dir }}",
+ },
+ ],
},
},
},
@@ -686,20 +323,23 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.nssa",
+ "name": "nssa",
"getval": re.compile(
- r"""\s+area\s(?P<area_id>\S+)
- \s(?P<nssa>nssa)*
- \s*(?P<no_redis>no-redistribution)*
- \s*(?P<def_origin>default-information-originate)*
- \s*(?P<metric>metric\s\d+)*
- \s*(?P<metric_type>metric-type\s\d+)*
- \s*(?P<no_summary>no-summary)*
- \s*(?P<no_ext>no-ext-capability)*$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ (\s(?P<nssa>nssa))?
+ (\s(?P<no_redis>no-redistribution))?
+ (\s(?P<def_origin>default-information-originate))?
+ (\smetric\s(?P<metric>\d+))?
+ (\smetric-type\s(?P<metric_type>\d+))?
+ (\s(?P<no_summary>no-summary))?
+ (\s(?P<nssa_only>nssa-only))?
+ (\s(?P<no_ext>no-ext-capability))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_nssa_translate,
- "compval": "nssa",
+ "setval": _tmplt_ospf_area_nssa,
"result": {
"processes": {
"{{ pid }}": {
@@ -707,13 +347,11 @@ class Ospfv2Template(NetworkTemplate):
"{{ area_id }}": {
"area_id": "{{ area_id }}",
"nssa": {
- "set": "{{ True if nssa is defined and def_origin is undefined and "
+ "set": "{{ True if def_origin is undefined and "
"no_ext is undefined and no_redis is undefined and nssa_only is undefined }}",
"default_information_originate": {
- "set": "{{ True if def_origin is defined and metric is undefined and "
- "metric_type is undefined and nssa_only is undefined }}",
- "metric": "{{ metric.split(" ")[1]|int }}",
- "metric_type": "{{ metric_type.split(" ")[1]|int }}",
+ "metric": "{{ metric|int }}",
+ "metric_type": "{{ metric_type|int }}",
"nssa_only": "{{ True if nssa_only is defined }}",
},
"no_ext_capability": "{{ True if no_ext is defined }}",
@@ -727,19 +365,19 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.nssa.translate",
+ "name": "nssa.translate",
"getval": re.compile(
- r"""\s+area*
- \s*(?P<area_id>\S+)*
- \s*(?P<nssa>nssa)*
- \stranslate\stype7*
- \s(?P<translate_always>always)*
- \s* (?P<translate_supress>suppress-fa)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ \snssa
+ \stranslate\stype7
+ (\s(?P<translate_always>always|suppress-fa))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_nssa,
- "compval": "nssa.translate",
+ "setval": "area {{ area_id }} nssa "
+ "translate type7 {{ nssa.translate if nssa.translate is defined }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -747,7 +385,7 @@ class Ospfv2Template(NetworkTemplate):
"{{ area_id }}": {
"area_id": "{{ area_id }}",
"nssa": {
- "translate": "{{ translate_always if translate_always is defined else translate_supress if translate_supress is defined }}",
+ "translate": "{{ translate_always }}",
},
},
},
@@ -756,19 +394,24 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.ranges",
+ "name": "ranges",
"getval": re.compile(
- r"""\s+area\s(?P<area_id>\S+)
- \srange
- \s(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
- \s(?P<netmask>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*((?P<advertise>advertise)|(?P<not_advertise>not-advertise))*
- \s*(?P<cost>cost\s\d+)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))
+ \srange
+ (\s(?P<address>\S+))
+ (\s(?P<netmask>\S+))
+ (\s(?P<advertise>advertise))?
+ (\s(?P<not_advertise>not-advertise))?
+ (\s(cost\s(?P<cost>\d+)))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_ranges,
- "compval": "ranges",
+ "setval": "area {{ area_id }} range {{ address }} {{ netmask }}"
+ "{{ (' advertise') if advertise is defined and advertise else '' }}"
+ "{{ (' not-advertise') if not_advertise is defined and not_advertise else '' }}"
+ "{{ (' cost ' + cost|string) if cost is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -780,7 +423,7 @@ class Ospfv2Template(NetworkTemplate):
"address": "{{ address }}",
"netmask": "{{ netmask }}",
"advertise": "{{ True if advertise is defined }}",
- "cost": "{{ cost.split(" ")[1]|int }}",
+ "cost": "{{ cost }}",
"not_advertise": "{{ True if not_advertise is defined }}",
},
],
@@ -791,19 +434,22 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.sham_link",
+ "name": "sham_link",
"getval": re.compile(
- r"""\s+area\s(?P<area_id>\S+)
- \ssham-link
- \s(?P<source>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
- \s(?P<destination>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<cost>cost\s\d+)*
- \s*(?P<ttl_security>ttl-security\shops\s\d+)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ \ssham-link
+ (\s(?P<source>\S+))?
+ (\s(?P<destination>\S+))?
+ (\s(cost\s(?P<cost>\d+)))?
+ (\s(ttl-security\shops\s(?P<ttl_security>\d+)))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_sham_link,
- "compval": "sham_link",
+ "setval": "area {{ area_id }} sham-link {{ sham_link.source }} {{ sham_link.destination }}"
+ "{{ (' cost ' + sham_link.cost|string) if sham_link.cost is defined else '' }}"
+ "{{ (' ttl-security hops ' + sham_link.ttl_security|string) if sham_link.ttl_security is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -813,8 +459,8 @@ class Ospfv2Template(NetworkTemplate):
"sham_link": {
"source": "{{ source }}",
"destination": "{{ destination }}",
- "cost": "{{ cost.split(" ")[1]|int }}",
- "ttl_security": '{{ ttl_security.split("hops ")[1] }}',
+ "cost": "{{ cost }}",
+ "ttl_security": "{{ ttl_security }}",
},
},
},
@@ -823,17 +469,20 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "area.stub",
+ "name": "stub",
"getval": re.compile(
- r"""\s+area\s(?P<area_id>\S+)
- \s(?P<stub>stub)*
- \s*(?P<no_ext>no-ext-capability)*
- \s*(?P<no_sum>no-summary)
- *$""",
+ r"""
+ \sarea
+ (\s(?P<area_id>\S+))?
+ (\s(?P<stub>stub))?
+ (\s(?P<no_ext>no-ext-capability))?
+ (\s(?P<no_sum>no-summary))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_area_stub_link,
- "compval": "stub",
+ "setval": "area {{ area_id }} stub"
+ "{{ (' no-ext-capability') if stub.no_ext_capability else ''}}"
+ "{{ (' no-summary') if stub.no_summary else ''}}",
"result": {
"processes": {
"{{ pid }}": {
@@ -854,18 +503,20 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "auto_cost",
"getval": re.compile(
- r"""\s+(?P<auto_cost>auto-cost)*
- \s*(?P<ref_band>reference-bandwidth\s\d+)
- *$""",
+ r"""
+ (\s(?P<auto_cost>auto-cost))
+ (\sreference-bandwidth\s(?P<ref_band>\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_auto_cost,
+ "setval": "auto-cost"
+ "{{ ' reference-bandwidth ' + auto_cost.reference_bandwidth|string if auto_cost.reference_bandwidth is defined }}",
"result": {
"processes": {
"{{ pid }}": {
"auto_cost": {
- "set": "{{ True if auto_cost is defined and ref_band is undefined }}",
- "reference_bandwidth": '{{ ref_band.split(" ")[1] }}',
+ "set": True,
+ "reference_bandwidth": "{{ ref_band }}",
},
},
},
@@ -874,31 +525,90 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "bfd",
"getval": re.compile(
- r"""\s+bfd*
- \s*(?P<bfd>all-interfaces)
- *$""",
+ r"""
+ \sbfd
+ (\s(?P<bfd>all-interfaces))?
+ $""",
re.VERBOSE,
),
"setval": "bfd all-interfaces",
"result": {"processes": {"{{ pid }}": {"bfd": "{{ True if bfd is defined }}"}}},
},
{
- "name": "capability",
+ "name": "capability.lls",
"getval": re.compile(
- r"""\s+capability*
- \s*((?P<lls>lls)|(?P<opaque>opaque)|(?P<transit>transit)|(?P<vrf_lite>vrf-lite))
- *$""",
+ r"""
+ \scapability
+ (\s(?P<lls>lls))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_capability,
+ "setval": "capability lls",
"result": {
"processes": {
"{{ pid }}": {
"capability": {
- "lls": "{{ True if lls is defined }}",
- "opaque": "{{ True if opaque is defined }}",
- "transit": "{{ True if transit is defined }}",
- "vrf_lite": "{{ True if vrf_lite is defined }}",
+ "lls": True,
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "capability.opaque",
+ "getval": re.compile(
+ r"""
+ \scapability
+ (\s(?P<opaque>opaque))
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "capability opaque",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "capability": {
+ "opaque": True,
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "capability.transit",
+ "getval": re.compile(
+ r"""
+ \scapability
+ (\s(?P<transit>transit))
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "capability transit",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "capability": {
+ "transit": True,
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "capability.vrf_lite",
+ "getval": re.compile(
+ r"""
+ \scapability
+ (\s(?P<vrf_lite>vrf-lite))
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "capability vrf-lite",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "capability": {
+ "vrf_lite": True,
},
},
},
@@ -907,19 +617,23 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "compatible",
"getval": re.compile(
- r"""\s+compatible*
- \s*((?P<rfc1583>rfc1583)|(?P<rfc1587>rfc1587)|(?P<rfc5243>rfc5243))
- *$""",
+ r"""
+ \scompatible
+ (\s(?P<rfc>rfc1583|rfc1587|rfc5243))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_compatible,
+ "setval": "compatible"
+ "{{ (' rfc1583') if compatible.rfc1583 else ''}}"
+ "{{ (' rfc1587') if compatible.rfc1587 else ''}}"
+ "{{ (' rfc5243') if compatible.rfc5243 else ''}}",
"result": {
"processes": {
"{{ pid }}": {
"compatible": {
- "rfc1583": "{{ True if rfc1583 is defined }}",
- "rfc1587": "{{ True if rfc1587 is defined }}",
- "rfc5243": "{{ True if rfc5243 is defined }}",
+ "rfc1583": "{{ True if 'rfc1583' in rfc else False }}",
+ "rfc1587": "{{ True if 'rfc1587' in rfc else False }}",
+ "rfc5243": "{{ True if 'rfc5243' in rfc else False }}",
},
},
},
@@ -928,25 +642,31 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "default_information",
"getval": re.compile(
- r"""\s+default-information*
- \s*(?P<originate>originate)*
- \s*(?P<always>always)*
- \s*(?P<metric>metric\s\d+)*
- \s*(?P<metric_type>metric-type\s\d+)*
- \s*(?P<route_map>route-map\s\S+)
- *$""",
+ r"""
+ \sdefault-information
+ (\s(?P<originate>originate))?
+ (\s(?P<always>always))?
+ (\smetric\s(?P<metric>\d+))?
+ (\smetric-type\s(?P<metric_type>\d+))?
+ (\sroute-map\s(?P<route_map>\S+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_default_information,
+ "setval": "default-information"
+ "{{ ' originate' if default_information.originate is defined else ''}}"
+ "{{ ' always' if default_information.always is defined else '' }}"
+ "{{ (' metric ' + default_information.metric|string) if default_information.metric is defined else '' }}"
+ "{{ (' metric-type ' + default_information.metric_type|string) if default_information.metric_type is defined else '' }}"
+ "{{ ' route-map ' + default_information.route_map if default_information.route_map is defined and default_information.metric is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
"default_information": {
"originate": "{{ True if originate is defined }}",
"always": "{{ True if always is defined }}",
- "metric": "{{ metric.split(" ")[1]|int }}",
- "metric_type": "{{ metric_type.split(" ")[1]|int }}",
- "route_map": "{{ route_map.split(" ")[1] }}",
+ "metric": "{{ metric }}",
+ "metric_type": "{{ metric_type }}",
+ "route_map": "{{ route_map }}",
},
},
},
@@ -955,30 +675,35 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "default_metric",
"getval": re.compile(
- r"""\s+default-metric(?P<default_metric>\s\d+)
- *$""",
+ r"""
+ \sdefault-metric
+ \s(?P<default_metric>\d+)?
+ $""",
re.VERBOSE,
),
- "setval": "default-metric {{ default_metric }}",
- "result": {"processes": {"{{ pid }}": {"default_metric": "{{ default_metric| int}}"}}},
+ "setval": "default-metric {{ default_metric|string }}",
+ "result": {"processes": {"{{ pid }}": {"default_metric": "{{ default_metric }}"}}},
},
{
"name": "discard_route",
"getval": re.compile(
- r"""\s+(?P<discard_route>discard-route)*
- \s*(?P<external>external\s\d+)*
- \s*(?P<internal>internal\s\d+)
- *$""",
+ r"""
+ (\s(?P<discard_route>discard-route))
+ (\sexternal\s(?P<external>\d+))?
+ (\sinternal\s(?P<internal>\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_discard_route,
+ "setval": "discard-route"
+ "{{ ' external ' + discard_route.external|string if discard_route.external is defined else '' }}"
+ "{{ ' internal ' + discard_route.internal|string if discard_route.internal is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
"discard_route": {
- "set": "{{ True if discard_route is defined and external is undefined and internal is undefined }}",
- "external": "{{ external.split(" ")[1]|int }}",
- "internal": "{{ internal.split(" ")[1]|int }}",
+ "set": True,
+ "external": "{{ external }}",
+ "internal": "{{ internal }}",
},
},
},
@@ -987,16 +712,18 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "distance.admin_distance",
"getval": re.compile(
- r"""\s+distance
- \s(?P<admin_dist>\S+)*
- \s*(?P<source>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<wildcard>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<acl>\S+)
- *$""",
+ r"""
+ \sdistance
+ (\s(?P<admin_dist>\S+))
+ (\s(?P<source>\S+))?
+ (\s(?P<wildcard>\S+))?
+ (\s(?P<acl>\S+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_distance_admin_distance,
- "compval": "admin_distance",
+ "setval": "distance {{ admin_distance.distance }} "
+ "{{ ( admin_distance.address + ' ' + admin_distance.wildcard_bits ) if admin_distance.address is defined else '' }}"
+ "{{ ' ' + admin_distance.acl if admin_distance.acl is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1015,24 +742,26 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "distance.ospf",
"getval": re.compile(
- r"""\s+distance
- \sospf*
- \s*(?P<intra>intra-area\s\d+)*
- \s*(?P<inter>inter-area\s\d+)*
- \s*(?P<external>external\s\d+)
- *$""",
+ r"""
+ \sdistance\sospf
+ (\sintra-area\s(?P<intra>\d+))
+ (\sinter-area\s(?P<inter>\d+))
+ (\sexternal\s(?P<external>\d+))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_distance_ospf,
- "compval": "ospf",
+ "setval": "distance ospf"
+ "{{ ' inter-area ' + distance.ospf.inter_area|string if distance.ospf.inter_area is defined else '' }}"
+ "{{ ' intra-area ' + distance.ospf.intra_area|string if distance.ospf.intra_area is defined else '' }}"
+ "{{ ' external ' + distance.ospf.external|string if distance.ospf.external is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
"distance": {
"ospf": {
- "inter_area": "{{ inter.split(" ")[1]|int }}",
- "intra_area": "{{ intra.split(" ")[1]|int }}",
- "external": "{{ external.split(" ")[1]|int }}",
+ "inter_area": "{{ inter|int }}",
+ "intra_area": "{{ intra|int }}",
+ "external": "{{ external|int }}",
},
},
},
@@ -1042,15 +771,15 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "distribute_list.acls",
"getval": re.compile(
- r"""\s+distribute-list
- \s(?P<name>\S+)*
- \s*(?P<dir>\S+)*
- \s*(?P<int_pro>\S+\s\d+)
- *$""",
+ r"""
+ \sdistribute-list
+ (\s(?P<name>\S+))
+ (\s(?P<dir>\S+))
+ (\s(?P<int_pro>\S+\s\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_distribute_list_acls,
- "compval": "distribute_list.acls",
+ "setval": "distribute-list {{ name }} {{ direction }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1071,23 +800,27 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "distribute_list.prefix",
"getval": re.compile(
- r"""\s+distribute-list
- \s(?P<prefix>prefix\s\S+)*
- \s*(?P<gateway>gateway\s\S+)*
- \s*(?P<dir>\S+)*
- \s*(?P<int_pro>\S+\s\S+)
- *$""",
+ r"""
+ \sdistribute-list
+ (\sprefix\s(?P<prefix>\S+))
+ (\sgateway\s(?P<gateway>\S+))?
+ (\s(?P<dir>\S+))?
+ (\s(?P<int_pro>\S+\s\S+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_distribute_list_prefix,
- "compval": "distribute_list.prefix",
+ "setval": "distribute-list prefix {{ distribute_list.prefix.name }}"
+ "{{ ' gateway ' + distribute_list.prefix.gateway_name if distribute_list.prefix.gateway_name is defined else '' }}"
+ "{{ ' ' + distribute_list.prefix.direction if distribute_list.prefix.direction is defined else '' }}"
+ "{{ ' ' + distribute_list.prefix.interface if distribute_list.prefix.interface is defined else '' }}"
+ "{{ ' ' + distribute_list.prefix.protocol if distribute_list.prefix.protocol is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
"distribute_list": {
"prefix": {
- "name": "{{ prefix.split(" ")[1] }}",
- "gateway_name": "{{ gateway.split(" ")[1] if prefix is defined }}",
+ "name": "{{ prefix }}",
+ "gateway_name": "{{ gateway }}",
"direction": "{{ dir if gateway is undefined }}",
"interface": '{{ int_pro if dir == "in" }}',
"protocol": '{{ int_pro if dir == "out" }}',
@@ -1100,18 +833,18 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "distribute_list.route_map",
"getval": re.compile(
- r"""\s+distribute-list
- \s(?P<route_map>route-map\s\S+)*
- \s*(?P<dir>\S+)
- *$""",
+ r"""
+ \sdistribute-list
+ (\sroute-map\s(?P<route_map>\S+))
+ (\s(?P<dir>\S+))
+ $""",
re.VERBOSE,
),
"setval": "distribute-list route-map {{ distribute_list.route_map.name }} in",
- "compval": "distribute_list.route_map",
"result": {
"processes": {
"{{ pid }}": {
- "distribute_list": {"route_map": {"name": "{{ route_map.split(" ")[1] }}"}},
+ "distribute_list": {"route_map": {"name": "{{ route_map }}"}},
},
},
},
@@ -1119,11 +852,12 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "domain_id",
"getval": re.compile(
- r"""\s+domain-id
- \s(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<secondary>secondary)*
- \s*(?P<null>null)
- *$""",
+ r"""
+ \sdomain-id
+ (\s(?P<address>\S+))
+ (\s(?P<secondary>secondary))?
+ (\s(?P<null>null))?
+ $""",
re.VERBOSE,
),
"setval": _tmplt_ospf_domain_id,
@@ -1144,9 +878,10 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "domain_tag",
"getval": re.compile(
- r"""\s+domain-tag
- \s(?P<tag>\d+)
- *$""",
+ r"""
+ \sdomain-tag
+ (\s(?P<tag>\d+))
+ $""",
re.VERBOSE,
),
"setval": "domain-tag {{ domain_tag }}",
@@ -1155,14 +890,18 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "event_log",
"getval": re.compile(
- r"""\s+(?P<event_log>event-log)*
- \s*(?P<one_shot>one-shot)*
- \s*(?P<pause>pause)*
- \s*(?P<size>size\s\d+)
- *$""",
+ r"""
+ (\s(?P<event_log>event-log))?
+ (\s(?P<one_shot>one-shot))?
+ (\s(?P<pause>pause))?
+ (\ssize\s(?P<size>\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_event_log,
+ "setval": "event-log"
+ "{{ ' one-shot' if event_log.one_shot else '' }}"
+ "{{ ' pause' if event_log.pause else '' }}"
+ "{{ ' size ' + event_log.size|string if event_log.size is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1170,7 +909,7 @@ class Ospfv2Template(NetworkTemplate):
"enable": "{{ True if event_log is defined and one_shot is undefined and pause is undefined and size is undefined }}",
"one_shot": "{{ True if one_shot is defined }}",
"pause": "{{ True if pause is defined }}",
- "size": "{{ size.split(" ")[1]|int }}",
+ "size": "{{ size }}",
},
},
},
@@ -1179,8 +918,9 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "help",
"getval": re.compile(
- r"""\s+(?P<help>help)
- *$""",
+ r"""
+ \s(?P<help>help)
+ $""",
re.VERBOSE,
),
"setval": "help",
@@ -1189,8 +929,9 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "ignore",
"getval": re.compile(
- r"""\s+(?P<ignore>ignore)
- *$""",
+ r"""
+ \s(?P<ignore>ignore)
+ $""",
re.VERBOSE,
),
"setval": "ignore lsa mospf",
@@ -1199,8 +940,9 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "interface_id",
"getval": re.compile(
- r"""\s+(?P<interface_id>interface-id\ssnmp-if-index)
- *$""",
+ r"""
+ (\s(?P<interface_id>interface-id\ssnmp-if-index))?
+ $""",
re.VERBOSE,
),
"setval": "interface-id snmp-if-index",
@@ -1213,8 +955,9 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "ispf",
"getval": re.compile(
- r"""\s+(?P<ispf>ispf)
- *$""",
+ r"""
+ \s(?P<ispf>ispf)
+ $""",
re.VERBOSE,
),
"setval": "ispf",
@@ -1223,24 +966,31 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "limit",
"getval": re.compile(
- r"""\s+limit\sretransmissions
- \s((?P<dc_num>dc\s\d+)|(?P<dc_disable>dc\sdisable))*
- \s*((?P<non_dc_num>non-dc\s\d+)|(?P<non_dc_disable>non-dc\sdisable))
- *$""",
+ r"""
+ \slimit\sretransmissions
+ (\sdc\s(?P<dc_num>\d+))?
+ (\sdc\sdisable(?P<dc_disable>))?
+ (\snon-dc\s(?P<non_dc_num>\d+))?
+ (\snon-dc\sdisable(?P<non_dc_disable>))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_limit,
+ "setval": "limit retransmissions"
+ "{{ ' dc ' + limit.dc.number|string if limit.dc.number is defined }}"
+ "{{ ' dc disable' if limit.dc.disable and limit.dc.number is not defined }}"
+ "{{ ' non-dc ' + limit.non_dc.number|string if limit.non_dc.number is defined }}"
+ "{{ ' non-dc disable' if limit.non_dc.disable and limit.non_dc.number is not defined }}",
"result": {
"processes": {
"{{ pid }}": {
"limit": {
"dc": {
- "number": "{{ dc_num.split(" ")[1]|int }}",
+ "number": "{{ dc_num|int }}",
"disable": "{{ True if dc_disable is defined }}",
},
"non_dc": {
- "number": "{{ non_dc_num.split(" ")[1]|int }}",
- "disable": "{{ True if dc_disable is defined }}",
+ "number": "{{ non_dc_num|int }}",
+ "disable": "{{ True if non_dc_disable is defined }}",
},
},
},
@@ -1250,14 +1000,18 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "local_rib_criteria",
"getval": re.compile(
- r"""\s+(?P<local>local-rib-criteria)*
- \s*(?P<forward>forwarding-address)*
- \s*(?P<inter>inter-area-summary)*
- \s*(?P<nssa>nssa-translation)
- *$""",
+ r"""
+ (\s(?P<local>local-rib-criteria))?
+ (\s(?P<forward>forwarding-address))?
+ (\s(?P<inter>inter-area-summary))?
+ (\s(?P<nssa>nssa-translation))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_vrf_local_rib_criteria,
+ "setval": "local-rib-criteria"
+ "{{ ' forwarding-address' if local_rib_criteria.forwarding_address else '' }}"
+ "{{ ' inter-area-summary' if local_rib_criteria.inter_area_summary else '' }}"
+ "{{ ' nssa-translation' if local_rib_criteria.nssa_translation else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1274,12 +1028,14 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "log_adjacency_changes",
"getval": re.compile(
- r"""\s+(?P<log>log-adjacency-changes)*
- \s*(?P<detail>detail)
- *$""",
+ r"""
+ (\s(?P<log>log-adjacency-changes))?
+ (\s(?P<detail>detail))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_log_adjacency_changes,
+ "setval": "log-adjacency-changes"
+ "{{ ' detail' if log_adjacency_changes.detail else '' }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1294,25 +1050,31 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "max_lsa",
"getval": re.compile(
- r"""\s+max-lsa
- \s(?P<number>\d+)*
- \s*(?P<threshold>\d+)*
- \s*(?P<ignore_count>ignore-count\s\d+)*
- \s*(?P<ignore_time>ignore-time\s\d+)*
- \s*(?P<reset_time>reset-time\s\d+)
- *$""",
+ r"""\smax-lsa
+ (\s(?P<number>\d+))?
+ (\s(?P<threshold>\d+))?
+ (\s(?P<warning>warning-only))?
+ (\signore-count\s(?P<ignore_count>\d+))?
+ (\signore-time\s(?P<ignore_time>\d+))?
+ (\sreset-time\s(?P<reset_time>\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_max_lsa,
+ "setval": "max-lsa {{ max_lsa.number|string }}"
+ "{{ ' ' + max_lsa.threshold_value|string if max_lsa.threshold_value is defined else '' }}"
+ "{{ ' warning-only' if max_lsa.warning_only else '' }}"
+ "{{ ' ignore-count ' + max_lsa.ignore_count|string if max_lsa.ignore_count is defined and not max_lsa.warning_only else '' }}"
+ "{{ ' ignore-time ' + max_lsa.ignore_time|string if max_lsa.ignore_time is defined and not max_lsa.warning_only else '' }}"
+ "{{ ' reset-time ' + max_lsa.reset_time|string if max_lsa.reset_time is defined and not max_lsa.warning_only else '' }}",
"result": {
"processes": {
"{{ pid }}": {
"max_lsa": {
"number": "{{ number }}",
"threshold_value": "{{ threshold }}",
- "ignore_count": "{{ ignore_count.split(" ")[1] }}",
- "ignore_time": "{{ ignore_time.split(" ")[1] }}",
- "reset_time": "{{ reset_time.split(" ")[1] }}",
+ "ignore_count": "{{ ignore_count }}",
+ "ignore_time": "{{ ignore_time }}",
+ "reset_time": "{{ reset_time }}",
"warning_only": "{{ True if warning is defined }}",
},
},
@@ -1322,14 +1084,15 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "max_metric",
"getval": re.compile(
- r"""\s+max-metric*
- \s*(?P<router_lsa>router-lsa)*
- \s*(?P<include_stub>include-stub)*
- \s*(?P<external_lsa>external-lsa\s\d+)*
- \s*(?P<startup_time>on-startup\s\d+)*
- \s*(?P<startup_wait>on-startup\s\S+)*
- \s*(?P<summary_lsa>summary-lsa\s\d+)
- *$""",
+ r"""
+ \smax-metric
+ (\s(?P<router_lsa>router-lsa))?
+ (\s(?P<include_stub>include-stub))?
+ (\sexternal-lsa\s(?P<external_lsa>\d+))?
+ (\son-startup\s(?P<startup_time>\d+))?
+ (\son-startup\s(?P<startup_wait>\S+))?
+ (\ssummary-lsa\s(?P<summary_lsa>\d+))?
+ $""",
re.VERBOSE,
),
"setval": _tmplt_ospf_max_metric,
@@ -1338,13 +1101,13 @@ class Ospfv2Template(NetworkTemplate):
"{{ pid }}": {
"max_metric": {
"router_lsa": "{{ True if router_lsa is defined }}",
- "external_lsa": "{{ external_lsa.split(" ")[1] }}",
- "include_stub": "{{ ignore_count.split(" ")[1] }}",
+ "external_lsa": "{{ external_lsa }}",
+ "include_stub": "{{ ignore_count }}",
"on_startup": {
- "time": "{{ startup_time.split(" ")[1] }}",
+ "time": "{{ startup_time }}",
"wait_for_bgp": "{{ True if startup_wait is defined }}",
},
- "summary_lsa": "{{ summary_lsa.split(" ")[1] }}",
+ "summary_lsa": "{{ summary_lsa }}",
},
},
},
@@ -1353,26 +1116,27 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "maximum_paths",
"getval": re.compile(
- r"""\s+maximum-paths*
- \s+(?P<paths>\d+)
- *$""",
+ r"""
+ \smaximum-paths
+ \s(?P<paths>\d+)
+ $""",
re.VERBOSE,
),
- "setval": "maximum-paths {{ maximum_paths }}",
+ "setval": "maximum-paths {{ maximum_paths|string }}",
"result": {"processes": {"{{ pid }}": {"maximum_paths": "{{ paths }}"}}},
},
{
- "name": "mpls.ldp",
+ "name": "mpls.ldp.autoconfig",
"getval": re.compile(
- r"""\s+mpls
- \sldp*
- \s*(?P<autoconfig>autoconfig*\s*(?P<area>area\s\S+))*
- \s*(?P<sync>sync)
- *$""",
+ r"""
+ \smpls\sldp
+ (\s(?P<autoconfig>autoconfig))
+ (\sarea\s(?P<area>\S+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_mpls_ldp,
- "compval": "ldp",
+ "setval": "mpls ldp autoconfig"
+ "{{ ' area ' + mpls.ldp.autoconfig.area if mpls.ldp.autoconfig.area is defined }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1380,9 +1144,30 @@ class Ospfv2Template(NetworkTemplate):
"ldp": {
"autoconfig": {
"set": "{{ True if autoconfig is defined and area is undefined }}",
- "area": "{{ area.split(" ")[1] }}",
+ "area": "{{ area }}",
},
- "sync": "{{ True if sync is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "mpls.ldp.sync",
+ "getval": re.compile(
+ r"""
+ \smpls\sldp
+ (\s(?P<sync>sync))
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "mpls ldp sync",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "mpls": {
+ "ldp": {
+ "sync": True,
},
},
},
@@ -1404,7 +1189,6 @@ class Ospfv2Template(NetworkTemplate):
re.VERBOSE,
),
"setval": _tmplt_ospf_mpls_traffic_eng,
- "compval": "traffic_eng",
"result": {
"processes": {
"{{ pid }}": {
@@ -1432,13 +1216,14 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "neighbor",
"getval": re.compile(
- r"""\s+neighbor
- \s(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<cost>cost\s\d+)*
- \s*(?P<db_filter>database-filter\sall\sout)*
- \s*(?P<poll>poll-interval\s\d+)*
- \s*(?P<priority>priority\s\d+)
- *$""",
+ r"""
+ \sneighbor
+ (\s(?P<address>\S+))
+ (\scost\s(?P<cost>\d+))
+ (\sdatabase-filter\sall\sout\s(?P<db_filter>))?
+ (\spoll-interval\s(?P<poll>\d+))?
+ (\spriority\s(?P<priority>\d+))?
+ $""",
re.VERBOSE,
),
"setval": _tmplt_ospf_neighbor,
@@ -1447,10 +1232,10 @@ class Ospfv2Template(NetworkTemplate):
"{{ pid }}": {
"neighbor": {
"address": "{{ address }}",
- "cost": "{{ cost.split(" ")[1] }}",
+ "cost": "{{ cost }}",
"database_filter": "{{ True if db_filter is defined }}",
- "poll_interval": "{{ poll.split(" ")[1] }}",
- "priority": "{{ priority.split(" ")[1] }}",
+ "poll_interval": "{{ poll }}",
+ "priority": "{{ priority }}",
},
},
},
@@ -1459,14 +1244,17 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "network",
"getval": re.compile(
- r"""\s+network
- \s(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<wildcard>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<area>area\s\S+)
- *$""",
+ r"""
+ \snetwork
+ (\s(?P<address>\S+))?
+ (\s(?P<wildcard>\S+))?
+ (\sarea\s(?P<area>\S+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_network,
+ "setval": "network"
+ "{{ (' ' + address + ' ' + wildcard_bits) if address is defined }}"
+ "{{ ' area ' + area if area is defined }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1474,7 +1262,7 @@ class Ospfv2Template(NetworkTemplate):
{
"address": "{{ address }}",
"wildcard_bits": "{{ wildcard }}",
- "area": "{{ area.split(" ")[1] }}",
+ "area": "{{ area }}",
},
],
},
@@ -1484,15 +1272,15 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "nsf.cisco",
"getval": re.compile(
- r"""\s+nsf
- \s(?P<cisco>cisco)*
- \s*(?P<helper>helper)*
- \s*(?P<disable>disable)
- *$""",
+ r"""
+ \snsf
+ (\s(?P<cisco>cisco))
+ (\s(?P<helper>helper))?
+ (\s(?P<disable>disable))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_nsf_cisco,
- "compval": "cisco",
+ "setval": "nsf cisco helper" "{{ ' disable' if nsf.cisco.disable }}",
"result": {
"processes": {
"{{ pid }}": {
@@ -1507,26 +1295,24 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "nsf.ietf",
+ "name": "nsf.ietf.disable",
"getval": re.compile(
- r"""\s+nsf
- \s(?P<ietf>ietf)*
- \s*(?P<helper>helper)*
- \s*(?P<disable>disable)*
- \s*(?P<strict>strict-lsa-checking)
- *$""",
+ r"""
+ \snsf
+ (\s(?P<ietf>ietf))
+ (\s(?P<helper>helper))
+ (\s(?P<disable>disable))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_nsf_ietf,
- "compval": "ietf",
+ "setval": "nsf ietf helper disable",
"result": {
"processes": {
"{{ pid }}": {
"nsf": {
"ietf": {
- "helper": "{{ True if helper is defined }}",
- "disable": "{{ True if disable is defined }}",
- "strict_lsa_checking": "{{ True if strict is defined }}",
+ "helper": True,
+ "disable": True,
},
},
},
@@ -1534,23 +1320,24 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "passive_interfaces",
+ "name": "nsf.ietf.strict_lsa_checking",
"getval": re.compile(
- r"""\s*(?P<no>no)*
- \s*passive-interface*
- \s*(?P<interface>\S+\s\S+|\S+)
- *$""",
+ r"""
+ \snsf
+ (\s(?P<ietf>ietf))
+ (\s(?P<helper>helper))
+ (\s(?P<strict>strict-lsa-checking))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_passive_interfaces,
+ "setval": "nsf ietf helper strict-lsa-checking",
"result": {
"processes": {
"{{ pid }}": {
- "passive_interfaces": {
- "default": "{{ True if 'default' in interface }}",
- "interface": {
- "set_interface": "{% if no is defined %}{{ False }}{% elif 'default' not in interface %}{{ True }}{% endif %}",
- "name": ["{{ interface if 'default' not in interface }}"],
+ "nsf": {
+ "ietf": {
+ "helper": "{{ True }}",
+ "strict_lsa_checking": True,
},
},
},
@@ -1558,21 +1345,55 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "passive_interface",
+ "name": "passive_interfaces.default",
"getval": re.compile(
- r"""\s+passive-interface
- \s(?P<interface>\S+\s\S+)
- *$""",
+ r"""
+ \spassive-interface
+ \s(?P<default_value>default)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "passive-interface" "{{ ' default' if passive_interfaces.default }}",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "passive_interfaces": {
+ "default": "{{ True if default_value is defined }}",
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "passive_interfaces.interface",
+ "getval": re.compile(
+ r"""
+ (\s(?P<no>no))?
+ \spassive-interface
+ \s(?P<interface>\S+)
+ $""",
re.VERBOSE,
),
- "setval": "passive-interface {{ passive_interface }}",
- "result": {"processes": {"{{ pid }}": {"passive_interface": "{{ interface }}"}}},
+ "setval": _tmplt_ospf_passive_interfaces,
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "passive_interfaces": {
+ "interface": {
+ "set_interface": "{{ not no }}",
+ "name": ["{{ interface if 'default' not in interface }}"],
+ },
+ },
+ },
+ },
+ },
},
{
"name": "prefix_suppression",
"getval": re.compile(
- r"""\s+(?P<prefix_sup>prefix-suppression)
- *$""",
+ r"""
+ \s(?P<prefix_sup>prefix-suppression)
+ $""",
re.VERBOSE,
),
"setval": "prefix-suppression",
@@ -1585,33 +1406,31 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "priority",
"getval": re.compile(
- r"""\s+priority
- \s(?P<priority>\d+)
- *$""",
+ r"""
+ \spriority
+ \s(?P<priority>\d+)
+ $""",
re.VERBOSE,
),
"setval": "priority {{ priority }}",
"result": {"processes": {"{{ pid }}": {"priority": "{{ priority }}"}}},
},
{
- "name": "queue_depth.hello",
+ "name": "queue_depth.hello.max_packets",
"getval": re.compile(
- r"""\s+queue-depth
- \shello*
- \s*(?P<max_packets>\d+)*
- \s*(?P<unlimited>unlimited)
- *$""",
+ r"""
+ \squeue-depth\shello
+ (\s(?P<max_packets>\d+))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_queue_depth_hello,
- "compval": "hello",
+ "setval": "queue-depth hello " "{{ queue_depth.hello.max_packets|string }}",
"result": {
"processes": {
"{{ pid }}": {
"queue_depth": {
"hello": {
"max_packets": "{{ max_packets }}",
- "unlimited": "{{ True if unlimited is defined }}",
},
},
},
@@ -1619,24 +1438,65 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "queue_depth.update",
+ "name": "queue_depth.hello.unlimited",
"getval": re.compile(
- r"""\s+queue-depth
- \supdate*
- \s*(?P<max_packets>\d+)*
- \s*(?P<unlimited>unlimited)
- *$""",
+ r"""
+ \squeue-depth\shello
+ (\s(?P<unlimited>unlimited))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_queue_depth_update,
- "compval": "update",
+ "setval": "queue-depth hello unlimited",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "queue_depth": {
+ "hello": {
+ "unlimited": True,
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "queue_depth.update.max_packets",
+ "getval": re.compile(
+ r"""
+ \squeue-depth\supdate
+ (\s(?P<max_packets>\d+))?
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "queue-depth update " "{{ queue_depth['update'].max_packets|string }}",
"result": {
"processes": {
"{{ pid }}": {
"queue_depth": {
"update": {
"max_packets": "{{ max_packets }}",
- "unlimited": "{{ True if unlimited is defined }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "queue_depth.update.unlimited",
+ "getval": re.compile(
+ r"""
+ \squeue-depth\supdate
+ (\s(?P<unlimited>unlimited))
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "queue-depth update unlimited",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "queue_depth": {
+ "update": {
+ "unlimited": True,
},
},
},
@@ -1646,9 +1506,10 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "router_id",
"getval": re.compile(
- r"""\s+router-id
- \s(?P<id>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})
- *$""",
+ r"""
+ \srouter-id
+ (\s(?P<id>\S+))?
+ $""",
re.VERBOSE,
),
"setval": "router-id {{ router_id }}",
@@ -1657,8 +1518,9 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "shutdown",
"getval": re.compile(
- r"""\s+(?P<shutdown>shutdown)
- *$""",
+ r"""
+ \s(?P<shutdown>shutdown)
+ $""",
re.VERBOSE,
),
"setval": "shutdown",
@@ -1667,27 +1529,53 @@ class Ospfv2Template(NetworkTemplate):
},
},
{
- "name": "summary_address",
+ "name": "summary_address.not_advertise",
"getval": re.compile(
- r"""\s+summary-address
- \s(?P<address>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<mask>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})*
- \s*(?P<not_adv>not-advertise)*
- \s*(?P<nssa>nssa-only)*
- \s*(?P<tag>tag\s\d+)
- *$""",
+ r"""
+ \ssummary-address
+ (\s(?P<address>\S+))
+ (\s(?P<mask>\S+))
+ (\s(?P<not_adv>not-advertise))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_summary_address,
+ "setval": "summary-address "
+ "{{ summary_address.address + ' ' + summary_address.mask }} not-advertise",
"result": {
"processes": {
"{{ pid }}": {
"summary_address": {
"address": "{{ address }}",
"mask": "{{ mask }}",
- "not_advertise": "{{ True if not_adv is defined }}",
- "nssa_only": "{{ True if nssa is defined }}",
- "tag": "{{ tag.split(" ")[1] }}",
+ "not_advertise": True,
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "summary_address.nssa_only",
+ "getval": re.compile(
+ r"""
+ \ssummary-address
+ (\s(?P<address>\S+))
+ (\s(?P<mask>\S+))
+ (\s(?P<nssa>nssa-only))
+ (\stag\s(?P<tag>\d+))?
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "summary-address "
+ "{{ summary_address.address + ' ' + summary_address.mask }} nssa-only"
+ "{{ ' tag ' + summary_address.tag|string if summary_address.tag is defined else '' }}",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "summary_address": {
+ "address": "{{ address }}",
+ "mask": "{{ mask }}",
+ "nssa_only": True,
+ "tag": "{{ tag }}",
},
},
},
@@ -1696,38 +1584,80 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "timers.lsa",
"getval": re.compile(
- r"""\s+timers
- \slsa
- \sarrival
- \s(?P<lsa>\d+)
- *$""",
+ r"""
+ \stimers
+ \slsa
+ \sarrival
+ (\s(?P<lsa>\d+))?
+ $""",
re.VERBOSE,
),
"setval": "timers lsa arrival {{ timers.lsa }}",
- "compval": "lsa",
"result": {"processes": {"{{ pid }}": {"timers": {"lsa": "{{ lsa }}"}}}},
},
{
- "name": "timers.pacing",
+ "name": "timers.pacing.flood",
"getval": re.compile(
- r"""\s+timers
- \spacing
- \s(?P<flood>flood\s\d+)*
- \s*(?P<lsa_group>lsa-group\s\d+)*
- \s*(?P<retransmission>retransmission\s\d+)
- *$""",
+ r"""
+ \stimers\spacing
+ (\sflood\s(?P<flood>\d+))
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "timers pacing"
+ "{{ ' flood ' + timers.pacing.flood|string if timers.pacing.flood is defined else '' }}",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "timers": {
+ "pacing": {
+ "flood": "{{ flood }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "timers.pacing.lsa_group",
+ "getval": re.compile(
+ r"""
+ \stimers\spacing
+ (\slsa-group\s(?P<lsa_group>\d+))
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_timers_pacing,
- "compval": "pacing",
+ "setval": "timers pacing"
+ "{{ ' lsa-group ' + timers.pacing.lsa_group|string if timers.pacing.lsa_group is defined else '' }}",
"result": {
"processes": {
"{{ pid }}": {
"timers": {
"pacing": {
- "flood": "{{ flood.split(" ")[1] }}",
- "lsa_group": "{{ lsa_group.split(" ")[1] }}",
- "retransmission": "{{ retransmission.split(" ")[1] }}",
+ "lsa_group": "{{ lsa_group }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "timers.pacing.retransmission",
+ "getval": re.compile(
+ r"""
+ \stimers\spacing
+ (\sretransmission\s(?P<retransmission>\d+))?
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "timers pacing"
+ "{{ ' retransmission ' + timers.pacing.retransmission|string if timers.pacing.retransmission is defined else '' }}",
+ "result": {
+ "processes": {
+ "{{ pid }}": {
+ "timers": {
+ "pacing": {
+ "retransmission": "{{ retransmission }}",
},
},
},
@@ -1737,17 +1667,16 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "timers.throttle.lsa",
"getval": re.compile(
- r"""\s+timers
- \sthrottle
- \s*(?P<lsa>lsa)*
- \s*(?P<first_delay>\d+)*
- \s*(?P<min_delay>\d+)*
- \s*(?P<max_delay>\d+)
- *$""",
+ r"""
+ \stimers\sthrottle
+ (\s(?P<lsa>lsa))?
+ (\s(?P<first_delay>\d+))?
+ (\s(?P<min_delay>\d+))?
+ (\s(?P<max_delay>\d+))?
+ $""",
re.VERBOSE,
),
"setval": "timers throttle lsa {{ throttle.lsa.first_delay }} {{ throttle.lsa.min_delay }} {{ throttle.lsa.max_delay }}",
- "compval": "throttle.lsa",
"result": {
"processes": {
"{{ pid }}": {
@@ -1767,17 +1696,16 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "timers.throttle.spf",
"getval": re.compile(
- r"""\s+timers
- \sthrottle
- \s*(?P<spf>spf)*
- \s*(?P<first_delay>\d+)*
- \s*(?P<min_delay>\d+)*
- \s*(?P<max_delay>\d+)
- *$""",
+ r"""
+ \stimers\sthrottle
+ (\s(?P<spf>spf))?
+ (\s(?P<first_delay>\d+))?
+ (\s(?P<min_delay>\d+))?
+ (\s(?P<max_delay>\d+))?
+ $""",
re.VERBOSE,
),
"setval": "timers throttle spf {{ throttle.spf.receive_delay }} {{ throttle.spf.between_delay }} {{ throttle.spf.max_delay }}",
- "compval": "throttle.spf",
"result": {
"processes": {
"{{ pid }}": {
@@ -1797,8 +1725,9 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "traffic_share",
"getval": re.compile(
- r"""\s+(?P<traffic>traffic-share\smin\sacross-interfaces)
- *$""",
+ r"""
+ \s(?P<traffic>traffic-share\smin\sacross-interfaces)
+ $""",
re.VERBOSE,
),
"setval": "traffic-share min across-interfaces",
@@ -1809,19 +1738,21 @@ class Ospfv2Template(NetworkTemplate):
{
"name": "ttl_security",
"getval": re.compile(
- r"""\s+ttl-security
- \s(?P<interfaces>all-interfaces)*
- \s*(?P<hops>hops\s\d+)
- *$""",
+ r"""
+ \sttl-security
+ (\s(?P<interfaces>all-interfaces))?
+ (\shops\s(?P<hops>\d+))?
+ $""",
re.VERBOSE,
),
- "setval": _tmplt_ospf_ttl_security,
+ "setval": "ttl-security all-interfaces"
+ "{{ ' hops ' + ttl_security.hops|string if ttl_security.hops is defined }}",
"result": {
"processes": {
"{{ pid }}": {
"ttl_security": {
"set": "{{ True if interfaces is defined and hops is undefined }}",
- "hops": "{{ hops.split(" ")[1] }}",
+ "hops": "{{ hops }}",
},
},
},
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv3.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv3.py
index 874eed614..1dbe0fc94 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv3.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ospfv3.py
@@ -81,11 +81,11 @@ def _tmplt_ospf_area_nssa(config_data):
command += " default-information-originate"
if "metric" in config_data["nssa"]["default_information_originate"]:
command += " metric {metric}".format(
- **config_data["nssa"]["default_information_originate"]
+ **config_data["nssa"]["default_information_originate"],
)
if "metric_type" in config_data["nssa"]["default_information_originate"]:
command += " metric-type {metric_type}".format(
- **config_data["nssa"]["default_information_originate"]
+ **config_data["nssa"]["default_information_originate"],
)
if "nssa_only" in config_data["nssa"]["default_information_originate"]:
command += " nssa-only"
@@ -150,7 +150,7 @@ def _tmplt_ospf_auto_cost(config_data):
command = "auto-cost"
if "reference_bandwidth" in config_data["auto_cost"]:
command += " reference-bandwidth {reference_bandwidth}".format(
- **config_data["auto_cost"]
+ **config_data["auto_cost"],
)
return command
@@ -210,7 +210,7 @@ def _tmplt_ospf_distance_admin_distance(config_data):
command = "distance {distance}".format(**config_data["distance"]["admin_distance"])
if "address" in config_data["distance"]["admin_distance"]:
command += " {address} {wildcard_bits}".format(
- **config_data["distance"]["admin_distance"]
+ **config_data["distance"]["admin_distance"],
)
if "acl" in config_data["distance"]["admin_distance"]:
command += " {acl}".format(**config_data["distance"]["admin_distance"])
@@ -395,17 +395,17 @@ def _tmplt_ospf_mpls_traffic_eng(config_data):
command += " area {area}".format(**config_data["mpls"]["traffic_eng"])
elif "autoroute_exclude" in config_data["mpls"]["traffic_eng"]:
command += " autoroute-exclude prefix-list {autoroute_exclude}".format(
- **config_data["mpls"]["traffic_eng"]
+ **config_data["mpls"]["traffic_eng"],
)
elif "interface" in config_data["mpls"]["traffic_eng"]:
command += " interface {int_type}".format(
- **config_data["mpls"]["traffic_eng"]["interface"]
+ **config_data["mpls"]["traffic_eng"]["interface"],
)
if "area" in config_data["mpls"]["traffic_eng"]["interface"]:
command += " area {area}".format(**config_data["mpls"]["traffic_eng"]["interface"])
elif "mesh_group" in config_data["mpls"]["traffic_eng"]:
command += " mesh-group {id} {interface}".format(
- **config_data["mpls"]["traffic_eng"]["mesh_group"]
+ **config_data["mpls"]["traffic_eng"]["mesh_group"],
)
if "area" in config_data["mpls"]["traffic_eng"]["mesh_group"]:
command += " area {area}".format(**config_data["mpls"]["traffic_eng"]["mesh_group"])
@@ -413,7 +413,7 @@ def _tmplt_ospf_mpls_traffic_eng(config_data):
command += " multicast-intact"
elif "router_id_interface" in config_data["mpls"]["traffic_eng"]:
command += " router-id {router_id_interface}".format(
- **config_data["mpls"]["traffic_eng"]
+ **config_data["mpls"]["traffic_eng"],
)
return command
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ping.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ping.py
index d7f375b71..1b7bde1ae 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ping.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/ping.py
@@ -47,6 +47,7 @@ class PingTemplate(NetworkTemplate):
"{{ (' repeat ' + count|string ) if count is defined else '' }}"
"{{ (' df-bit' ) if df_bit|d(False) else '' }}"
"{{ (' timeout ' + timeout|string) if timeout is defined else '' }}"
+ "{{ (' size ' + size|string) if size is defined else '' }}"
"{{ (' ingress ' + ingress) if ingress is defined else '' }}"
"{{ (' egress ' + egress) if egress is defined else '' }}"
"{{ (' source ' + source) if source is defined else '' }}",
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/prefix_lists.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/prefix_lists.py
index 041d926f5..43d163c5d 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/prefix_lists.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/prefix_lists.py
@@ -22,66 +22,66 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.r
)
-def _tmplt_set_prefix_lists(config_data):
- if "prefix_list" in config_data:
- if config_data.get("afi") == "ipv4":
- config_data["afi"] = "ip"
- cmd = "{afi} prefix-list {name}".format(**config_data)
- if config_data.get("prefix_list"):
- if config_data["prefix_list"].get("description"):
- cmd += " description {description}".format(**config_data["prefix_list"])
- else:
- cmd += " seq {sequence} {action} {prefix}".format(**config_data["prefix_list"])
- if config_data["prefix_list"].get("ge"):
- cmd += " ge {ge}".format(**config_data["prefix_list"])
- if config_data["prefix_list"].get("le"):
- cmd += " le {le}".format(**config_data["prefix_list"])
- return cmd
-
-
class Prefix_listsTemplate(NetworkTemplate):
def __init__(self, lines=None):
super(Prefix_listsTemplate, self).__init__(lines=lines, tmplt=self)
PARSERS = [
{
- "name": "prefix_list",
+ "name": "entry",
"getval": re.compile(
r"""
- ^(?P<afi>ip|ipv6)*
- \s*prefix-list*
- \s*(?P<name>\S+)*
- \s*(?P<description>description\s\S.*)*
- \s*(?P<sequence>seq\s\S+)*
- \s*(?P<action>deny|permit)*
- \s*(?P<prefix>(?:[0-9]{1,3}\.){3}[0-9]{1,3}/\d+|(([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}/\d+))*
- \s*(?P<ge>ge\s\d+)*
- \s*(?P<le>le\s\d+)*
+ ^(?P<afi>ip|ipv6)\sprefix-list
+ (\s(?P<name>\S+))
+ (\sseq\s(?P<sequence>\d+))?
+ (\s(?P<action>deny|permit))?
+ (\s(?P<prefix>\S+))?
+ (\sge\s(?P<ge>\d+))?
+ (\sle\s(?P<le>\d+))?
$""",
re.VERBOSE,
),
- "setval": _tmplt_set_prefix_lists,
+ "setval": "{{ 'ip' if afi == 'ipv4' else afi }} prefix-list {{ name }}"
+ "{{ (' seq ' + sequence|string) if sequence|d('') else '' }}"
+ " {{ action }}"
+ " {{ prefix }}"
+ "{{ (' ge ' + ge|string) if ge|d('') else '' }}"
+ "{{ (' le ' + le|string) if le|d('') else '' }}",
+ "shared": True,
"result": {
- "{{ afi + '_' + name }}": {
+ "{{ afi + name }}": {
"afi": "{{ 'ipv4' if afi is defined and afi=='ip' else 'ipv6' }}",
- "prefix_lists": [
+ "name": "{{ name }}",
+ "entries": [
{
- "name": "{{ name if name is defined }}",
- "description": "{{ description.split('description ')[1] if description is defined }}",
- "entries": {
- # Description at this level is deprecated, should be removed when we plan to remove the
- # Description from entries level
- "description": "{{ description.split('description ')[1] if description is defined }}",
- "sequence": "{{ sequence.split(' ')[1] if sequence is defined }}",
- "action": "{{ action if action is defined }}",
- "prefix": "{{ prefix if prefix is defined }}",
- "ge": "{{ ge.split(' ')[1] if ge is defined }}",
- "le": "{{ le.split(' ')[1] if le is defined }}",
- },
+ "sequence": "{{ sequence }}",
+ "action": "{{ action }}",
+ "prefix": "{{ prefix }}",
+ "ge": "{{ ge }}",
+ "le": "{{ le }}",
},
],
},
},
+ },
+ {
+ "name": "description",
+ "getval": re.compile(
+ r"""
+ ^(?P<afi>ip|ipv6)\sprefix-list
+ (\s(?P<name>\S+))
+ (\sdescription\s(?P<description>.+$))?
+ """,
+ re.VERBOSE,
+ ),
+ "setval": "{{ 'ip' if afi == 'ipv4' else afi }} prefix-list {{ name }} description {{ description }}",
"shared": True,
+ "result": {
+ "{{ afi + name }}": {
+ "name": "{{ name }}",
+ "afi": "{{ 'ipv4' if afi is defined and afi=='ip' else 'ipv6' }}",
+ "description": "{{ description }}",
+ },
+ },
},
]
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/route_maps.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/route_maps.py
index 47b4402b6..1e569ccca 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/route_maps.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/route_maps.py
@@ -41,11 +41,11 @@ def _tmplt_route_map_match(config_data):
cmd += " best-range"
if config_data["match"]["additional_paths"]["best_range"].get("lower_limit"):
cmd += " lower-limit {lower_limit}".format(
- **config_data["match"]["additional_paths"]["best_range"]
+ **config_data["match"]["additional_paths"]["best_range"],
)
if config_data["match"]["additional_paths"]["best_range"].get("upper_limit"):
cmd += " upper-limit {upper_limit}".format(
- **config_data["match"]["additional_paths"]["best_range"]
+ **config_data["match"]["additional_paths"]["best_range"],
)
if config_data["match"]["additional_paths"].get("group_best"):
cmd += " group-best"
@@ -294,7 +294,7 @@ def _tmplt_route_map_match_ipv6(config_data):
cmd += " address"
if config_data["match"]["ipv6"]["address"].get("prefix_list"):
cmd += " prefix-list {prefix_list}".format(
- **config_data["match"]["ipv6"]["address"]
+ **config_data["match"]["ipv6"]["address"],
)
elif config_data["match"]["ipv6"]["address"].get("acl"):
cmd += " {acl}".format(**config_data["match"]["ipv6"]["address"])
@@ -306,7 +306,7 @@ def _tmplt_route_map_match_ipv6(config_data):
cmd += " src-pfx"
if config_data["match"]["ipv6"]["flowspec"].get("prefix_list"):
cmd += " prefix-list {prefix_list}".format(
- **config_data["match"]["ipv6"]["flowspec"]
+ **config_data["match"]["ipv6"]["flowspec"],
)
elif config_data["match"]["ipv6"]["flowspec"].get("acl"):
cmd += " {acl}".format(**config_data["match"]["ipv6"]["flowspec"])
@@ -314,7 +314,7 @@ def _tmplt_route_map_match_ipv6(config_data):
cmd += " next-hop"
if config_data["match"]["ipv6"]["next_hop"].get("prefix_list"):
cmd += " prefix-list {prefix_list}".format(
- **config_data["match"]["ipv6"]["next_hop"]
+ **config_data["match"]["ipv6"]["next_hop"],
)
elif config_data["match"]["ipv6"]["next_hop"].get("acl"):
cmd += " {acl}".format(**config_data["match"]["ipv6"]["next_hop"])
@@ -322,7 +322,7 @@ def _tmplt_route_map_match_ipv6(config_data):
cmd += " route-source"
if config_data["match"]["ipv6"]["route_source"].get("prefix_list"):
cmd += " prefix-list {prefix_list}".format(
- **config_data["match"]["ipv6"]["route_source"]
+ **config_data["match"]["ipv6"]["route_source"],
)
elif config_data["match"]["ipv6"]["route_source"].get("acl"):
cmd += " {acl}".format(**config_data["match"]["ipv6"]["route_source"])
@@ -380,7 +380,7 @@ def _tmplt_route_map_set(config_data):
if set.get("dampening"):
command.append(
"set dampening {penalty_half_time} {reuse_route_val} {suppress_route_val} {max_suppress}".format(
- **set["dampening"]
+ **set["dampening"],
),
)
if set.get("default"):
@@ -403,7 +403,7 @@ def _tmplt_route_map_set(config_data):
cmd = "set extcommunity rt"
if set["extcommunity"]["rt"].get("range"):
cmd += " range {lower_limit} {upper_limit}".format(
- **set["extcommunity"]["rt"]["range"]
+ **set["extcommunity"]["rt"]["range"],
)
elif set["extcommunity"]["rt"].get("address"):
cmd += " {address}".format(**set["extcommunity"]["rt"])
@@ -416,7 +416,7 @@ def _tmplt_route_map_set(config_data):
cmd = "set extcommunity vpn-distinguisher"
if set["extcommunity"]["vpn_distinguisher"].get("range"):
cmd += " range {lower_limit} {upper_limit}".format(
- **set["extcommunity"]["vpn_distinguisher"]["range"]
+ **set["extcommunity"]["vpn_distinguisher"]["range"],
)
elif set["extcommunity"]["vpn_distinguisher"].get("address"):
cmd += " {address}".format(**set["extcommunity"]["vpn_distinguisher"])
@@ -454,13 +454,13 @@ def _tmplt_route_map_set(config_data):
if set["metric"]["deviation"] == "plus":
cmd += (
" +{eigrp_delay} {metric_reliability} {metric_bandwidth} {mtu}".format(
- **set["metric"]
+ **set["metric"],
)
)
elif set["metric"]["deviation"] == "minus":
cmd += (
" -{eigrp_delay} {metric_reliability} {metric_bandwidth} {mtu}".format(
- **set["metric"]
+ **set["metric"],
)
)
if set["metric"].get("deviation") and not set["metric"].get("eigrp_delay"):
@@ -512,7 +512,7 @@ def _tmplt_route_map_set_ip(config_data):
cmd += " global next-hop"
if set_ip["global_route"].get("verify_availability"):
cmd += " verify-availability {address} {sequence} track {track}".format(
- **set_ip["global_route"]["verify_availability"]
+ **set_ip["global_route"]["verify_availability"],
)
elif set_ip["global_route"].get("address"):
cmd += " {address}".format(**set_ip["global_route"])
@@ -543,7 +543,8 @@ def _tmplt_route_map_set_ip(config_data):
if set_ip["next_hop"].get("verify_availability"):
command.append(
"{0} verify-availability {address} {sequence} track {track}".format(
- cmd, **set_ip["next_hop"]["verify_availability"]
+ cmd,
+ **set_ip["next_hop"]["verify_availability"],
),
)
if set_ip.get("precedence"):
@@ -584,7 +585,7 @@ def _tmplt_route_map_set_ip(config_data):
cmd += " vrf {vrf} next-hop".format(**set_ip)
if set_ip["vrf"].get("verify_availability").get("address"):
cmd += " verify-availability {address} {sequence} track {track}".format(
- **set_ip["vrf"]["verify_availability"]
+ **set_ip["vrf"]["verify_availability"],
)
elif set_ip["vrf"].get("address"):
cmd += " {address}".format(**set_ip["vrf"])
@@ -604,7 +605,7 @@ def _tmplt_route_map_set_ipv6(config_data):
cmd += " global next-hop"
if set_ipv6["global_route"].get("verify_availability"):
cmd += " verify-availability {address} {sequence} track {track}".format(
- **set_ipv6["global_route"]["verify_availability"]
+ **set_ipv6["global_route"]["verify_availability"],
)
elif set_ipv6["global_route"].get("address"):
cmd += " {address}".format(**set_ipv6["global_route"])
@@ -621,7 +622,7 @@ def _tmplt_route_map_set_ipv6(config_data):
if set_ipv6.get("vrf"):
cmd += (
" vrf {vrf} next-hop verify-availability {address} {sequence} track {track}".format(
- **set_ipv6["vrf"]["verify_availability"]
+ **set_ipv6["vrf"]["verify_availability"],
)
)
return cmd
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/snmp_server.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/snmp_server.py
index 87f9e7c07..5107612eb 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/snmp_server.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/snmp_server.py
@@ -85,8 +85,6 @@ def cmd_option_trap_bgp(config_data):
if conf:
if conf.get("enable"):
cmd += "snmp-server enable traps bgp"
- if conf.get("cbgp2"):
- cmd += " cbgp2"
if conf.get("state_changes"):
if conf.get("state_changes").get("enable"):
cmd += " state-changes"
@@ -281,6 +279,7 @@ class Snmp_serverTemplate(NetworkTemplate):
(\s(?P<version>v1|v3|v2c))?
(\s(?P<version_option>auth|noauth|priv))?
(\scontext\s(?P<context>\S+))?
+ (\smatch\s(?P<match>\S+))?
(\sread\s(?P<read>\S+))?
(\swrite\s(?P<write>\S+))?
(\snotify\s(?P<notify>\S+))?
@@ -293,6 +292,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"{{ (' ' + version) if version is defined else '' }}"
"{{ (' ' + version_option) if version_option is defined else '' }}"
"{{ (' context ' + context) if context is defined else '' }}"
+ "{{ (' match ' + match) if match is defined else '' }}"
"{{ (' read ' + read) if read is defined else '' }}"
"{{ (' write ' + write) if write is defined else '' }}"
"{{ (' notify ' + notify) if notify is defined else '' }}"
@@ -305,6 +305,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"version": "{{ version }}",
"version_option": "{{ version_option }}",
"context": "{{ context }}",
+ "match": "{{ match }}",
"notify": "{{ notify }}",
"read": "{{ read }}",
"write": "{{ write }}",
@@ -396,7 +397,7 @@ class Snmp_serverTemplate(NetworkTemplate):
(\sremote\s(?P<remote>\S+))?
(\sudp-port\s(?P<udp_port>\d+))?
(\s(?P<version>v1|v3|v2c))?
- (\s(?P<version_option>auth|encrypted))?
+ (\s(?P<version_option>encrypted))?
(\saccess\sipv6\s(?P<acl_v6>\S+))?
(\saccess\s(?P<acl_v4>\S+|\d+))?
(\svrf\s(?P<vrf>\S+))?
@@ -409,13 +410,17 @@ class Snmp_serverTemplate(NetworkTemplate):
"{{ (' udp-port ' + udp_port|string) if udp_port is defined else '' }}"
"{{ (' ' + version) if version is defined else '' }}"
"{{ (' ' + version_option) if version_option is defined else '' }}"
- "{{ (' auth ' + authentication.algorithm) if authentication is defined and authentication.algorithm is defined else '' }}"
- "{{ (' ' + authentication.password) if authentication is defined and authentication.password is defined else '' }}"
- "{{ (' priv ' + encryption.priv) if encryption is defined and encryption.priv is defined else '' }}"
- "{{ (' ' + encryption.priv_option) if encryption is defined and encryption.priv_option is defined else '' }}"
- "{{ (' ' + encryption.password) if encryption is defined and encryption.password is defined else '' }}"
- "{{ (' access ' + acl_v4|string) if acl_v4 is defined else '' }}"
- "{{ (' access ipv6 ' + acl_v6) if acl_v6 is defined else '' }}"
+ "{% if authentication is defined and 'algorithm' in authentication and 'password' in authentication %}"
+ "{{ (' auth ' + authentication.algorithm + ' ' + authentication.password) }}"
+ "{% if encryption is defined and 'priv' in encryption and 'password' in encryption %}"
+ "{{ (' priv ' + encryption.priv) }}"
+ "{{ (' ' + encryption.priv_option) if 'priv_option' in encryption else '' }}"
+ "{{ (' ' + encryption.password) }}"
+ "{% endif %}"
+ "{% endif %}"
+ "{{ (' access') if acl_v6 is defined or acl_v4 is defined else '' }}"
+ "{{ (' ipv6 ' + acl_v6) if acl_v6 is defined else '' }}"
+ "{{ (' ' + acl_v4|string) if acl_v4 is defined else '' }}"
"{{ (' vrf ' + vrf) if vrf is defined else '' }}",
"result": {
"users": [
@@ -464,7 +469,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"name": "if_index",
"getval": re.compile(
r"""
- ^snmp-server\sifindex
+ ^snmp(-server|\sifmib)\sifindex
(\s(?P<if_index>persist))?
""", re.VERBOSE,
),
@@ -501,7 +506,7 @@ class Snmp_serverTemplate(NetworkTemplate):
r"""
^snmp-server\sip\sdscp
(\s(?P<dscp>\d+))?
- (\sprecedence(?P<precedence>\d+))?
+ (\sprecedence\s(?P<precedence>\d+))?
""", re.VERBOSE,
),
"setval": "snmp-server ip dscp "
@@ -605,8 +610,22 @@ class Snmp_serverTemplate(NetworkTemplate):
"trap_source": "{{ interface }}",
},
},
-
- { # only traps
+ # only traps
+ {
+ "name": "traps.aaa_server",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\saaa_server
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps aaa_server",
+ "result": {
+ "traps": {
+ "aaa_server": True,
+ },
+ },
+ },
+ {
"name": "traps.auth_framework",
"getval": re.compile(
r"""
@@ -614,14 +633,13 @@ class Snmp_serverTemplate(NetworkTemplate):
(\s(?P<sec_violation>sec-violation))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps"
- "{{ (' auth-framework') if traps.auth_framework.enable is defined else '' }}"
- "{{ (' sec-violation') if traps.auth_framework.sec_violation is defined else '' }}",
+ "setval": "snmp-server enable traps auth-framework"
+ "{{ (' sec-violation') if traps.auth_framework.sec_violation|d(False) is defined else '' }}",
"result": {
"traps": {
"auth_framework": {
"enable": True,
- "sec_violation": "{{ not not excluded }}",
+ "sec_violation": "{{ not not sec_violation }}",
},
},
},
@@ -653,12 +671,11 @@ class Snmp_serverTemplate(NetworkTemplate):
"getval": re.compile(
r"""
^snmp-server\senable\straps\sbgp
- (\s(?P<cbgp2>cbgp2))?
(\s(?P<state_changes>state-changes))?
(\s(?P<all>all))?
(\s(?P<backward_trans>backward-trans))?
(\s(?P<limited>limited))?
- (\sthreshold(?P<prefix>prefix))?
+ (\sthreshold(?P<prefix>prefix))?\s*$
""", re.VERBOSE,
),
"setval": cmd_option_trap_bgp,
@@ -666,7 +683,6 @@ class Snmp_serverTemplate(NetworkTemplate):
"result": {
"traps": {
"bgp": {
- "cbgp2": "{{ not not cbgp2 }}",
"enable": True,
"state_changes": {
"enable": "{{ not not state_changes }}",
@@ -682,6 +698,22 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.bgp.cbgp2",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sbgp\scbgp2
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps bgp cbgp2",
+ "result": {
+ "traps": {
+ "bgp": {
+ "cbgp2": True,
+ },
+ },
+ },
+ },
+ {
"name": "traps.bridge",
"getval": re.compile(
r"""
@@ -704,6 +736,50 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.bulkstat",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sbulkstat
+ (\s(?P<collection>collection))?
+ (\s(?P<transfer>transfer))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps bulkstat"
+ "{{ ' collection' if traps.bulkstat.collection|d(False) else '' }}"
+ "{{ ' transfer' if traps.bulkstat.transfer|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "bulkstat": {
+ "enable": True,
+ "collection": "{{ not not collection }}",
+ "transfer": "{{ not not transfer }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.call_home",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\scall-home
+ (\s(?P<message_send_fail>message-send-fail))?
+ (\s(?P<server_fail>server-fail))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps call-home"
+ "{{ ' message-send-fail' if traps.call_home.message_send_fail|d(False) else '' }}"
+ "{{ ' server-fail' if traps.call_home.server_fail|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "call_home": {
+ "enable": True,
+ "message_send_fail": "{{ not not message_send_fail }}",
+ "server_fail": "{{ not not server_fail }}",
+ },
+ },
+ },
+ },
+ {
"name": "traps.casa",
"getval": re.compile(
r"""
@@ -718,44 +794,58 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.cnpd",
+ "name": "traps.cef",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\scnpd
+ ^snmp-server\senable\straps\scef
+ (\s(?P<resource_failure>resource-failure))?
+ (\s(?P<peer_state_change>peer-state-change))?
+ (\s(?P<peer_fib_state_change>peer-fib-state-change))?
+ (\s(?P<inconsistency>inconsistency))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps cnpd",
+ "setval": "snmp-server enable traps cef"
+ "{{ ' resource-failure' if traps.cef.resource_failure|d(False) else '' }}"
+ "{{ ' peer-state-change' if traps.cef.peer_state_change|d(False) else '' }}"
+ "{{ ' peer-fib-state-change' if traps.cef.peer_fib_state_change|d(False) else '' }}"
+ "{{ ' inconsistency' if traps.cef.inconsistency|d(False) else '' }}",
"result": {
"traps": {
- "cnpd": True,
+ "cef": {
+ "enable": True,
+ "inconsistency": "{{ not not inconsistency }}",
+ "peer_fib_state_change": "{{ not not peer_fib_state_change }}",
+ "peer_state_change": "{{ not not peer_state_change }}",
+ "resource_failure": "{{ not not resource_failure }}",
+ },
},
},
},
{
- "name": "traps.config",
+ "name": "traps.cnpd",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sconfig
+ ^snmp-server\senable\straps\scnpd
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps config",
+ "setval": "snmp-server enable traps cnpd",
"result": {
"traps": {
- "config": True,
+ "cnpd": True,
},
},
},
{
- "name": "traps.isis",
+ "name": "traps.config",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sisis$
+ ^snmp-server\senable\straps\sconfig\s*$
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps isis",
+ "setval": "snmp-server enable traps config",
"result": {
"traps": {
- "isis": True,
+ "config": True,
},
},
},
@@ -763,7 +853,7 @@ class Snmp_serverTemplate(NetworkTemplate):
"name": "traps.config_copy",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sconfig-copy
+ ^snmp-server\senable\straps\s(config-copy|copy-config)
""", re.VERBOSE,
),
"setval": "snmp-server enable traps config-copy",
@@ -788,6 +878,26 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.cpu",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\scpu
+ ((?P<threshold_old>_threshold))?
+ (\s(?P<threshold>threshold))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps cpu"
+ "{{ ' threshold' if traps.cpu.threshold|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "cpu": {
+ "enable": True,
+ "threshold": "{{ not not threshold or not not threshold_old }}",
+ },
+ },
+ },
+ },
+ {
"name": "traps.dhcp",
"getval": re.compile(
r"""
@@ -802,6 +912,28 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.dlsw",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sdlsw
+ (\s(?P<circuit>circuit))?
+ (\s(?P<tconn>tconn))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps dlsw"
+ "{{ ' circuit' if traps.dlsw.circuit|d(False) else '' }}"
+ "{{ ' tconn' if traps.dlsw.tconn|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "dlsw": {
+ "enable": True,
+ "circuit": "{{ not not circuit }}",
+ "tconn": "{{ not not tconn }}",
+ },
+ },
+ },
+ },
+ {
"name": "traps.eigrp",
"getval": re.compile(
r"""
@@ -816,10 +948,24 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.energywise",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\senergywise$
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps energywise",
+ "result": {
+ "traps": {
+ "energywise": True,
+ },
+ },
+ },
+ {
"name": "traps.entity",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sentity
+ ^snmp-server\senable\straps\sentity\s*$
""", re.VERBOSE,
),
"setval": "snmp-server enable traps entity",
@@ -830,16 +976,228 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.energywise",
+ "name": "traps.entity_diag",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senergywise$
+ ^snmp-server\senable\straps\sentity-diag
+ (\s(?P<boot_up_fail>boot-up-fail))?
+ (\s(?P<hm_test_recover>hm-test-recover))?
+ (\s(?P<hm_thresh_reached>hm-thresh-reached))?
+ (\s(?P<scheduled_test_fail>scheduled-test-fail))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps energywise",
+ "setval": "snmp-server enable traps entity-diag"
+ "{{ ' boot-up-fail' if traps.entity_diag.boot_up_fail|d(False) else '' }}"
+ "{{ ' hm-test-recover' if traps.entity_diag.hm_test_recover|d(False) else '' }}"
+ "{{ ' hm-thresh-reached' if traps.entity_diag.hm_thresh_reached|d(False) else '' }}"
+ "{{ ' scheduled-test-fail' if traps.entity_diag.scheduled_test_fail|d(False) else '' }}",
"result": {
"traps": {
- "energywise": True,
+ "entity_diag": {
+ "enable": True,
+ "boot_up_fail": "{{ not not boot_up_fail }}",
+ "hm_test_recover": "{{ not not hm_test_recover }}",
+ "hm_thresh_reached": "{{ not not hm_thresh_reached }}",
+ "scheduled_test_fail": "{{ not not scheduled_test_fail }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.entity_perf",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sentity-perf
+ (\s(?P<throughput_notif>throughput-notif))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps entity-perf"
+ "{{ ' throughput-notif' if traps.entity_perf.throughput_notif|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "entity_perf": {
+ "enable": True,
+ "throughput_notif": "{{ not not throughput_notif }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.entity_state",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sentity-state
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps entity-state",
+ "result": {
+ "traps": {
+ "entity_state": True,
+ },
+ },
+ },
+ {
+ "name": "traps.envmon",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\senvmon
+ (\s(?P<fan>fan))?
+ (\s(?P<shutdown>shutdown))?
+ (\s(?P<supply>supply))?
+ (\s(?P<temperature>temperature))?
+ (\s(?P<status>status))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps envmon"
+ "{{ ' fan' if traps.envmon.fan_enable|d(False) else '' }}"
+ "{{ ' shutdown' if traps.envmon.shutdown|d(False) else '' }}"
+ "{{ ' supply' if traps.envmon.supply|d(False) else '' }}"
+ "{{ ' temperature' if traps.envmon.temperature|d(False) else '' }}"
+ "{{ ' status' if traps.envmon.status|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "envmon": {
+ "enable": True,
+ "fan_enable": "{{ True if fan else False }}",
+ "shutdown": "{{ True if shutdown else False }}",
+ "supply": "{{ True if supply else False }}",
+ "temperature": "{{ True if temperature else False }}",
+ "status": "{{ True if status else False }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.errdisable",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\serrdisable
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps errdisable",
+ "result": {
+ "traps": {
+ "errdisable": True,
+ },
+ },
+ },
+ {
+ "name": "traps.ether_oam",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sether-oam
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps ether-oam",
+ "result": {
+ "traps": {
+ "ether_oam": True,
+ },
+ },
+ },
+ {
+ "name": "traps.ethernet.cfm.alarm",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sethernet\scfm\salarm
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps ethernet cfm alarm",
+ "result": {
+ "traps": {
+ "ethernet": {
+ "cfm": {
+ "alarm": True,
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.ethernet.cfm.cc",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sethernet\scfm\scc
+ (\s(?P<mep_up>mep-up))?
+ (\s(?P<mep_down>mep-down))?
+ (\s(?P<cross_connect>cross-connect))?
+ (\s(?P<loop>loop))?
+ (\s(?P<config>config))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps ethernet cfm cc"
+ "{{ ' mep-up' if traps.ethernet.cfm.cc.mep_up|d(False) else ''}}"
+ "{{ ' mep-down' if traps.ethernet.cfm.cc.mep_down|d(False) else ''}}"
+ "{{ ' cross-connect' if traps.ethernet.cfm.cc.cross_connect|d(False) else ''}}"
+ "{{ ' loop' if traps.ethernet.cfm.cc.loop|d(False) else ''}}"
+ "{{ ' config' if traps.ethernet.cfm.cc.config|d(False) else ''}}",
+ "result": {
+ "traps": {
+ "ethernet": {
+ "cfm": {
+ "cc": {
+ "mep_up": "{{ not not mep_up }}",
+ "mep_down": "{{ not not mep_down }}",
+ "cross_connect": "{{ not not cross_connect }}",
+ "loop": "{{ not not loop }}",
+ "config": "{{ not not config }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.ethernet.cfm.crosscheck",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sethernet\scfm\scrosscheck
+ (\s(?P<mep_missing>mep-missing))?
+ (\s(?P<mep_unknown>mep-unknown))?
+ (\s(?P<service_up>service-up))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps ethernet cfm crosscheck"
+ "{{ ' mep-missing' if traps.ethernet.cfm.crosscheck.mep_missing|d(False) else ''}}"
+ "{{ ' mep-unknown' if traps.ethernet.cfm.crosscheck.mep_unknown|d(False) else ''}}"
+ "{{ ' service-up' if traps.ethernet.cfm.crosscheck.service_up|d(False) else ''}}",
+ "result": {
+ "traps": {
+ "ethernet": {
+ "cfm": {
+ "crosscheck": {
+ "mep_missing": "{{ not not mep_missing }}",
+ "mep_unknown": "{{ not not mep_unknown }}",
+ "service_up": "{{ not not service_up }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.ethernet.evc",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sethernet\sevc
+ (\s(?P<status>status))?
+ (\s(?P<create>create))?
+ (\s(?P<delete>delete))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps ethernet evc"
+ "{{ ' status' if traps.ethernet.evc.status|d(False) else ''}}"
+ "{{ ' create' if traps.ethernet.evc.create|d(False) else ''}}"
+ "{{ ' delete' if traps.ethernet.evc.delete|d(False) else ''}}",
+ "result": {
+ "traps": {
+ "ethernet": {
+ "evc": {
+ "create": "{{ not not create }}",
+ "delete": "{{ not not delete }}",
+ "status": "{{ not not status }}",
+ },
+ },
},
},
},
@@ -858,6 +1216,69 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.flash",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sflash
+ (\s(?P<insertion>insertion))?
+ (\s(?P<removal>removal))?
+ (\s(?P<lowspace>lowspace))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps flash"
+ "{{ ' insertion' if traps.flash.insertion|d(False) else '' }}"
+ "{{ ' removal' if traps.flash.removal|d(False) else '' }}"
+ "{{ ' lowspace' if traps.flash.lowspace|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "flash": {
+ "enable": True,
+ "insertion": "{{ not not insertion }}",
+ "removal": "{{ not not removal }}",
+ "lowspace": "{{ not not lowspace }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.flex_links",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sflex-links
+ (\s(?P<status>status))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps flex-links"
+ "{{ ' status' if traps.flex_links.status|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "flex_links": {
+ "enable": True,
+ "status": "{{ not not status }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.firewall",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sfirewall
+ (\s(?P<serverstatus>serverstatus))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps firewall"
+ "{{ ' serverstatus' if traps.firewall.serverstatus|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "firewall": {
+ "enable": True,
+ "serverstatus": "{{ not not serverstatus }}",
+ },
+ },
+ },
+ },
+ {
"name": "traps.flowmon",
"getval": re.compile(
r"""
@@ -872,6 +1293,46 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
+ "name": "traps.frame_relay",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\s(framerelay|frame-relay)$
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps frame-relay",
+ "result": {
+ "traps": {
+ "frame_relay": {
+ "enable": True,
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.frame_relay.subif",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sframe-relay\ssubif
+ (\sinterval(?P<interval>\d+))?
+ (\scount(?P<count>\d+))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps frame-relay subif"
+ "{{ ' interval ' + interval|string if traps.frame_relay.subif.interval|d(False) else '' }}"
+ "{{ ' count ' + count|string if traps.frame_relay.subif.count|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "frame_relay": {
+ "subif": {
+ "enable": "{{ not not subif }}",
+ "interval": "{{ interval }}",
+ "count": "{{ count }}",
+ },
+ },
+ },
+ },
+ },
+ {
"name": "traps.fru_ctrl",
"getval": re.compile(
r"""
@@ -900,519 +1361,720 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.ipsla",
+ "name": "traps.ike.policy.add",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsla
+ ^snmp-server\senable\straps\sike\spolicy\sadd
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsla",
+ "setval": "snmp-server enable traps ike policy add",
"result": {
"traps": {
- "ipsla": True,
+ "ike": {
+ "policy": {
+ "add": True,
+ },
+ },
},
},
},
{
- "name": "traps.msdp",
+ "name": "traps.ike.policy.delete",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\smsdp$
+ ^snmp-server\senable\straps\sike\spolicy\sdelete
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps msdp",
+ "setval": "snmp-server enable traps ike policy delete",
"result": {
"traps": {
- "msdp": True,
+ "ike": {
+ "policy": {
+ "delete": True,
+ },
+ },
},
},
},
{
- "name": "traps.pw_vc",
+ "name": "traps.ike.tunnel.start",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\spw\svc$
+ ^snmp-server\senable\straps\sike\stunnel\sstart
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps pw vc",
+ "setval": "snmp-server enable traps ike tunnel start",
"result": {
"traps": {
- "pw_vc": True,
+ "ike": {
+ "tunnel": {
+ "start": True,
+ },
+ },
},
},
},
{
- "name": "traps.mvpn",
+ "name": "traps.ike.tunnel.stop",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\smvpn
+ ^snmp-server\senable\straps\sike\stunnel\sstop
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps mvpn",
+ "setval": "snmp-server enable traps ike tunnel stop",
"result": {
"traps": {
- "mvpn": True,
+ "ike": {
+ "tunnel": {
+ "stop": True,
+ },
+ },
},
},
},
{
- "name": "traps.mpls_vpn",
+ "name": "traps.ipmulticast",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\smpls\svpn
+ ^snmp-server\senable\straps\sipmulticast
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps mpls vpn",
+ "setval": "snmp-server enable traps ipmulticast",
"result": {
"traps": {
- "mpls_vpn": True,
+ "ipmulticast": True,
},
},
},
{
- "name": "traps.pki",
+ "name": "traps.ipsec.cryptomap.add",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\spki
+ ^snmp-server\senable\straps\sipsec\scryptomap\sadd
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps pki",
+ "setval": "snmp-server enable traps ipsec cryptomap add",
"result": {
"traps": {
- "pki": True,
+ "ipsec": {
+ "cryptomap": {
+ "add": True,
+ },
+ },
},
},
},
{
- "name": "traps.rsvp",
+ "name": "traps.ipsec.cryptomap.attach",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\srsvp
+ ^snmp-server\senable\straps\sipsec\scryptomap\sattach
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps rsvp",
+ "setval": "snmp-server enable traps ipsec cryptomap attach",
"result": {
"traps": {
- "rsvp": True,
+ "ipsec": {
+ "cryptomap": {
+ "attach": True,
+ },
+ },
},
},
},
{
- "name": "traps.syslog",
+ "name": "traps.ipsec.cryptomap.delete",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\ssyslog
+ ^snmp-server\senable\straps\sipsec\scryptomap\sdelete
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps syslog",
+ "setval": "snmp-server enable traps ipsec cryptomap delete",
"result": {
"traps": {
- "syslog": True,
+ "ipsec": {
+ "cryptomap": {
+ "delete": True,
+ },
+ },
},
},
},
{
- "name": "traps.transceiver_all",
+ "name": "traps.ipsec.cryptomap.detach",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\stransceiver\sall
+ ^snmp-server\senable\straps\sipsec\scryptomap\sdetach
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps transceiver all",
+ "setval": "snmp-server enable traps ipsec cryptomap detach",
"result": {
"traps": {
- "transceiver_all": True,
+ "ipsec": {
+ "cryptomap": {
+ "detach": True,
+ },
+ },
},
},
},
{
- "name": "traps.tty",
+ "name": "traps.ipsec.too_many_sas",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\stty
+ ^snmp-server\senable\straps\sipsec\stoo-many-sas
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps tty",
+ "setval": "snmp-server enable traps ipsec too-many-sas",
"result": {
"traps": {
- "tty": True,
+ "ipsec": {
+ "too_many_sas": True,
+ },
},
},
},
{
- "name": "traps.envmon.shutdown",
+ "name": "traps.ipsec.tunnel.start",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sshutdown$
+ ^snmp-server\senable\straps\sipsec\stunnel\sstart
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon shutdown",
+ "setval": "snmp-server enable traps ipsec tunnel start",
"result": {
"traps": {
- "envmon": {
- "shutdown": True,
+ "ipsec": {
+ "tunnel": {
+ "start": True,
+ },
},
},
},
},
{
- "name": "traps.envmon.status",
+ "name": "traps.ipsec.tunnel.stop",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sstatus$
+ ^snmp-server\senable\straps\sipsec\stunnel\sstop
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon status",
+ "setval": "snmp-server enable traps ipsec tunnel stop",
"result": {
"traps": {
- "envmon": {
- "status": True,
+ "ipsec": {
+ "tunnel": {
+ "stop": True,
+ },
},
},
},
},
{
- "name": "traps.envmon.supply",
+ "name": "traps.ipsla",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\ssupply$
+ ^snmp-server\senable\straps\sipsla
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon supply",
+ "setval": "snmp-server enable traps ipsla",
"result": {
"traps": {
- "envmon": {
- "supply": True,
- },
+ "ipsla": True,
},
},
},
{
- "name": "traps.envmon.temperature",
+ "name": "traps.isis",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\stemperature$
+ ^snmp-server\senable\straps\sisis$
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon temperature",
+ "setval": "snmp-server enable traps isis",
"result": {
"traps": {
- "envmon": {
- "temperature": True,
- },
+ "isis": True,
},
},
},
{
- "name": "traps.envmon.fan.enable",
+ "name": "traps.l2tc",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sfan$
+ ^snmp-server\senable\straps\sl2tc
+ (\s(?P<threshold>threshold))?
+ (\s(?P<sys_threshold>sys-threshold))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon fan",
+ "setval": "snmp-server enable traps l2tc"
+ "{{ ' threshold' if traps.l2tc.threshold|d(False) else '' }}"
+ "{{ ' sys-threshold' if traps.l2tc.sys_threshold|d(False) else '' }}",
"result": {
"traps": {
- "envmon": {
- "fan": {
- "enable": True,
- },
+ "l2tc": {
+ "enable": True,
+ "sys_threshold": "{{ not not sys_threshold }}",
+ "threshold": "{{ not not threshold }}",
},
},
},
},
{
- "name": "traps.envmon.fan.shutdown",
+ "name": "traps.l2tun.pseudowire_status",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sfan\sshutdown$
+ ^snmp-server\senable\straps\sl2tun\spseudowire\sstatus
+ (\s(?P<pseudowire_status>))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon fan shutdown",
+ "setval": "snmp-server enable traps l2tun pseudowire status",
"result": {
"traps": {
- "envmon": {
- "fan": {
- "shutdown": True,
- },
+ "l2tun": {
+ "pseudowire_status": True,
},
},
},
},
{
- "name": "traps.envmon.fan.status",
+ "name": "traps.l2tun.session",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sfan\sstatus$
+ ^snmp-server\senable\straps\sl2tun\ssession
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon fan status",
+ "setval": "snmp-server enable traps l2tun session",
"result": {
"traps": {
- "envmon": {
- "fan": {
- "status": True,
- },
+ "l2tun": {
+ "session": True,
},
},
},
},
{
- "name": "traps.envmon.fan.supply",
+ "name": "traps.license",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sfan\ssupply$
+ ^snmp-server\senable\straps\slicense
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon fan supply",
+ "setval": "snmp-server enable traps license",
"result": {
"traps": {
- "envmon": {
- "fan": {
- "supply": True,
- },
- },
+ "license": True,
},
},
},
{
- "name": "traps.envmon.fan.temperature",
+ "name": "traps.lisp",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\senvmon\sfan\stemperature$
+ ^snmp-server\senable\straps\slisp
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps envmon fan temperature",
+ "setval": "snmp-server enable traps lisp",
"result": {
"traps": {
- "envmon": {
- "fan": {
- "temperature": True,
- },
- },
+ "lisp": True,
},
},
},
{
- "name": "traps.vrrp",
+ "name": "traps.local_auth",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\svrrp
+ ^snmp-server\senable\straps\slocal-auth
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps vrrp",
+ "setval": "snmp-server enable traps local-auth",
"result": {
"traps": {
- "vrrp": True,
+ "local_auth": True,
},
},
},
{
- "name": "traps.ipmulticast",
+ "name": "traps.mac_notification",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipmulticast
+ ^snmp-server\senable\straps\smac-notification
+ (\s(?P<change>change))?
+ (\s(?P<move>move))?
+ (\s(?P<threshold>threshold))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipmulticast",
+ "setval": "snmp-server enable traps mac-notification"
+ "{{ ' change' if traps.mac_notification.change|d(False) else '' }}"
+ "{{ ' move' if traps.mac_notification.move|d(False) else '' }}"
+ "{{ ' threshold' if traps.mac_notification.threshold|d(False) else '' }}",
"result": {
"traps": {
- "ipmulticast": True,
+ "mac_notification": {
+ "enable": True,
+ "change": "{{ not not change }}",
+ "move": "{{ not not move }}",
+ "threshold": "{{ not not threshold }}",
+ },
},
},
},
{
- "name": "traps.ike.policy.add",
+ "name": "traps.memory",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sike\spolicy\sadd
+ ^snmp-server\senable\straps\smemory
+ (\s(?P<bufferpeak>bufferpeak))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ike policy add",
+ "setval": "snmp-server enable traps memory"
+ "{{ ' bufferpeak' if traps.memory.bufferpeak|d(False) else '' }}",
"result": {
"traps": {
- "ike": {
- "policy": {
- "add": True,
- },
+ "memory": {
+ "enable": True,
+ "bufferpeak": "{{ not not bufferpeak }}",
},
},
},
},
{
- "name": "traps.ike.policy.delete",
+ "name": "traps.mpls.fast_reroute",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sike\spolicy\sdelete
+ ^snmp-server\senable\straps\smpls\sfast-reroute
+ (\s(?P<protected>protected))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ike policy delete",
+ "setval": "snmp-server enable traps mpls fast-reroute"
+ "{{ ' protected' if traps.mpls.fast_reroute.protected|d(False) else '' }}",
"result": {
"traps": {
- "ike": {
- "policy": {
- "delete": True,
+ "mpls": {
+ "fast_reroute": {
+ "enable": True,
+ "protected": "{{ not not protected }}",
},
},
},
},
},
{
- "name": "traps.ike.tunnel.start",
+ "name": "traps.mpls.ldp",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sike\stunnel\sstart
+ ^snmp-server\senable\straps\smpls\sldp
+ (\s(?P<pv_limit>pv-limit))?
+ (\s(?P<session_down>session-down))?
+ (\s(?P<session_up>session-up))?
+ (\s(?P<threshold>threshold))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ike tunnel start",
+ "setval": "snmp-server enable traps mpls ldp"
+ "{{ ' pv-limit' if traps.mpls.ldp.pv_limit|d(False) else '' }}"
+ "{{ ' session-down' if traps.mpls.ldp.session_down|d(False) else '' }}"
+ "{{ ' session-up' if traps.mpls.ldp.session_up|d(False) else '' }}"
+ "{{ ' threshold' if traps.mpls.ldp.threshold|d(False) else '' }}",
"result": {
"traps": {
- "ike": {
- "tunnel": {
- "start": True,
+ "mpls": {
+ "ldp": {
+ "enable": True,
+ "pv_limit": "{{ not not pv_limit }}",
+ "session_down": "{{ not not session_down }}",
+ "session_up": "{{ not not session_up }}",
+ "threshold": "{{ not not threshold }}",
},
},
},
},
},
{
- "name": "traps.ike.tunnel.stop",
+ "name": "traps.mpls.rfc.ldp",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sike\stunnel\sstop
+ ^snmp-server\senable\straps\smpls\srfc\sldp
+ (\s(?P<pv_limit>pv-limit))?
+ (\s(?P<session_down>session-down))?
+ (\s(?P<session_up>session-up))?
+ (\s(?P<threshold>threshold))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ike tunnel stop",
+ "setval": "snmp-server enable traps mpls rfc ldp"
+ "{{ ' pv-limit' if traps.mpls.rfc.ldp.pv_limit|d(False) else '' }}"
+ "{{ ' session-down' if traps.mpls.rfc.ldp.session_down|d(False) else '' }}"
+ "{{ ' session-up' if traps.mpls.rfc.ldp.session_up|d(False) else '' }}"
+ "{{ ' threshold' if traps.mpls.rfc.ldp.threshold|d(False) else '' }}",
"result": {
"traps": {
- "ike": {
- "tunnel": {
- "stop": True,
+ "mpls": {
+ "rfc": {
+ "ldp": {
+ "enable": True,
+ "pv_limit": "{{ not not pv_limit }}",
+ "session_down": "{{ not not session_down }}",
+ "session_up": "{{ not not session_up }}",
+ "threshold": "{{ not not threshold }}",
+ },
},
},
},
},
},
{
- "name": "traps.ipsec.cryptomap.add",
+ "name": "traps.mpls.rfc.traffic_eng",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\scryptomap\sadd
+ ^snmp-server\senable\straps\smpls\srfc\straffic-eng
+ (\s(?P<down>down))?
+ (\s(?P<reoptimized>reoptimized))?
+ (\s(?P<reroute>reroute))?
+ (\s(?P<up>up))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec cryptomap add",
+ "setval": "snmp-server enable traps mpls rfc traffic-eng"
+ "{{ ' down' if traps.mpls.rfc.traffic_eng.down|d(False) else '' }}"
+ "{{ ' reoptimized' if traps.mpls.rfc.traffic_eng.reoptimized|d(False) else '' }}"
+ "{{ ' reroute' if traps.mpls.rfc.traffic_eng.reroute|d(False) else '' }}"
+ "{{ ' up' if traps.mpls.rfc.traffic_eng.up|d(False) else '' }}",
"result": {
"traps": {
- "ipsec": {
- "cryptomap": {
- "add": True,
+ "mpls": {
+ "rfc": {
+ "traffic_eng": {
+ "enable": True,
+ "down": "{{ not not down }}",
+ "reoptimized": "{{ not not reoptimized }}",
+ "reroute": "{{ not not reroute }}",
+ "up": "{{ not not up }}",
+ },
},
},
},
},
},
{
- "name": "traps.ipsec.cryptomap.delete",
+ "name": "traps.mpls.rfc.vpn",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\scryptomap\sdelete
+ ^snmp-server\senable\straps\smpls\srfc\svpn
+ (\s(?P<illegal_label>illegal-label))?
+ (\s(?P<max_thresh_cleared>max-thresh-cleared))?
+ (\s(?P<max_threshold>max-threshold))?
+ (\s(?P<mid_threshold>mid-threshold))?
+ (\s(?P<vrf_down>vrf-down))?
+ (\s(?P<vrf_up>vrf-up))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec cryptomap delete",
+ "setval": "snmp-server enable traps mpls rfc vpn"
+ "{{ ' illegal-label' if traps.mpls.rfc.vpn.illegal_label|d(False) else '' }}"
+ "{{ ' max-thresh-cleared' if traps.mpls.rfc.vpn.max_thresh_cleared|d(False) else '' }}"
+ "{{ ' max-threshold' if traps.mpls.rfc.vpn.max_threshold|d(False) else '' }}"
+ "{{ ' mid-threshold' if traps.mpls.rfc.vpn.mid_threshold|d(False) else '' }}"
+ "{{ ' vrf-down' if traps.mpls.rfc.vpn.vrf_down|d(False) else '' }}"
+ "{{ ' vrf-up' if traps.mpls.rfc.vpn.vrf_up|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "mpls": {
+ "rfc": {
+ "vpn": {
+ "enable": True,
+ "illegal_label": "{{ not not illegal_label }}",
+ "max_thresh_cleared": "{{ not not max_thresh_cleared }}",
+ "max_threshold": "{{ not not max_threshold }}",
+ "mid_threshold": "{{ not not mid_threshold }}",
+ "vrf_down": "{{ not not vrf_down }}",
+ "vrf_up": "{{ not not vrf_up }}",
+ },
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.mpls.traffic_eng",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\smpls\straffic-eng
+ (\s(?P<down>down))?
+ (\s(?P<reroute>reroute))?
+ (\s(?P<up>up))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps mpls traffic-eng"
+ "{{ ' down' if traps.mpls.traffic_eng.down|d(False) else '' }}"
+ "{{ ' reroute' if traps.mpls.traffic_eng.reroute|d(False) else '' }}"
+ "{{ ' up' if traps.mpls.traffic_eng.up|d(False) else '' }}",
"result": {
"traps": {
- "ipsec": {
- "cryptomap": {
- "delete": True,
+ "mpls": {
+ "traffic_eng": {
+ "enable": True,
+ "down": "{{ not not down }}",
+ "reroute": "{{ not not reroute }}",
+ "up": "{{ not not up }}",
},
},
},
},
},
{
- "name": "traps.ipsec.cryptomap.attach",
+ "name": "traps.mpls.vpn",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\scryptomap\sattach
+ ^snmp-server\senable\straps\smpls(-|\s)vpn
+ (\s(?P<illegal_label>illegal-label))?
+ (\s(?P<max_thresh_cleared>max-thresh-cleared))?
+ (\s(?P<max_threshold>max-threshold))?
+ (\s(?P<mid_threshold>mid-threshold))?
+ (\s(?P<vrf_down>vrf-down))?
+ (\s(?P<vrf_up>vrf-up))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec cryptomap attach",
+ "setval": "{% if 'vpn' in traps.mpls and traps.mpls.vpn.enable %}"
+ "snmp-server enable traps mpls vpn"
+ "{{ ' illegal-label' if traps.mpls.vpn.illegal_label|d(False) else '' }}"
+ "{{ ' max-thresh-cleared' if traps.mpls.vpn.max_thresh_cleared|d(False) else '' }}"
+ "{{ ' max-threshold' if traps.mpls.vpn.max_threshold|d(False) else '' }}"
+ "{{ ' mid-threshold' if traps.mpls.vpn.mid_threshold|d(False) else '' }}"
+ "{{ ' vrf-down' if traps.mpls.vpn.vrf_down|d(False) else '' }}"
+ "{{ ' vrf-up' if traps.mpls.vpn.vrf_up|d(False) else '' }}"
+ "{% endif %}",
"result": {
"traps": {
- "ipsec": {
- "cryptomap": {
- "attach": True,
+ "mpls": {
+ "vpn": {
+ "enable": True,
+ "illegal_label": "{{ not not illegal_label }}",
+ "max_thresh_cleared": "{{ not not max_thresh_cleared }}",
+ "max_threshold": "{{ not not max_threshold }}",
+ "mid_threshold": "{{ not not mid_threshold }}",
+ "vrf_down": "{{ not not vrf_down }}",
+ "vrf_up": "{{ not not vrf_up }}",
},
},
},
},
},
{
- "name": "traps.ipsec.cryptomap.detach",
+ "name": "traps.msdp",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\scryptomap\sdetach
+ ^snmp-server\senable\straps\smsdp$
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec cryptomap detach",
+ "setval": "snmp-server enable traps msdp",
"result": {
"traps": {
- "ipsec": {
- "cryptomap": {
- "detach": True,
+ "msdp": True,
+ },
+ },
+ },
+ {
+ "name": "traps.mvpn",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\smvpn
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps mvpn",
+ "result": {
+ "traps": {
+ "mvpn": True,
+ },
+ },
+ },
+ {
+ "name": "traps.nhrp.nhc",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\snhrp\snhc
+ (\s(?P<down>down))?
+ (\s(?P<up>up))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps nhrp nhc"
+ "{{ ' down' if traps.nhrp.nhc.down|d(False) else '' }}"
+ "{{ ' up' if traps.nhrp.nhc.up|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "nhrp": {
+ "enable": True,
+ "nhc": {
+ "enable": True,
+ "down": "{{ not not down }}",
+ "up": "{{ not not up }}",
},
},
},
},
},
{
- "name": "traps.ipsec.tunnel.start",
+ "name": "traps.nhrp.nhp",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\stunnel\sstart
+ ^snmp-server\senable\straps\snhrp\snhp
+ (\s(?P<down>down))?
+ (\s(?P<up>up))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec tunnel start",
+ "setval": "snmp-server enable traps nhrp nhp"
+ "{{ ' down' if traps.nhrp.nhc.down|d(False) else '' }}"
+ "{{ ' up' if traps.nhrp.nhc.up|d(False) else '' }}",
"result": {
"traps": {
- "ipsec": {
- "tunnel": {
- "start": True,
+ "nhrp": {
+ "enable": True,
+ "nhp": {
+ "enable": True,
+ "down": "{{ not not down }}",
+ "up": "{{ not not up }}",
},
},
},
},
},
{
- "name": "traps.ipsec.tunnel.stop",
+ "name": "traps.nhrp.nhs",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\stunnel\sstop
+ ^snmp-server\senable\straps\snhrp\snhs
+ (\s(?P<down>down))?
+ (\s(?P<up>up))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec tunnel stop",
+ "setval": "snmp-server enable traps nhrp nhs"
+ "{{ ' down' if traps.nhrp.nhc.down|d(False) else '' }}"
+ "{{ ' up' if traps.nhrp.nhc.up|d(False) else '' }}",
"result": {
"traps": {
- "ipsec": {
- "tunnel": {
- "stop": True,
+ "nhrp": {
+ "enable": True,
+ "nhs": {
+ "enable": True,
+ "down": "{{ not not down }}",
+ "up": "{{ not not up }}",
},
},
},
},
},
{
- "name": "traps.ipsec.too_many_sas",
+ "name": "traps.nhrp.quota_exceeded",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sipsec\stoo-many-sas
+ ^snmp-server\senable\straps\snhrp
+ (\s(?P<quota_exceeded>quota-exceeded))?$
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ipsec too-many-sas",
+ "setval": "snmp-server enable traps nhrp"
+ "{{ ' quota-exceeded' if traps.nhrp.quota_exceeded|d(False) else '' }}",
"result": {
"traps": {
- "ipsec": {
- "too_many_sas": True,
+ "nhrp": {
+ "enable": True,
+ "quota_exceeded": "{{ not not quota_exceeded }}",
},
},
},
@@ -1436,36 +2098,36 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.ospf.cisco_specific.retransmit",
+ "name": "traps.ospf.cisco_specific.lsa",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sospf\scisco-specific\sretransmit
+ ^snmp-server\senable\straps\sospf\scisco-specific\slsa
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ospf cisco-specific retransmit",
+ "setval": "snmp-server enable traps ospf cisco-specific lsa",
"result": {
"traps": {
"ospf": {
"cisco_specific": {
- "retransmit": True,
+ "lsa": True,
},
},
},
},
},
{
- "name": "traps.ospf.cisco_specific.lsa",
+ "name": "traps.ospf.cisco_specific.retransmit",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sospf\scisco-specific\slsa
+ ^snmp-server\senable\straps\sospf\scisco-specific\sretransmit
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ospf cisco-specific lsa",
+ "setval": "snmp-server enable traps ospf cisco-specific retransmit",
"result": {
"traps": {
"ospf": {
"cisco_specific": {
- "lsa": True,
+ "retransmit": True,
},
},
},
@@ -1552,33 +2214,33 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.ospf.retransmit",
+ "name": "traps.ospf.lsa",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sospf\sretransmit
+ ^snmp-server\senable\straps\sospf\slsa
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ospf retransmit",
+ "setval": "snmp-server enable traps ospf lsa",
"result": {
"traps": {
"ospf": {
- "retransmit": True,
+ "lsa": True,
},
},
},
},
{
- "name": "traps.ospf.lsa",
+ "name": "traps.ospf.retransmit",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sospf\slsa
+ ^snmp-server\senable\straps\sospf\sretransmit
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ospf lsa",
+ "setval": "snmp-server enable traps ospf retransmit",
"result": {
"traps": {
"ospf": {
- "lsa": True,
+ "retransmit": True,
},
},
},
@@ -1600,72 +2262,91 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.l2tun.pseudowire_status",
- "getval": re.compile(
- r"""
- ^snmp-server\senable\straps\sl2tun\spseudowire\sstatus
- (\s(?P<pseudowire_status>))?
- """, re.VERBOSE,
- ),
- "setval": "snmp-server enable traps l2tun pseudowire status",
- "result": {
- "traps": {
- "l2tun": {
- "pseudowire_status": True,
- },
- },
- },
- },
- {
- "name": "traps.l2tun.session",
+ "name": "traps.ospfv3.errors",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sl2tun\ssession
+ ^snmp-server\senable\straps\sospfv3\serrors
+ (\s(?P<bad_packet>bad-packet))?
+ (\s(?P<config_error>config-error))?
+ (\s(?P<virt_bad_packet>virt-bad-packet))?
+ (\s(?P<virt_config_error>virt-config-error))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps l2tun session",
+ "setval": "snmp-server enable traps ospfv3 errors"
+ "{{ ' bad-packet' if traps.ospfv3.errors.bad_packet|d(False) else '' }}"
+ "{{ ' config-error' if traps.ospfv3.errors.config_error|d(False) else '' }}"
+ "{{ ' virt-bad-packet' if traps.ospfv3.errors.virt_bad_packet|d(False) else '' }}"
+ "{{ ' virt-config-error' if traps.ospfv3.errors.virt_config_error|d(False) else '' }}",
"result": {
"traps": {
- "l2tun": {
- "session": True,
+ "ospfv3": {
+ "errors": {
+ "enable": True,
+ "bad_packet": "{{ not not bad_packet }}",
+ "config_error": "{{ not not config_error }}",
+ "virt_bad_packet": "{{ not not virt_bad_packet }}",
+ "virt_config_error": "{{ not not virt_config_error }}",
+ },
},
},
},
},
{
- "name": "traps.cpu",
+ "name": "traps.ospfv3.rate_limit",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\scpu
- (\s(?P<threshold>threshold))?
+ ^snmp-server\senable\straps\sospfv3\srate-limit
+ (\s(?P<rate_limit>[0-9]+))?
""", re.VERBOSE,
),
- "setval": "{{ 'snmp-server enable traps cpu' if traps.cpu.enable is defined else '' }}"
- "{{ ' threshold' if traps.cpu.threshold is defined else '' }}",
+ "setval": "snmp-server enable traps ospfv3 rate_limit"
+ "{{ traps.ospfv3.rate_limit|int if traps.ospfv3.rate_limit|int > 0 else '' }}",
"result": {
"traps": {
- "cpu": {
- "enable": True,
- "threshold": "{{ not not threshold }}",
+ "ospfv3": {
+ "rate_limit": "{{ rate_limit if rate_limit|int >=2 or rate_limit|int <= 60 }}",
},
},
},
},
{
- "name": "traps.firewall",
+ "name": "traps.ospfv3.state_change",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sfirewall
- (\s(?P<serverstatus>serverstatus))?
+ ^snmp-server\senable\straps\sospfv3\sstate-change
+ (\s(?P<if_state_change>if-state-change))?
+ (\s(?P<neighbor_restart_helper_status_change>neighbor-restart-helper-status-change))?
+ (\s(?P<neighbor_state_change>neighbor-state-change))?
+ (\s(?P<nssa_translator_status_change>nssa-translator-status-change))?
+ (\s(?P<restart_status_change>restart-status-change))?
+ (\s(?P<virtif_state_change>virtif-state-change))?
+ (\s(?P<virtneighbor_restart_helper_status_change>virtneighbor-restart-helper-status-change))?
+ (\s(?P<virtneighbor_state_change>virtneighbor-state-change))?
""", re.VERBOSE,
),
- "setval": "{{ 'snmp-server enable traps firewall' if traps.firewall.enable is defined else '' }}"
- "{{ ' serverstatus' if traps.firewall.serverstatus|d(False) else ''}}",
+ "setval": "snmp-server enable traps ospfv3 state-change"
+ "{{ ' if-state-change' if traps.ospfv3.state_change.if_state_change|d(False) else '' }}"
+ "{{ ' neighbor-restart-helper-status-change' if traps.ospfv3.state_change.neighbor_restart_helper_status_change|d(False) else '' }}"
+ "{{ ' neighbor-state-change' if traps.ospfv3.state_change.neighbor_state_change|d(False) else '' }}"
+ "{{ ' nssa-translator-status-change' if traps.ospfv3.state_change.nssa_translator_status_change|d(False) else '' }}"
+ "{{ ' restart-status-change' if traps.ospfv3.state_change.restart_status_change|d(False) else '' }}"
+ "{{ ' virtif-state-change' if traps.ospfv3.state_change.virtif_state_change|d(False) else '' }}"
+ "{{ ' virtneighbor-restart-helper-status-change' if traps.ospfv3.state_change.vn_restart_helper_status_change|d(False) else '' }}"
+ "{{ ' virtneighbor-state-change' if traps.ospfv3.state_change.vn_state_change|d(False) else '' }}",
"result": {
"traps": {
- "firewall": {
- "enable": True,
- "serverstatus": "{{ not not serverstatus }}",
+ "ospfv3": {
+ "state_change": {
+ "enable": True,
+ "if_state_change": "{{ not not if_state_change }}",
+ "neighbor_restart_helper_status_change": "{{ not not neighbor_restart_helper_status_change }}",
+ "neighbor_state_change": "{{ not not neighbor_state_change }}",
+ "nssa_translator_status_change": "{{ not not nssa_translator_status_change }}",
+ "restart_status_change": "{{ not not restart_status_change }}",
+ "virtif_state_change": "{{ not not virtif_state_change }}",
+ "vn_restart_helper_status_change": "{{ not not virtneighbor_restart_helper_status_change }}",
+ "vn_state_change": "{{ not not virtneighbor_state_change }}",
+ },
},
},
},
@@ -1696,28 +2377,126 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.vrfmib",
+ "name": "traps.pki",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\svrfmib
- (\s(?P<vrf_up>vrf-up))?
- (\s(?P<vrf_down>vrf-down))?
- (\s(?P<vnet_trunk_up>vnet-trunk-up))?
- (\s(?P<vnet_trunk_down>vnet-trunk-down))?
+ ^snmp-server\senable\straps\spki
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps vrfmib"
- "{{ ' vrf-up' if traps.vrfmib.vrf_up|d(False) else ''}}"
- "{{ ' vrf-down' if traps.vrfmib.vrf_down|d(False) else ''}}"
- "{{ ' vnet-trunk-up' if traps.vrfmib.vnet_trunk_up|d(False) else ''}}"
- "{{ ' vnet-trunk-down' if traps.vrfmib.vnet_trunk_down|d(False) else ''}}",
+ "setval": "snmp-server enable traps pki",
"result": {
"traps": {
- "vrfmib": {
- "vrf_up": "{{ not not vrf_up }}",
- "vrf_down": "{{ not not vrf_down }}",
- "vnet_trunk_up": "{{ not not vnet_trunk_up }}",
- "vnet_trunk_down": "{{ not not vnet_trunk_down }}",
+ "pki": True,
+ },
+ },
+ },
+ {
+ "name": "traps.port_security",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sport-security
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps port-security",
+ "result": {
+ "traps": {
+ "port_security": True,
+ },
+ },
+ },
+ {
+ "name": "traps.power_ethernet",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\spower-ethernet
+ (\s(?P<police>police))?$
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps power-ethernet"
+ "{{ ' police' if traps.power_ethernet.police|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "power_ethernet": {
+ "enable": True,
+ "police": "{{ not not police }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.pw_vc",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\spw\svc$
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps pw vc",
+ "result": {
+ "traps": {
+ "pw_vc": True,
+ },
+ },
+ },
+ {
+ "name": "traps.rep",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\srep
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps rep",
+ "result": {
+ "traps": {
+ "rep": True,
+ },
+ },
+ },
+ {
+ "name": "traps.rsvp",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\srsvp
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps rsvp",
+ "result": {
+ "traps": {
+ "rsvp": True,
+ },
+ },
+ },
+ {
+ "name": "traps.rf",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\srf
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps rf",
+ "result": {
+ "traps": {
+ "rf": True,
+ },
+ },
+ },
+ {
+ "name": "traps.smart_license",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\ssmart-license
+ (\s(?P<entitlement>entitlement))?
+ (\s(?P<global>global))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps smart-license"
+ "{{ ' entitlement' if traps.smart_license.entitlement|d(False) else '' }}"
+ "{{ ' global' if traps.smart_license.global|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "smart_license": {
+ "enable": True,
+ "entitlement": "{{ not not entitlement }}",
+ "global": "{{ not not global }}",
},
},
},
@@ -1738,8 +2517,8 @@ class Snmp_serverTemplate(NetworkTemplate):
"{{ ' authentication' if traps.snmp.authentication is defined else '' }}"
"{{ ' linkdown' if traps.snmp.linkdown|d(False) else ''}}"
"{{ ' linkup' if traps.snmp.linkup|d(False) else ''}}"
- "{{ ' warmstart' if traps.snmp.warmstart|d(False) else ''}}"
- "{{ ' coldstart' if traps.snmp.coldstart|d(False) else ''}}",
+ "{{ ' coldstart' if traps.snmp.coldstart|d(False) else ''}}"
+ "{{ ' warmstart' if traps.snmp.warmstart|d(False) else ''}}",
"result": {
"traps": {
"snmp": {
@@ -1753,202 +2532,381 @@ class Snmp_serverTemplate(NetworkTemplate):
},
},
{
- "name": "traps.frame_relay",
+ "name": "traps.stackwise",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sframe-relay$
+ ^snmp-server\senable\straps\sstackwise
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps frame-relay",
+ "setval": "snmp-server enable traps stackwise",
"result": {
"traps": {
- "frame_relay": {
+ "stackwise": True,
+ },
+ },
+ },
+ {
+ "name": "traps.stpx",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sstpx
+ (\s(?P<inconsistency>inconsistency))?
+ (\s(?P<root_inconsistency>root-inconsistency))?
+ (\s(?P<loop_inconsistency>loop-inconsistency))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps stpx"
+ "{{ ' inconsistency' if traps.stpx.inconsistency|d(False) else '' }}"
+ "{{ ' root-inconsistency' if traps.stpx.root_inconsistency|d(False) else '' }}"
+ "{{ ' loop-inconsistency' if traps.stpx.loop_inconsistency|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "stpx": {
"enable": True,
+ "inconsistency": "{{ not not inconsistency }}",
+ "loop_inconsistency": "{{ not not loop_inconsistency }}",
+ "root_inconsistency": "{{ not not root_inconsistency }}",
},
},
},
},
{
- "name": "traps.frame_relay.subif",
+ "name": "traps.syslog",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sframe-relay\ssubif
- (\scount(?P<count>\d+))?
- (\sinterval(?P<interval>\d+))?
+ ^snmp-server\senable\straps\ssyslog
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps frame-relay subif"
- "{{ (' count ' + count|string) if traps.frame_relay.count else '' }}"
- "{{ (' interval ' + interval|string) if traps.frame_relay.interval else '' }}",
+ "setval": "snmp-server enable traps syslog",
"result": {
"traps": {
- "frame_relay": {
- "subif": {
- "enable": "{{ not not subif }}",
- "interval": "{{ interval }}",
- "count": "{{ count }}",
- },
+ "syslog": True,
+ },
+ },
+ },
+ {
+ "name": "traps.transceiver_all",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\stransceiver\sall
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps transceiver all",
+ "result": {
+ "traps": {
+ "transceiver_all": True,
+ },
+ },
+ },
+ {
+ "name": "traps.trustsec",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\strustsec
+ (?!\S)
+ (\s(?P<authz_file_error>authz-file-error))?
+ (\s(?P<cache_file_error>cache-file-error))?
+ (\s(?P<keystore_file_error>keystore-file-error))?
+ (\s(?P<keystore_sync_fail>keystore-sync-fail))?
+ (\s(?P<random_number_fail>random-number-fail))?
+ (\s(?P<src_entropy_fail>src-entropy-fail))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps trustsec"
+ "{{ ' authz-file-error' if traps.trustsec.authz_file_error|d(False) else '' }}"
+ "{{ ' cache-file-error' if traps.trustsec.cache_file_error|d(False) else '' }}"
+ "{{ ' keystore-file-error' if traps.trustsec.keystore_file_error|d(False) else '' }}"
+ "{{ ' keystore-sync-fail' if traps.trustsec.keystore_sync_fail|d(False) else '' }}"
+ "{{ ' random-number-fail' if traps.trustsec.random_number_fail|d(False) else '' }}"
+ "{{ ' src-entropy-fail' if traps.trustsec.src_entropy_fail|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "trustsec": {
+ "enable": True,
+ "authz_file_error": "{{ not not authz_file_error }}",
+ "cache_file_error": "{{ not not cache_file_error }}",
+ "keystore_file_error": "{{ not not keystore_file_error }}",
+ "keystore_sync_fail": "{{ not not keystore_sync_fail }}",
+ "random_number_fail": "{{ not not random_number_fail }}",
+ "src_entropy_fail": "{{ not not src_entropy_fail }}",
},
},
},
},
{
- "name": "traps.cef",
+ "name": "traps.trustsec_interface",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\scef
- (\s(?P<resource_failure>resource-failure))?
- (\s(?P<peer_state_change>peer-state-change))?
- (\s(?P<peer_fib_state_change>peer-fib-state-change))?
- (\s(?P<inconsistency>inconsistency))?
+ ^snmp-server\senable\straps\strustsec-interface
+ (\s(?P<unauthorized>unauthorized))?
+ (\s(?P<sap_fail>sap-fail))?
+ (\s(?P<authc_fail>authc-fail))?
+ (\s(?P<supplicant_fail>supplicant-fail))?
+ (\s(?P<authz_fail>authz-fail))?
""", re.VERBOSE,
),
- "setval": "{{ 'snmp-server enable traps cef' if traps.cef.enable is defined else '' }}"
- "{{ ' resource-failure' if traps.cef.resource_failure|d(False) else ''}}"
- "{{ ' peer-state-change' if traps.cef.peer_state_change|d(False) else ''}}"
- "{{ ' peer-fib-state-change' if traps.cef.peer_fib_state_change|d(False) else ''}}"
- "{{ ' inconsistency' if traps.cef.inconsistency|d(False) else ''}}",
+ "setval": "snmp-server enable traps trustsec-interface"
+ "{{ ' unauthorized' if traps.trustsec_interface.unauthorized|d(False) else '' }}"
+ "{{ ' sap-fail' if traps.trustsec_interface.sap_fail|d(False) else '' }}"
+ "{{ ' authc-fail' if traps.trustsec_interface.authc_fail|d(False) else '' }}"
+ "{{ ' supplicant-fail' if traps.trustsec_interface.supplicant_fail|d(False) else '' }}"
+ "{{ ' authz-fail' if traps.trustsec_interface.authz_fail|d(False) else '' }}",
"result": {
"traps": {
- "cef": {
+ "trustsec_interface": {
"enable": True,
- "inconsistency": "{{ not not inconsistency }}",
- "peer_fib_state_change": "{{ not not peer_fib_state_change }}",
- "peer_state_change": "{{ not not peer_state_change }}",
- "resource_failure": "{{ not not resource_failure }}",
+ "unauthorized": "{{ not not unauthorized }}",
+ "sap_fail": "{{ not not sap_fail }}",
+ "authc_fail": "{{ not not authc_fail }}",
+ "supplicant_fail": "{{ not not supplicant_fail }}",
+ "authz_fail": "{{ not not authz_fail }}",
},
},
},
},
{
- "name": "traps.dlsw",
+ "name": "traps.trustsec_policy",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sdlsw
- (\s(?P<circuit>circuit))?
- (\s(?P<tconn>tconn))?
+ ^snmp-server\senable\straps\strustsec-policy
+ (\s(?P<peer_policy_updated>peer-policy-updated))?
+ (\s(?P<authz_sgacl_fail>authz-sgacl-fail))?
""", re.VERBOSE,
),
- "setval": "{{ 'snmp-server enable traps dlsw' if traps.dlsw.enable is defined else '' }}"
- "{{ ' circuit' if traps.dlsw.circuit|d(False) else ''}}"
- "{{ ' tconn' if traps.dlsw.tconn|d(False) else ''}}",
+ "setval": "snmp-server enable traps trustsec-policy"
+ "{{ ' peer-policy-updated' if traps.trustsec_policy.peer_policy_updated|d(False) else '' }}"
+ "{{ ' authz-sgacl-fail' if traps.trustsec_policy.authz_sgacl_fail|d(False) else '' }}",
"result": {
"traps": {
- "dlsw": {
+ "trustsec_policy": {
"enable": True,
- "circuit": "{{ not not circuit }}",
- "tconn": "{{ not not tconn }}",
+ "peer_policy_updated": "{{ not not peer_policy_updated }}",
+ "authz_sgacl_fail": "{{ not not authz_sgacl_fail }}",
},
},
},
},
{
- "name": "traps.ethernet.evc",
+ "name": "traps.trustsec_server",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sethernet\sevc
- (\s(?P<status>status))?
- (\s(?P<create>create))?
- (\s(?P<delete>delete))?
+ ^snmp-server\senable\straps\strustsec-server
+ (\s(?P<radius_server>radius-server))?
+ (\s(?P<provision_secret>provision-secret))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ethernet evc"
- "{{ ' create' if traps.ethernet.evc.create|d(False) else ''}}"
- "{{ ' delete' if traps.ethernet.evc.delete|d(False) else ''}}"
- "{{ ' status' if traps.ethernet.evc.status|d(False) else ''}}",
+ "setval": "snmp-server enable traps trustsec-server"
+ "{{ ' radius-server' if traps.trustsec_server.radius_server|d(False) else '' }}"
+ "{{ ' provision-secret' if traps.trustsec_server.provision_secret|d(False) else '' }}",
"result": {
"traps": {
- "ethernet": {
- "evc": {
- "create": "{{ not not create }}",
- "delete": "{{ not not delete }}",
- "status": "{{ not not status }}",
- },
+ "trustsec_server": {
+ "enable": True,
+ "radius_server": "{{ not not radius_server }}",
+ "provision_secret": "{{ not not provision_secret }}",
},
},
},
},
{
- "name": "traps.ethernet.cfm.cc",
+ "name": "traps.trustsec_sxp",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sethernet\scfm\scc
- (\s(?P<mep_up>mep-up))?
- (\s(?P<mep_down>mep-down))?
- (\s(?P<cross_connect>cross-connect))?
- (\s(?P<loop>loop))?
- (\s(?P<config>config))?
+ ^snmp-server\senable\straps\strustsec-sxp
+ (\s(?P<conn_srcaddr_err>conn-srcaddr-err))?
+ (\s(?P<msg_parse_err>msg-parse-err))?
+ (\s(?P<conn_config_err>conn-config-err))?
+ (\s(?P<binding_err>binding-err))?
+ (\s(?P<conn_up>conn-up))?
+ (\s(?P<conn_down>conn-down))?
+ (\s(?P<binding_expn_fail>binding-expn-fail))?
+ (\s(?P<oper_nodeid_change>oper-nodeid-change))?
+ (\s(?P<binding_conflict>binding-conflict))?
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ethernet cfm cc"
- "{{ ' mep-up' if traps.ethernet.cfm.cc.mep_up|d(False) else ''}}"
- "{{ ' mep-down' if traps.ethernet.cfm.cc.mep_down|d(False) else ''}}"
- "{{ ' cross-connect' if traps.ethernet.cfm.cc.cross_connect|d(False) else ''}}"
- "{{ ' loop' if traps.ethernet.cfm.cc.loop|d(False) else ''}}"
- "{{ ' config' if traps.ethernet.cfm.cc.config|d(False) else ''}}",
+ "setval": "snmp-server enable traps trustsec-sxp"
+ "{{ ' conn-srcaddr-err' if traps.trustsec_sxp.conn_srcaddr_err|d(False) else '' }}"
+ "{{ ' msg-parse-err' if traps.trustsec_sxp.msg_parse_err|d(False) else '' }}"
+ "{{ ' conn-config-err' if traps.trustsec_sxp.conn_config_err|d(False) else '' }}"
+ "{{ ' binding-err' if traps.trustsec_sxp.binding_err|d(False) else '' }}"
+ "{{ ' conn-up' if traps.trustsec_sxp.conn_up|d(False) else '' }}"
+ "{{ ' conn-down' if traps.trustsec_sxp.conn_down|d(False) else '' }}"
+ "{{ ' binding-expn-fail' if traps.trustsec_sxp.binding_expn_fail|d(False) else '' }}"
+ "{{ ' oper-nodeid-change' if traps.trustsec_sxp.oper_nodeid_change|d(False) else '' }}"
+ "{{ ' binding-conflict' if traps.trustsec_sxp.binding_conflict|d(False) else '' }}",
"result": {
"traps": {
- "ethernet": {
- "cfm": {
- "cc": {
- "mep_up": "{{ not not mep_up }}",
- "mep_down": "{{ not not mep_down }}",
- "cross_connect": "{{ not not cross_connect }}",
- "loop": "{{ not not loop }}",
- "config": "{{ not not config }}",
- },
- },
+ "trustsec_sxp": {
+ "enable": True,
+ "conn_srcaddr_err": "{{ not not conn_srcaddr_err }}",
+ "msg_parse_err": "{{ not not msg_parse_err }}",
+ "conn_config_err": "{{ not not conn_config_err }}",
+ "binding_err": "{{ not not binding_err }}",
+ "conn_up": "{{ not not conn_up }}",
+ "conn_down": "{{ not not conn_down }}",
+ "binding_expn_fail": "{{ not not binding_expn_fail }}",
+ "oper_nodeid_change": "{{ not not oper_nodeid_change }}",
+ "binding_conflict": "{{ not not binding_conflict }}",
},
},
},
},
{
- "name": "traps.ethernet.cfm.crosscheck",
+ "name": "traps.tty",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sethernet\scfm\scrosscheck
- (\s(?P<mep_missing>mep-missing))?
- (\s(?P<mep_unknown>mep-unknown))?
- (\s(?P<service_up>service-up))?
+ ^snmp-server\senable\straps\stty
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ethernet cfm crosscheck"
- "{{ ' mep-missing' if traps.ethernet.cfm.crosscheck.mep_missing|d(False) else ''}}"
- "{{ ' mep-unknown' if traps.ethernet.cfm.crosscheck.mep_unknown|d(False) else ''}}"
- "{{ ' service-up' if traps.ethernet.cfm.crosscheck.service_up|d(False) else ''}}",
+ "setval": "snmp-server enable traps tty",
"result": {
"traps": {
- "ethernet": {
- "cfm": {
- "crosscheck": {
- "mep_missing": "{{ not not mep_missing }}",
- "mep_unknown": "{{ not not mep_unknown }}",
- "service_up": "{{ not not service_up }}",
- },
- },
+ "tty": True,
+ },
+ },
+ },
+ {
+ "name": "traps.udld",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\sudld
+ (\s(?P<link_fail_rpt>link-fail-rpt))?
+ (\s(?P<status_change>status-change))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps udld"
+ "{{ ' link-fail-rpt' if traps.udld.link_fail_rpt|d(False) else '' }}"
+ "{{ ' status-change' if traps.udld.status_change|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "udld": {
+ "enable": True,
+ "link_fail_rpt": "{{ not not link_fail_rpt }}",
+ "status_change": "{{ not not status_change }}",
},
},
},
},
{
- "name": "traps.ethernet.cfm.alarm",
+ "name": "traps.vlan_membership",
"getval": re.compile(
r"""
- ^snmp-server\senable\straps\sethernet\scfm\salarm
+ ^snmp-server\senable\straps\svlan-membership
""", re.VERBOSE,
),
- "setval": "snmp-server enable traps ethernet cfm alarm",
+ "setval": "snmp-server enable traps vlan-membership",
"result": {
"traps": {
- "ethernet": {
- "cfm": {
- "alarm": True,
- },
+ "vlan_membership": True,
+ },
+ },
+ },
+ {
+ "name": "traps.vlancreate",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\svlancreate
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps vlancreate",
+ "result": {
+ "traps": {
+ "vlancreate": True,
+ },
+ },
+ },
+ {
+ "name": "traps.vlandelete",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\svlandelete
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps vlandelete",
+ "result": {
+ "traps": {
+ "vlandelete": True,
+ },
+ },
+ },
+ {
+ "name": "traps.vrfmib",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\svrfmib
+ (\s(?P<vrf_up>vrf-up))?
+ (\s(?P<vrf_down>vrf-down))?
+ (\s(?P<vnet_trunk_up>vnet-trunk-up))?
+ (\s(?P<vnet_trunk_down>vnet-trunk-down))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps vrfmib"
+ "{{ ' vrf-up' if traps.vrfmib.vrf_up|d(False) else ''}}"
+ "{{ ' vrf-down' if traps.vrfmib.vrf_down|d(False) else ''}}"
+ "{{ ' vnet-trunk-up' if traps.vrfmib.vnet_trunk_up|d(False) else ''}}"
+ "{{ ' vnet-trunk-down' if traps.vrfmib.vnet_trunk_down|d(False) else ''}}",
+ "result": {
+ "traps": {
+ "vrfmib": {
+ "vrf_up": "{{ not not vrf_up }}",
+ "vrf_down": "{{ not not vrf_down }}",
+ "vnet_trunk_up": "{{ not not vnet_trunk_up }}",
+ "vnet_trunk_down": "{{ not not vnet_trunk_down }}",
},
},
},
},
{
+ "name": "traps.vrrp",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\svrrp
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps vrrp",
+ "result": {
+ "traps": {
+ "vrrp": True,
+ },
+ },
+ },
+ {
+ "name": "traps.vswitch",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\svswitch
+ (\s(?P<dual_active>dual-active))?
+ (\s(?P<vsl>vsl))?
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps vswitch"
+ "{{ ' dual-active' if traps.vswitch.dual_active|d(False) else '' }}"
+ "{{ ' vsl' if traps.vswitch.vsl|d(False) else '' }}",
+ "result": {
+ "traps": {
+ "vswitch": {
+ "enable": True,
+ "dual_active": "{{ not not dual_active }}",
+ "vsl": "{{ not not vsl }}",
+ },
+ },
+ },
+ },
+ {
+ "name": "traps.vtp",
+ "getval": re.compile(
+ r"""
+ ^snmp-server\senable\straps\svtp
+ """, re.VERBOSE,
+ ),
+ "setval": "snmp-server enable traps vtp",
+ "result": {
+ "traps": {
+ "vtp": True,
+ },
+ },
+ },
+ {
"name": "system_shutdown",
"getval": re.compile(
r"""
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/static_routes.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/static_routes.py
index 790f0c8df..a43d59cf7 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/static_routes.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/static_routes.py
@@ -37,7 +37,7 @@ class Static_routesTemplate(NetworkTemplate):
(\svrf\s(?P<vrf>\S+))?
(\s(?P<dest>\S+))
(\s(?P<netmask>\S+))
- (\s(?P<interface>(ACR|ATM-ACR|Analysis-Module|AppNav-Compress|AppNav-UnCompress|Async|Auto-Template|BD-VIF|BDI|BVI|Bluetooth|CDMA-Ix|CEM-ACR|CEM-PG|CTunnel|Container|Dialer|EsconPhy|Ethernet-Internal|Fcpa|Filter|Filtergroup|GigabitEthernet|IMA-ACR|LongReachEthernet|Loopback|Lspvif|MFR|Multilink|NVI|Null|PROTECTION_GROUP|Port-channel|Portgroup|Pos-channel|SBC|SDH_ACR|SERIAL-ACR|SONET_ACR|SSLVPN-VIF|SYSCLOCK|Serial-PG|Service-Engine|TLS-VIF|Tunnel|VPN|Vif|Vir-cem-ACR|Virtual-PPP|Virtual-TokenRing)\d+))?
+ (\s(?P<interface>(ACR|ATM-ACR|Analysis-Module|AppNav-Compress|AppNav-UnCompress|Async|Auto-Template|BD-VIF|BDI|BVI|Bluetooth|CDMA-Ix|CEM-ACR|CEM-PG|CTunnel|Container|Dialer|EsconPhy|Ethernet-Internal|Fcpa|Filter|Filtergroup|GigabitEthernet|IMA-ACR|LongReachEthernet|Loopback|Lspvif|MFR|Multilink|NVI|Null|PROTECTION_GROUP|Port-channel|Portgroup|Pos-channel|SBC|SDH_ACR|SERIAL-ACR|SONET_ACR|SSLVPN-VIF|SYSCLOCK|Serial-PG|Service-Engine|TLS-VIF|Tunnel|VPN|Vif|Vir-cem-ACR|Virtual-PPP|Virtual-TokenRing)\S+))?
(\s(?P<forward_router_address>(?!multicast|dhcp|global|tag|track|permanent|name)\S+))?
(\s(?P<distance_metric>\d+))?
(\stag\s(?P<tag>\d+))?
@@ -93,7 +93,7 @@ class Static_routesTemplate(NetworkTemplate):
(\stopology\s(?P<topology>\S+))?
(\svrf\s(?P<vrf>\S+))?
(\s(?P<dest>\S+))
- (\s(?P<interface>(ACR|ATM-ACR|Analysis-Module|AppNav-Compress|AppNav-UnCompress|Async|Auto-Template|BD-VIF|BDI|BVI|Bluetooth|CDMA-Ix|CEM-ACR|CEM-PG|CTunnel|Container|Dialer|EsconPhy|Ethernet-Internal|Fcpa|Filter|Filtergroup|GigabitEthernet|IMA-ACR|LongReachEthernet|Loopback|Lspvif|MFR|Multilink|NVI|Null|PROTECTION_GROUP|Port-channel|Portgroup|Pos-channel|SBC|SDH_ACR|SERIAL-ACR|SONET_ACR|SSLVPN-VIF|SYSCLOCK|Serial-PG|Service-Engine|TLS-VIF|Tunnel|VPN|Vif|Vir-cem-ACR|Virtual-PPP|Virtual-TokenRing)\d+))?
+ (\s(?P<interface>(ACR|ATM-ACR|Analysis-Module|AppNav-Compress|AppNav-UnCompress|Async|Auto-Template|BD-VIF|BDI|BVI|Bluetooth|CDMA-Ix|CEM-ACR|CEM-PG|CTunnel|Container|Dialer|EsconPhy|Ethernet-Internal|Fcpa|Filter|Filtergroup|GigabitEthernet|IMA-ACR|LongReachEthernet|Loopback|Lspvif|MFR|Multilink|NVI|Null|PROTECTION_GROUP|Port-channel|Portgroup|Pos-channel|SBC|SDH_ACR|SERIAL-ACR|SONET_ACR|SSLVPN-VIF|SYSCLOCK|Serial-PG|Service-Engine|TLS-VIF|Tunnel|VPN|Vif|Vir-cem-ACR|Virtual-PPP|Virtual-TokenRing)\S+))?
(\s(?P<forward_router_address>(?!multicast|unicast|tag|track|permanent|name)\S+))?
(\s(?P<distance_metric>\d+))?
(\s(?P<multicast>multicast))?
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/vxlan_vtep.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/vxlan_vtep.py
new file mode 100644
index 000000000..ed9517b17
--- /dev/null
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/rm_templates/vxlan_vtep.py
@@ -0,0 +1,131 @@
+# -*- 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 Vxlan_vtep parser templates file. This contains
+a list of parser definitions and associated functions that
+facilitates both facts gathering and native command generation for
+the given network resource.
+"""
+
+import re
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import (
+ NetworkTemplate,
+)
+
+
+class Vxlan_vtepTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ super(Vxlan_vtepTemplate, self).__init__(lines=lines, tmplt=self, module=module)
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "interface",
+ "getval": re.compile(
+ r"""^interface\s(?P<interface>\S+)$""",
+ re.VERBOSE,
+ ),
+ "setval": "interface {{ interface }}",
+ "result": {"{{ interface }}": {"interface": "{{ interface }}"}},
+ "shared": True,
+ },
+ {
+ "name": "source_interface",
+ "getval": re.compile(
+ r"""\s+source-interface
+ \s(?P<source_interface>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "source-interface {{ source_interface }}",
+ "result": {"{{ interface }}": {"source_interface": "{{ source_interface }}"}},
+ },
+ {
+ "name": "host_reachability_bgp",
+ "getval": re.compile(
+ r"""\s+host-reachability\sprotocol\sbgp$""",
+ re.VERBOSE,
+ ),
+ "setval": "host-reachability protocol bgp",
+ "result": {
+ "{{ interface }}": {
+ "host_reachability_bgp": True,
+ },
+ },
+ },
+ # member vni starts
+ {
+ "name": "replication",
+ "getval": re.compile(
+ r"""
+ \s+member\svni\s(?P<vni>\d+)\s(?P<type>mcast-group|ingress-replication)
+ (\s(?P<ipv4_mcast_group>[\d.]+))?
+ (\s(?P<ipv6_mcast_group>[\da-fA-F:]+))?
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "member vni {{ vni }}"
+ "{{ (' ' + 'ingress-replication') if replication.type == 'ingress' else (' ' + 'mcast-group') }}"
+ "{{ (' ' + replication.mcast_group.ipv4) if replication.mcast_group is defined and "
+ "replication.mcast_group.ipv4 is defined and replication.type == 'static' else '' }}"
+ "{{ (' ' + replication.mcast_group.ipv6) if replication.mcast_group is defined and "
+ "replication.mcast_group.ipv6 is defined and replication.type == 'static' else '' }}",
+ "result": {
+ "{{ interface }}": {
+ "member": {
+ "vni": {
+ "l2vni": [
+ {
+ "vni": "{{ vni }}",
+ "replication": {
+ "type": "{{ 'ingress' if type == 'ingress-replication' else 'static' }}",
+ "mcast_group": {
+ "ipv4": "{{ ipv4_mcast_group }}",
+ "ipv6": "{{ ipv6_mcast_group }}",
+ },
+ },
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ {
+ "name": "vrf",
+ "getval": re.compile(
+ r"""
+ \s+member\svni
+ \s(?P<vni>\d+)
+ \svrf\s(?P<vrf>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "member vni {{ vni }} vrf {{ vrf }}",
+ "result": {
+ "{{ interface }}": {
+ "member": {
+ "vni": {
+ "l3vni": [
+ {
+ "vni": "{{ vni }}",
+ "vrf": "{{ vrf }}",
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
+ # member vni ends
+ ]
+ # fmt: on
diff --git a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/utils/utils.py b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/utils/utils.py
index 80b4b084d..f3038f7f2 100644
--- a/ansible_collections/cisco/ios/plugins/module_utils/network/ios/utils/utils.py
+++ b/ansible_collections/cisco/ios/plugins/module_utils/network/ios/utils/utils.py
@@ -77,7 +77,7 @@ def new_dict_to_set(input_dict, temp_list, test_set, count=0):
temp_list.append(k)
for each in v:
if isinstance(each, dict):
- if [True for i in each.values() if type(i) == list]:
+ if [True for i in each.values() if isinstance(i, list)]:
new_dict_to_set(each, temp_list, test_set, count)
else:
new_dict_to_set(each, temp_list, test_set, 0)
@@ -105,9 +105,12 @@ def new_dict_to_set(input_dict, temp_list, test_set, count=0):
expand_dict(new_dict)
if tuple(iteritems(temp_dict)) not in test_set:
test_set.add(tuple(iteritems(temp_dict)))
+ return test_dict
-def dict_to_set(sample_dict):
+def dict_to_set(sample_dict, sort_dictionary=False):
+ if sort_dictionary:
+ sample_dict = sort_dict(sample_dict)
# Generate a set with passed dictionary for comparison
test_dict = dict()
if isinstance(sample_dict, dict):
@@ -421,3 +424,13 @@ def vlan_range_to_list(vlans):
result.append(a)
return numerical_sort(result)
return result
+
+
+def sort_dict(dictionary):
+ sorted_dict = dict()
+ for key, value in sorted(dictionary.items()):
+ if isinstance(value, dict):
+ sorted_dict[key] = sort_dict(value)
+ else:
+ sorted_dict[key] = value
+ return sorted_dict