summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGomathiselviS <gomathiselvi@gmail.com>2021-02-24 12:16:02 -0500
committerGitHub <noreply@github.com>2021-02-24 17:16:02 +0000
commita679a918cb0474a0eb5db73f925e612b4863c177 (patch)
tree14756d2a168b6fadc3ed8289acabc33ac565fe39
parentdf81f31331b2b1b4ab894da44532cb3ea245f83a (diff)
downloadvyos-ansible-old-a679a918cb0474a0eb5db73f925e612b4863c177.tar.gz
vyos-ansible-old-a679a918cb0474a0eb5db73f925e612b4863c177.zip
Add vyos_bgp_global resource module (#125)
Add vyos_bgp_global resource module Reviewed-by: https://github.com/apps/ansible-zuul
-rw-r--r--changelogs/fragments/bgp_global_resource_module.yaml3
-rw-r--r--meta/runtime.yml6
-rw-r--r--plugins/module_utils/network/vyos/argspec/bgp_global/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/argspec/bgp_global/bgp_global.py290
-rw-r--r--plugins/module_utils/network/vyos/config/bgp_global/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py426
-rw-r--r--plugins/module_utils/network/vyos/facts/bgp_global/__init__.py0
-rw-r--r--plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py88
-rw-r--r--plugins/module_utils/network/vyos/facts/facts.py4
-rw-r--r--plugins/module_utils/network/vyos/rm_templates/bgp_global.py2043
-rw-r--r--plugins/modules/vyos_bgp_global.py1440
-rw-r--r--tests/integration/targets/vyos_bgp_global/defaults/main.yaml3
-rw-r--r--tests/integration/targets/vyos_bgp_global/meta/main.yaml3
-rw-r--r--tests/integration/targets/vyos_bgp_global/tasks/cli.yaml19
-rw-r--r--tests/integration/targets/vyos_bgp_global/tasks/main.yaml4
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/_parsed_config.cfg30
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/_populate.yaml37
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/_populate_af.yaml12
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/_preconfig.yaml10
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/_remove_config.yaml11
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/deleted.yaml42
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/deleted_af.yaml26
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/empty_config.yaml49
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/gathered.yaml24
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/merged.yaml71
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/parsed.yaml16
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/purged.yaml32
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/rendered.yaml45
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/replaced.yaml72
-rw-r--r--tests/integration/targets/vyos_bgp_global/tests/cli/replaced_af.yaml56
-rw-r--r--tests/integration/targets/vyos_bgp_global/vars/main.yaml150
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_af_config.cfg5
-rw-r--r--tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_config.cfg23
-rw-r--r--tests/unit/modules/network/vyos/test_vyos_bgp_global.py562
-rw-r--r--tests/unit/modules/network/vyos/vyos_module.py8
35 files changed, 5608 insertions, 2 deletions
diff --git a/changelogs/fragments/bgp_global_resource_module.yaml b/changelogs/fragments/bgp_global_resource_module.yaml
new file mode 100644
index 0000000..4d19b12
--- /dev/null
+++ b/changelogs/fragments/bgp_global_resource_module.yaml
@@ -0,0 +1,3 @@
+---
+minor_changes:
+ - Add vyos BGP global resource module.(https://github.com/ansible-collections/vyos.vyos/pull/125).
diff --git a/meta/runtime.yml b/meta/runtime.yml
index e68ed60..1f99057 100644
--- a/meta/runtime.yml
+++ b/meta/runtime.yml
@@ -6,6 +6,10 @@ plugin_routing:
redirect: vyos.vyos.vyos
banner:
redirect: vyos.vyos.vyos
+ vyos_bgp_global:
+ redirect: vyos.vyos.vyos
+ bgp_global:
+ redirect: vyos.vyos.vyos
vyos_command:
redirect: vyos.vyos.vyos
command:
@@ -113,6 +117,8 @@ plugin_routing:
modules:
banner:
redirect: vyos.vyos.vyos_banner
+ bgp_global:
+ redirect: vyos.vyos.vyos_bgp_global
command:
redirect: vyos.vyos.vyos_command
config:
diff --git a/plugins/module_utils/network/vyos/argspec/bgp_global/__init__.py b/plugins/module_utils/network/vyos/argspec/bgp_global/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/bgp_global/__init__.py
diff --git a/plugins/module_utils/network/vyos/argspec/bgp_global/bgp_global.py b/plugins/module_utils/network/vyos/argspec/bgp_global/bgp_global.py
new file mode 100644
index 0000000..4192a84
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/bgp_global/bgp_global.py
@@ -0,0 +1,290 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The arg spec for the vyos_bgp_global module
+"""
+
+
+class Bgp_globalArgs(object): # pylint: disable=R0903
+ """The arg spec for the vyos_bgp_global module"""
+
+ def __init__(self, **kwargs):
+ pass
+
+ argument_spec = {
+ "running_config": {"type": "str"},
+ "state": {
+ "default": "merged",
+ "type": "str",
+ "choices": [
+ "merged",
+ "replaced",
+ "deleted",
+ "gathered",
+ "parsed",
+ "rendered",
+ "purged",
+ ],
+ },
+ "config": {
+ "type": "dict",
+ "options": {
+ "redistribute": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "route_map": {"type": "str"},
+ "metric": {"type": "int"},
+ "protocol": {
+ "type": "str",
+ "choices": [
+ "connected",
+ "kernel",
+ "ospf",
+ "rip",
+ "static",
+ ],
+ },
+ },
+ },
+ "network": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "backdoor": {"type": "bool"},
+ "route_map": {"type": "str"},
+ "address": {"type": "str"},
+ },
+ },
+ "maximum_paths": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "path": {"type": "str"},
+ "count": {"type": "int"},
+ },
+ },
+ "aggregate_address": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "summary_only": {"type": "bool"},
+ "as_set": {"type": "bool"},
+ "prefix": {"type": "str"},
+ },
+ },
+ "timers": {
+ "type": "dict",
+ "options": {
+ "holdtime": {"type": "int"},
+ "keepalive": {"type": "int"},
+ },
+ },
+ "neighbor": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "shutdown": {"type": "bool"},
+ "weight": {"type": "int"},
+ "default_originate": {"type": "str"},
+ "peer_group_name": {"type": "str"},
+ "route_reflector_client": {"type": "bool"},
+ "strict_capability_match": {"type": "bool"},
+ "remove_private_as": {"type": "bool"},
+ "as_override": {"type": "bool"},
+ "port": {"type": "int"},
+ "soft_reconfiguration": {"type": "bool"},
+ "nexthop_self": {"type": "bool"},
+ "remote_as": {"type": "int"},
+ "ebgp_multihop": {"type": "int"},
+ "route_map": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "action": {
+ "type": "str",
+ "choices": ["export", "import"],
+ },
+ "route_map": {"type": "str"},
+ },
+ },
+ "distribute_list": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "action": {
+ "type": "str",
+ "choices": ["export", "import"],
+ },
+ "acl": {"type": "int"},
+ },
+ },
+ "allowas_in": {"type": "int"},
+ "passive": {"type": "bool"},
+ "ttl_security": {"type": "int"},
+ "peer_group": {"type": "bool"},
+ "maximum_prefix": {"type": "int"},
+ "prefix_list": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "action": {
+ "type": "str",
+ "choices": ["export", "import"],
+ },
+ "prefix_list": {"type": "str"},
+ },
+ },
+ "update_source": {"type": "str"},
+ "description": {"type": "str"},
+ "local_as": {"type": "int"},
+ "route_server_client": {"type": "bool"},
+ "attribute_unchanged": {
+ "type": "dict",
+ "options": {
+ "as_path": {"type": "bool"},
+ "med": {"type": "bool"},
+ "next_hop": {"type": "bool"},
+ },
+ },
+ "disable_connected_check": {"type": "bool"},
+ "address": {"type": "str"},
+ "password": {"type": "str"},
+ "disable_send_community": {
+ "type": "str",
+ "choices": ["extended", "standard"],
+ },
+ "unsuppress_map": {"type": "str"},
+ "override_capability": {"type": "bool"},
+ "filter_list": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "action": {
+ "type": "str",
+ "choices": ["export", "import"],
+ },
+ "path_list": {"type": "str"},
+ },
+ },
+ "capability": {
+ "type": "dict",
+ "options": {
+ "orf": {
+ "type": "str",
+ "choices": ["send", "receive"],
+ },
+ "dynamic": {"type": "bool"},
+ },
+ },
+ "timers": {
+ "type": "dict",
+ "options": {
+ "holdtime": {"type": "int"},
+ "connect": {"type": "int"},
+ "keepalive": {"type": "int"},
+ },
+ },
+ "disable_capability_negotiation": {"type": "bool"},
+ "advertisement_interval": {"type": "int"},
+ },
+ },
+ "bgp_params": {
+ "type": "dict",
+ "options": {
+ "router_id": {"type": "str"},
+ "distance": {
+ "elements": "dict",
+ "type": "list",
+ "options": {
+ "prefix": {"type": "int"},
+ "type": {
+ "type": "str",
+ "choices": [
+ "external",
+ "internal",
+ "local",
+ ],
+ },
+ "value": {"type": "int"},
+ },
+ },
+ "dampening": {
+ "type": "dict",
+ "options": {
+ "half_life": {"type": "int"},
+ "start_suppress_time": {"type": "int"},
+ "max_suppress_time": {"type": "int"},
+ "re_use": {"type": "int"},
+ },
+ },
+ "graceful_restart": {"type": "int"},
+ "scan_time": {"type": "int"},
+ "always_compare_med": {"type": "bool"},
+ "no_fast_external_failover": {"type": "bool"},
+ "bestpath": {
+ "type": "dict",
+ "options": {
+ "med": {
+ "type": "str",
+ "choices": ["confed", "missing-as-worst"],
+ },
+ "as_path": {
+ "type": "str",
+ "choices": ["confed", "ignore"],
+ },
+ "compare_routerid": {"type": "bool"},
+ },
+ },
+ "enforce_first_as": {"type": "bool"},
+ "default": {
+ "type": "dict",
+ "options": {
+ "local_pref": {"type": "int"},
+ "no_ipv4_unicast": {"type": "bool"},
+ },
+ },
+ "cluster_id": {"type": "str"},
+ "no_client_to_client_reflection": {"type": "bool"},
+ "deterministic_med": {"type": "bool"},
+ "log_neighbor_changes": {"type": "bool"},
+ "disable_network_import_check": {"type": "bool"},
+ "confederation": {
+ "type": "list",
+ "elements": "dict",
+ "options": {
+ "peers": {"type": "int"},
+ "identifier": {"type": "int"},
+ },
+ },
+ },
+ },
+ "as_number": {"type": "int"},
+ },
+ },
+ } # pylint: disable=C0301
diff --git a/plugins/module_utils/network/vyos/config/bgp_global/__init__.py b/plugins/module_utils/network/vyos/config/bgp_global/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/bgp_global/__init__.py
diff --git a/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py b/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py
new file mode 100644
index 0000000..0a5f15d
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/bgp_global/bgp_global.py
@@ -0,0 +1,426 @@
+#
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+#
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+"""
+The vyos_bgp_global 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.
+"""
+import re
+from ansible.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+ dict_merge,
+)
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.resource_module import (
+ ResourceModule,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import (
+ Facts,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.bgp_global import (
+ Bgp_globalTemplate,
+)
+
+
+class Bgp_global(ResourceModule):
+ """
+ The vyos_bgp_global config class
+ """
+
+ def __init__(self, module):
+ super(Bgp_global, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="bgp_global",
+ tmplt=Bgp_globalTemplate(),
+ )
+ self.parsers = []
+
+ 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 = {}
+
+ if (
+ self.want.get("as_number") == self.have.get("as_number")
+ or not self.have
+ ):
+ if self.want:
+ wantd = {self.want["as_number"]: self.want}
+ if self.have:
+ haved = {self.have["as_number"]: self.have}
+ else:
+ self._module.fail_json(
+ msg="Only one bgp instance is allowed per device"
+ )
+
+ # turn all lists of dicts into dicts prior to merge
+ for entry in wantd, haved:
+ self._bgp_global_list_to_dict(entry)
+
+ # 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 == "purged":
+ h_del = {}
+ for k, v in iteritems(haved):
+ if k in wantd or not wantd:
+ h_del.update({k: v})
+ for num, entry in iteritems(h_del):
+ self.commands.append(
+ self._tmplt.render({"as_number": num}, "router", True)
+ )
+ wantd = {}
+
+ if self.state == "deleted":
+ self._compare(want={}, have=self.have)
+ wantd = {}
+
+ 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 Bgp_global network resource.
+ """
+ parsers = ["maximum_paths", "timers"]
+ self._compare_neighbor(want, have)
+ self._compare_lists(want, have)
+ self._compare_bgp_params(want, have)
+ for name, entry in iteritems(want):
+ if name != "as_number":
+ self.compare(
+ parsers=parsers,
+ want={"as_number": want["as_number"], name: entry},
+ have={
+ "as_number": want["as_number"],
+ name: have.pop(name, {}),
+ },
+ )
+ for name, entry in iteritems(have):
+ if name != "as_number":
+ self.compare(
+ parsers=parsers,
+ want={},
+ have={"as_number": have["as_number"], name: entry},
+ )
+ # Do the negation first
+ command_set = []
+ for cmd in self.commands:
+ if cmd not in command_set:
+ if "delete" in cmd:
+ command_set.insert(0, cmd)
+ else:
+ command_set.append(cmd)
+ self.commands = command_set
+
+ def _compare_neighbor(self, want, have):
+
+ parsers = [
+ "neighbor.advertisement_interval",
+ "neighbor.allowas_in",
+ "neighbor.as_override",
+ "neighbor.attribute_unchanged.as_path",
+ "neighbor.attribute_unchanged.med",
+ "neighbor.attribute_unchanged.next_hop",
+ "neighbor.capability_dynamic",
+ "neighbor.capability_orf",
+ "neighbor.default_originate",
+ "neighbor.description",
+ "neighbor.disable_capability_negotiation",
+ "neighbor.disable_connected_check",
+ "neighbor.disable_send_community",
+ "neighbor.distribute_list",
+ "neighbor.ebgp_multihop",
+ "neighbor.filter_list",
+ "neighbor.local_as",
+ "neighbor.maximum_prefix",
+ "neighbor.nexthop_self",
+ "neighbor.override_capability",
+ "neighbor.passive",
+ "neighbor.password",
+ "neighbor.peer_group_name",
+ "neighbor.port",
+ "neighbor.prefix_list",
+ "neighbor.remote_as",
+ "neighbor.remove_private_as",
+ "neighbor.route_map",
+ "neighbor.route_reflector_client",
+ "neighbor.route_server_client",
+ "neighbor.shutdown",
+ "neighbor.soft_reconfiguration",
+ "neighbor.strict_capability_match",
+ "neighbor.unsuppress_map",
+ "neighbor.update_source",
+ "neighbor.weight",
+ "neighbor.ttl_security",
+ "neighbor.timers",
+ "network.backdoor",
+ "network.route_map",
+ ]
+ wneigh = want.pop("neighbor", {})
+ hneigh = have.pop("neighbor", {})
+ self._compare_neigh_lists(wneigh, hneigh)
+ for name, entry in iteritems(wneigh):
+ for k, v in entry.items():
+ if k == "address":
+ continue
+ if hneigh.get(name):
+ h = {"address": name, k: hneigh[name].pop(k, {})}
+ else:
+ h = {}
+ self.compare(
+ parsers=parsers,
+ want={
+ "as_number": want["as_number"],
+ "neighbor": {"address": name, k: v},
+ },
+ have={"as_number": want["as_number"], "neighbor": h},
+ )
+ for name, entry in iteritems(hneigh):
+ if name not in wneigh.keys():
+ if self._check_af(name):
+ msg = "Use the _bgp_address_family module to delete the address_family under neighbor {0}, before replacing/deleting the neighbor.".format(
+ name
+ )
+ self._module.fail_json(msg=msg)
+ else:
+ self.commands.append(
+ "delete protocols bgp "
+ + str(have["as_number"])
+ + " neighbor "
+ + name
+ )
+ continue
+ for k, v in entry.items():
+ self.compare(
+ parsers=parsers,
+ want={},
+ have={
+ "as_number": have["as_number"],
+ "neighbor": {"address": name, k: v},
+ },
+ )
+
+ def _compare_bgp_params(self, want, have):
+ parsers = [
+ "bgp_params.always_compare_med",
+ "bgp_params.bestpath.as_path",
+ "bgp_params.bestpath.compare_routerid",
+ "bgp_params.bestpath.med",
+ "bgp_params.cluster_id",
+ "bgp_params.confederation",
+ "bgp_params.dampening_half_life",
+ "bgp_params.dampening_max_suppress_time",
+ "bgp_params.dampening_re_use",
+ "bgp_params.dampening_start_suppress_time",
+ "bgp_params.default",
+ "bgp_params.deterministic_med",
+ "bgp_params.disbale_network_import_check",
+ "bgp_params.enforce_first_as",
+ "bgp_params.graceful_restart",
+ "bgp_params.log_neighbor_changes",
+ "bgp_params.no_client_to_client_reflection",
+ "bgp_params.no_fast_external_failover",
+ "bgp_params.routerid",
+ "bgp_params.scan_time",
+ ]
+ wbgp = want.pop("bgp_params", {})
+ hbgp = have.pop("bgp_params", {})
+ for name, entry in iteritems(wbgp):
+ if name == "confederation":
+ if entry != hbgp.pop(name, {}):
+ self.addcmd(
+ {
+ "as_number": want["as_number"],
+ "bgp_params": {name: entry},
+ },
+ "bgp_params.confederation",
+ False,
+ )
+ elif name == "distance":
+ if entry != hbgp.pop(name, {}):
+ distance_parsers = [
+ "bgp_params.distance.global",
+ "bgp_params.distance.prefix",
+ ]
+ for distance_type in entry:
+ self.compare(
+ parsers=distance_parsers,
+ want={
+ "as_number": want["as_number"],
+ "bgp_params": {name: distance_type},
+ },
+ have={
+ "as_number": want["as_number"],
+ "bgp_params": {name: hbgp.pop(name, {})},
+ },
+ )
+ else:
+ self.compare(
+ parsers=parsers,
+ want={
+ "as_number": want["as_number"],
+ "bgp_params": {name: entry},
+ },
+ have={
+ "as_number": want["as_number"],
+ "bgp_params": {name: hbgp.pop(name, {})},
+ },
+ )
+ if not wbgp and hbgp:
+ self.commands.append(
+ "delete protocols bgp "
+ + str(have["as_number"])
+ + " parameters"
+ )
+ hbgp = {}
+ for name, entry in iteritems(hbgp):
+ if name == "confederation":
+ self.commands.append(
+ "delete protocols bgp "
+ + str(have["as_number"])
+ + " parameters confederation"
+ )
+ elif name == "distance":
+ distance_parsers = [
+ "bgp_params.distance.global",
+ "bgp_params.distance.prefix",
+ ]
+ self.compare(
+ parsers=distance_parsers,
+ want={},
+ have={
+ "as_number": have["as_number"],
+ "bgp_params": {name: entry[0]},
+ },
+ )
+ else:
+ self.compare(
+ parsers=parsers,
+ want={},
+ have={
+ "as_number": have["as_number"],
+ "bgp_params": {name: entry},
+ },
+ )
+
+ def _compare_lists(self, want, have):
+ parsers = [
+ "network.backdoor",
+ "network.route_map",
+ "redistribute.metric",
+ "redistribute.route_map",
+ "aggregate_address",
+ ]
+ for attrib in ["redistribute", "network", "aggregate_address"]:
+ wdict = want.pop(attrib, {})
+ hdict = have.pop(attrib, {})
+ for key, entry in iteritems(wdict):
+ if entry != hdict.get(key, {}):
+ self.compare(
+ parsers=parsers,
+ want={"as_number": want["as_number"], attrib: entry},
+ have=hdict.pop(key, {}),
+ )
+ hdict.pop(key, {})
+ # remove remaining items in have for replaced
+ if not wdict and hdict:
+ attrib = re.sub("_", "-", attrib)
+ self.commands.append(
+ "delete protocols bgp "
+ + str(have["as_number"])
+ + " "
+ + attrib
+ )
+ hdict = {}
+ for key, entry in iteritems(hdict):
+ self.compare(
+ parsers=parsers,
+ want={},
+ have={"as_number": have["as_number"], attrib: entry},
+ )
+
+ def _compare_neigh_lists(self, want, have):
+ for attrib in [
+ "distribute_list",
+ "filter_list",
+ "prefix_list",
+ "route_map",
+ ]:
+ wdict = want.pop(attrib, {})
+ hdict = have.pop(attrib, {})
+ for key, entry in iteritems(wdict):
+ if entry != hdict.pop(key, {}):
+ self.addcmd(entry, "neighbor.{0}".format(attrib), False)
+ # remove remaining items in have for replaced
+ for entry in hdict.values():
+ self.addcmd(entry, "neighbor.{0}".format(attrib), True)
+
+ def _bgp_global_list_to_dict(self, entry):
+ for name, proc in iteritems(entry):
+ if "neighbor" in proc:
+ neigh_dict = {}
+ for entry in proc.get("neighbor", []):
+ neigh_dict.update({entry["address"]: entry})
+ proc["neighbor"] = neigh_dict
+
+ if "network" in proc:
+ network_dict = {}
+ for entry in proc.get("network", []):
+ network_dict.update({entry["address"]: entry})
+ proc["network"] = network_dict
+
+ if "aggregate_address" in proc:
+ agg_dict = {}
+ for entry in proc.get("aggregate_address", []):
+ agg_dict.update({entry["prefix"]: entry})
+ proc["aggregate_address"] = agg_dict
+
+ if "redistribute" in proc:
+ redis_dict = {}
+ for entry in proc.get("redistribute", []):
+ redis_dict.update({entry["protocol"]: entry})
+ proc["redistribute"] = redis_dict
+
+ def _check_af(self, neighbor):
+ af_present = False
+ if self._connection:
+ config_lines = self._get_config(self._connection).splitlines()
+ for line in config_lines:
+ if "address-family" in line:
+ af_present = True
+ return af_present
+
+ def _get_config(self, connection):
+ return connection.get(
+ 'show configuration commands | match "set protocols bgp .* neighbor"'
+ )
diff --git a/plugins/module_utils/network/vyos/facts/bgp_global/__init__.py b/plugins/module_utils/network/vyos/facts/bgp_global/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/bgp_global/__init__.py
diff --git a/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py b/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py
new file mode 100644
index 0000000..3cfa83c
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/bgp_global/bgp_global.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+"""
+The vyos bgp_global fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import (
+ utils,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.bgp_global import (
+ Bgp_globalTemplate,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.bgp_global.bgp_global import (
+ Bgp_globalArgs,
+)
+import re
+
+
+class Bgp_globalFacts(object):
+ """The vyos bgp_global facts class"""
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = Bgp_globalArgs.argument_spec
+
+ def get_device_data(self, connection):
+ return connection.get(
+ 'show configuration commands | match "set protocols bgp"'
+ )
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for Bgp_global network resource
+
+ :param connection: the device connection
+ :param ansible_facts: Facts dictionary
+ :param data: previously collected conf
+
+ :rtype: dictionary
+ :returns: facts
+ """
+ facts = {}
+ objs = {}
+ config_lines = []
+
+ if not data:
+ data = self.get_device_data(connection)
+
+ for resource in data.splitlines():
+ if "address-family" not in resource:
+ config_lines.append(re.sub("'", "", resource))
+
+ bgp_global_parser = Bgp_globalTemplate(lines=config_lines)
+ objs = bgp_global_parser.parse()
+
+ if "neighbor" in objs:
+ objs["neighbor"] = list(objs["neighbor"].values())
+ objs["neighbor"] = sorted(
+ objs["neighbor"], key=lambda k: k["address"]
+ )
+ if "network" in objs:
+ objs["network"] = sorted(
+ objs["network"], key=lambda k: k["address"]
+ )
+ if "aggregate_address" in objs:
+ objs["aggregate_address"] = sorted(
+ objs["aggregate_address"], key=lambda k: k["prefix"]
+ )
+
+ ansible_facts["ansible_network_resources"].pop("bgp_global", None)
+
+ params = utils.remove_empties(
+ utils.validate_config(self.argument_spec, {"config": objs})
+ )
+
+ facts["bgp_global"] = params.get("config", [])
+ ansible_facts["ansible_network_resources"].update(facts)
+
+ return ansible_facts
diff --git a/plugins/module_utils/network/vyos/facts/facts.py b/plugins/module_utils/network/vyos/facts/facts.py
index c2766de..95eff2e 100644
--- a/plugins/module_utils/network/vyos/facts/facts.py
+++ b/plugins/module_utils/network/vyos/facts/facts.py
@@ -49,6 +49,9 @@ from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospf_interfaces.ospf_interfaces import (
Ospf_interfacesFacts,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_global.bgp_global import (
+ Bgp_globalFacts,
+)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import (
Default,
Neighbors,
@@ -70,6 +73,7 @@ FACT_RESOURCE_SUBSETS = dict(
ospfv3=Ospfv3Facts,
ospfv2=Ospfv2Facts,
ospf_interfaces=Ospf_interfacesFacts,
+ bgp_global=Bgp_globalFacts,
)
diff --git a/plugins/module_utils/network/vyos/rm_templates/bgp_global.py b/plugins/module_utils/network/vyos/rm_templates/bgp_global.py
new file mode 100644
index 0000000..aff6258
--- /dev/null
+++ b/plugins/module_utils/network/vyos/rm_templates/bgp_global.py
@@ -0,0 +1,2043 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+"""
+The Bgp_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.module_utils.six import iteritems
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network_template import (
+ NetworkTemplate,
+)
+
+
+def _tmplt_bgp_params_confederation(config_data):
+ command = []
+ for list_el in config_data["bgp_params"]["confederation"]:
+ for k, v in iteritems(list_el):
+ command.append(
+ "protocols bgp {as_number} parameters confederation ".format(
+ **config_data
+ )
+ + k
+ + " "
+ + str(v)
+ )
+
+ return command
+
+
+def _tmplt_bgp_maximum_paths(config_data):
+ command = []
+ for list_el in config_data["maximum_paths"]:
+ command.append(
+ "protocols bgp {as_number} maximum-paths ".format(**config_data)
+ + list_el["path"]
+ + " "
+ + str(list_el["count"])
+ )
+ return command
+
+
+def _tmplt_bgp_aggregate_address(config_data):
+ command = "protocols bgp {as_number} aggregate-address".format(
+ **config_data
+ )
+ if config_data["aggregate_address"].get("as_set"):
+ command += " {prefix} as-set".format(
+ **config_data["aggregate_address"]
+ )
+ if config_data["aggregate_address"].get("summary_only"):
+ command += " {prefix} summary-only".format(
+ **config_data["aggregate_address"]
+ )
+ return command
+
+
+def _tmplt_delete_bgp_maximum_paths(config_data):
+ command = "protocols bgp {as_number} maximum-paths".format(**config_data)
+ return command
+
+
+def _tmplt_bgp_params_default(config_data):
+ command = "protocols bgp {as_number} parameters default".format(
+ **config_data
+ )
+ if config_data["bgp_params"]["default"].get("no_ipv4_unicast"):
+ command += " no-ipv4-unicast"
+ if config_data["bgp_params"]["default"].get("local_pref"):
+ command += " local-pref {local_pref}".format(
+ **config_data["bgp_params"]["default"]
+ )
+ return command
+
+
+def _tmplt_bgp_delete_redistribute(config_data):
+ command = (
+ "protocols bgp {as_number} redistribute ".format(**config_data)
+ + config_data["redistribute"]["protocol"]
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_timers(config_data):
+ command = []
+ for k, v in iteritems(config_data["neighbor"]["timers"]):
+ command.append(
+ "protocols bgp {as_number} neighbor ".format(**config_data)
+ + config_data["neighbor"]["address"]
+ + " timers "
+ + k
+ + " "
+ + str(v)
+ )
+
+ return command
+
+
+def _tmplt_bgp_timers(config_data):
+ command = []
+ for k, v in iteritems(config_data["timers"]):
+ command.append(
+ "protocols bgp {as_number} ".format(**config_data)
+ + "timers "
+ + k
+ + " "
+ + str(v)
+ )
+
+ return command
+
+
+def _tmplt_bgp_neighbor_attribute_unchanged_as_path(config_data):
+ command = "protocols bgp {as_number} ".format(
+ **config_data
+ ) + "neighbor {address} attribute-unchanged as-path".format(
+ **config_data["neighbor"]
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_attribute_unchanged_med(config_data):
+ command = "protocols bgp {as_number} ".format(
+ **config_data
+ ) + "neighbor {address} attribute-unchanged med".format(
+ **config_data["neighbor"]
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_attribute_unchanged_next_hop(config_data):
+ command = "protocols bgp {as_number} ".format(
+ **config_data
+ ) + "neighbor {address} attribute-unchanged next-hop".format(
+ **config_data["neighbor"]
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_distribute_list(config_data):
+ command = []
+ for list_el in config_data["neighbor"]["distribute_list"]:
+ command.append(
+ "protocols bgp {as_number} ".format(**config_data)
+ + "neighbor {address} distribute-list ".format(
+ **config_data["neighbor"]
+ )
+ + list_el["action"]
+ + " "
+ + str(list_el["acl"])
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_route_map(config_data):
+ command = []
+ for list_el in config_data["neighbor"]["route_map"]:
+ command.append(
+ "protocols bgp {as_number} ".format(**config_data)
+ + "neighbor {address} route-map ".format(**config_data["neighbor"])
+ + list_el["action"]
+ + " "
+ + str(list_el["route_map"])
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_prefix_list(config_data):
+ command = []
+ for list_el in config_data["neighbor"]["prefix_list"]:
+ command.append(
+ "protocols bgp {as_number} ".format(**config_data)
+ + "neighbor {address} prefix-list ".format(
+ **config_data["neighbor"]
+ )
+ + list_el["action"]
+ + " "
+ + str(list_el["prefix_list"])
+ )
+ return command
+
+
+def _tmplt_bgp_neighbor_filter_list(config_data):
+ command = []
+ for list_el in config_data["neighbor"]["filter_list"]:
+ command.append(
+ "protocols bgp {as_number} ".format(**config_data)
+ + "neighbor {address} filter-list ".format(
+ **config_data["neighbor"]
+ )
+ + list_el["action"]
+ + " "
+ + str(list_el["path_list"])
+ )
+ return command
+
+
+def _tmplt_bgp_params_distance(config_data):
+ command = (
+ "protocols bgp {as_number} parameters distance global ".format(
+ **config_data
+ )
+ + config_data["bgp_params"]["distance"]["type"]
+ + " "
+ + str(config_data["bgp_params"]["distance"]["value"])
+ )
+ return command
+
+
+class Bgp_globalTemplate(NetworkTemplate):
+ def __init__(self, lines=None):
+ prefix = {"set": "set", "remove": "delete"}
+ super(Bgp_globalTemplate, self).__init__(
+ lines=lines, tmplt=self, prefix=prefix
+ )
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "router",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }}",
+ "compval": "as_number",
+ "result": {
+ "as_number": "{{ as_num }}",
+ }
+ },
+ {
+ "name": "aggregate_address",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+aggregate-address
+ \s+(?P<address>\S+)
+ \s*(?P<as_set>as-set)*
+ \s*(?P<summary_only>summary-only)*
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_aggregate_address,
+ "remval": "protocols bgp {{ as_number }} aggregate-address {{ aggregate_address.prefix }}",
+ "compval": "aggregate_address",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "aggregate_address": [
+ {
+ "prefix": "{{ address }}",
+ "as_set": "{{ True if as_set is defined }}",
+ "summary_only": "{{ True if summary_only is defined }}"
+ }
+ ]
+ }
+ },
+ {
+ "name": "maximum_paths",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+maximum-paths
+ \s+(?P<path>ebgp|ibgp)
+ \s+(?P<count>\d+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_maximum_paths,
+ "remval": _tmplt_delete_bgp_maximum_paths,
+ "compval": "maximum_paths",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "maximum_paths": [
+ {
+ "path": "{{ path }}",
+ "count": "{{ count }}",
+ }
+ ]
+ }
+ },
+ {
+ "name": "neighbor.advertisement_interval",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+advertisement-interval
+ \s+(?P<interval>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} advertisement-interval {{ neighbor.advertisement_interval }}",
+ "remval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} advertisement-interval",
+ "compval": "neighbor.advertisement_interval",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "advertisement_interval": "{{ interval }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.allowas_in",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+allowas-in
+ \s+number
+ \s+(?P<num>\'\d+\')
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} allowas-in number {{ neighbor.allowas_in }}",
+ "compval": "neighbor.allowas_in",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "allowas_in": "{{ count }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.as_override",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+as-override
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} as-override",
+ "compval": "neighbor.as_override",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "as_override": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.attribute_unchanged.as_path",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+attribute-unchanged
+ \s+(?P<val>as-path)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_attribute_unchanged_as_path,
+ "compval": "neighbor.attribute_unchanged",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "attribute_unchanged": {
+ "{{ 'as_path' }}": "{{ True }}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.attribute_unchanged.med",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+attribute-unchanged
+ \s+(?P<val>med)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_attribute_unchanged_med,
+ "compval": "neighbor.attribute_unchanged",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "attribute_unchanged": {
+ "{{ 'med' }}": "{{ True }}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.attribute_unchanged.next_hop",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+attribute-unchanged
+ \s+(?P<val>next-hop)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_attribute_unchanged_next_hop,
+ "compval": "neighbor.attribute_unchanged",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "attribute_unchanged": {
+ "{{ 'next_hop' }}": "{{ True }}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.capability_dynamic",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+capability
+ \s+(?P<dynamic>dynamic)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} capability dynamic",
+ "compval": "neighbor.capability.dynamic",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "capability": {
+ "dynamic": "{{ True if dynamic is defined}}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.capability_orf",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+capability
+ \s+orf
+ \s+prefix-list
+ \s+(?P<orf>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} capability orf prefix-list {{ neighbor.capability.orf }}",
+ "compval": "neighbor.capability.orf",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "capability": {
+ "orf": "{{ orf }}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.default_originate",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+default-originate
+ \s+route-map
+ \s+(?P<map>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} default-originate route-map {{ neighbor.default_originate }}",
+ "compval": "neighbor.advertisement_interval",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "default_originate": "{{ map }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.description",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+description
+ \s+(?P<desc>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} description {{ neighbor.description }}",
+ "compval": "neighbor.description",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "description": "{{ desc }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.disable_capability_negotiation",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+disable-capability-negotiation
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-capability-negotiation",
+ "compval": "neighbor.disable_capability_negotiation",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "disable_capability_negotiation": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.disable_connected_check",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+disable-connected-check
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-connected-check",
+ "compval": "neighbor.disable_connected_check",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "disable_connected_check": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.disable_send_community",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+disable-send-community
+ \s+(?P<comm>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} disable-send-community {{ neighbor.disable_send_community }}",
+ "compval": "neighbor.disable_send_community",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "disable_send_community": "{{ comm }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.distribute_list",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+distribute-list
+ \s+(?P<action>export|import)
+ \s+(?P<list>\d+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_distribute_list,
+ "compval": "neighbor.distribute_list",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "distribute_list": [
+ {
+ "action": "{{ action }}",
+ "acl": "{{ list }}"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.ebgp_multihop",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+ebgp-multihop
+ \s+(?P<hop>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} ebgp-multihop {{ neighbor.ebgp_multihop }}",
+ "compval": "neighbor.ebgp_multihop",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "ebgp_multihop": "{{ hop|int }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.filter_list",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+filter-list
+ \s+(?P<action>export|import)
+ \s+(?P<list>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_filter_list,
+ "compval": "neighbor.filter_list",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "filter_list": [
+ {
+ "action": "{{ action }}",
+ "path_list": "{{ list }}"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.local_as",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+local-as
+ \s+(?P<as>\S+)
+ \s+no-prepend
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} local-as {{ neighbor.local_as }} no-prepend",
+ "compval": "neighbor.local_as",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "local_as": "{{ as }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.maximum_prefix",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+maximum-prefix
+ \s+(?P<num>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} maximum-prefix {{ neighbor.maximum_prefix }}",
+ "compval": "neighbor.maximum_prefix",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "maximum_prefix": "{{ num }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.nexthop_self",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+nexthop-self
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} nexthop-self",
+ "compval": "neighbor.nexthop_self",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "nexthop_self": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.override_capability",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+override-capability
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} override-capability",
+ "compval": "neighbor.override_capability",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "override_capability": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.passive",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+passive
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} nexthop-self",
+ "compval": "neighbor.passive",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "passive": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.password",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+password
+ \s+(?P<pwd>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} password {{ neighbor.address }}",
+ "compval": "neighbor.password",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "password": "{{ pwd }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.peer_group_name",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+peer-group
+ \s+(?P<name>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} peer-group {{ neighbor.peer_group_name }}",
+ "compval": "neighbor.peer_group_name",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "peer_group_name": "{{ name }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.port",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+port
+ \s+(?P<num>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} port {{ neighbor.port }}",
+ "compval": "neighbor.port",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "port": "{{ num|int }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.prefix_list",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+prefix-list
+ \s+(?P<action>export|import)
+ \s+(?P<list>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_prefix_list,
+ "compval": "neighbor.prefix_list",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "prefix_list": [
+ {
+ "action": "{{ action }}",
+ "prefix_list": "{{ list }}"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.remote_as",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+remote-as
+ \s+(?P<num>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} remote-as {{ neighbor.remote_as }}",
+ "compval": "neighbor.remote_as",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "remote_as": "{{ num|int }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.remove_private_as",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+remote-private-as
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} remote-private-as",
+ "compval": "neighbor.remove_private_as",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "remove_private_as": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.route_map",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+route-map
+ \s+(?P<action>export|import)
+ \s+(?P<map>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_route_map,
+ "compval": "neighbor.route_map",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "route_map": [
+ {
+ "action": "{{ action }}",
+ "route_map": "{{ map }}"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.route_reflector_client",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+route-reflector-client
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} router-reflector-client",
+ "compval": "neighbor.route_reflector_client",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "route_reflector_client": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.route_server_client",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+route-server-client
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} route-server-client",
+ "compval": "neighbor.route_server_client",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "route_server_client": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.shutdown",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+shutdown
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} shutdown",
+ "compval": "neighbor.shutdown",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "shutdown": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.soft_reconfiguration",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+soft-reconfiguration
+ \s+inbound
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} soft-reconfiguration",
+ "compval": "neighbor.soft_reconfiguration",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "soft_reconfiguration": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.strict_capability_match",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+strict-capability-match
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} strict-capability-match",
+ "compval": "neighbor.strict_capability_match",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "strict_capability_match": "{{ True }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.unsuppress_map",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+unsuppress-map
+ \s+(?P<map>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} unsuppress-map {{ neighbor.unsuppress_map }}",
+ "compval": "neighbor.unsuppress_map",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "unsuppress_map": "{{ map }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.update_source",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+update-source
+ \s+(?P<src>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} update-source {{ neighbor.update_source }}",
+ "compval": "neighbor.update_source",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "update_source": "{{ src }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.weight",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+weight
+ \s+(?P<num>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} weight {{ neighbor.weight }}",
+ "compval": "neighbor.weight",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "weight": "{{ num }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.ttl_security",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+ttl-security
+ \s+(?P<ttl>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} ttl-security {{ neighbor.ttl_security }}",
+ "compval": "neighbor.ttl_security",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "ttl_security": "{{ ttl|int }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "neighbor.timers",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+neighbor
+ \s+(?P<address>\S+)
+ \s+timers
+ \s+(?P<type>connect|holdtime|keepalive)
+ \s+(?P<sec>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_neighbor_timers,
+ "remval": "protocols bgp {{ as_number }} neighbor {{ neighbor.address }} timers",
+ "compval": "neighbor.timers",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "neighbor": {
+ "{{ address }}": {
+ "address": "{{ address }}",
+ "timers": {
+ "{{ type }}": "{{ sec }}"
+ }
+ }
+ }
+ }
+ },
+ {
+ "name": "network.backdoor",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+network
+ \s+(?P<address>\S+)
+ \s+backdoor
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} network {{ network.address }} backdoor",
+ "remval": "protocols bgp {{ as_number }} network {{ network.address }}",
+ "compval": "network.backdoor",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "network": [
+ {
+ "address": "{{ address }}",
+ "backdoor": "{{ True }}"
+ }
+ ]
+ }
+ },
+ {
+ "name": "network.route_map",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+network
+ \s+(?P<address>\S+)
+ \s+route-map
+ \s+(?P<map>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} network {{ network.address }} route-map {{ network.route_map }}",
+ "remval": "protocols bgp {{ as_number }} network {{ network.address }}",
+ "compval": "network.route_map",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "network": [
+ {
+ "address": "{{ address }}",
+ "route_map": "{{ map }}"
+ }
+ ]
+ }
+ },
+ {
+ "name": "redistribute.metric",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+redistribute
+ \s+(?P<proto>\S+)
+ \s+metric
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} redistribute {{ redistribute.protocol }} metric {{ redistribute.metric }}",
+ "remval": _tmplt_bgp_delete_redistribute,
+ "compval": "redistribute",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "redistribute": [
+ {
+ "protocol": "{{ proto }}",
+ "metric": "{{ val|int }}"
+ }
+ ]
+ }
+ },
+ {
+ "name": "redistribute.route_map",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+redistribute
+ \s+(?P<proto>\S+)
+ \s+route-map
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} redistribute {{ redistribute.protocol }} route-map {{ redistribute.route_map }}",
+ "remval": _tmplt_bgp_delete_redistribute,
+ "compval": "redistribute",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "redistribute": [
+ {
+ "protocol": "{{ proto }}",
+ "route_map": "{{ val }}"
+ }
+ ]
+ }
+ },
+ {
+ "name": "timers",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+timers
+ \s+(?P<type>\S+)
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_timers,
+ "remval": "protocols bgp {{ as_number }} timers",
+ "compval": "timers",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "timers": {
+ "{{ type }}": "{{ val }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.always_compare_med",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+always-compare-med
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters always-compare-med",
+ "compval": "bgp_params.always_compare_med",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "always_compare_med": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.bestpath.as_path",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+bestpath
+ \s+as-path
+ \s+(?P<path>confed|ignore)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters bestpath as-path {{ bgp_params.bestpath.as_path }}",
+ "compval": "bgp_params.bestpath.as_path",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "bestpath": {
+ "as_path": "{{ path }}",
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.bestpath.compare_routerid",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+bestpath
+ \s+compare-routerid
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters bestpath compare-routerid",
+ "compval": "bgp_params.bestpath.compare_routerid",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "bestpath": {
+ "compare_routerid": "{{ True }}",
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.bestpath.med",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+bestpath
+ \s+med
+ \s+(?P<path>confed|missing-as-worst)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters bestpath med {{ bestpath.med }}",
+ "compval": "bgp_params.bestpath.med",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "bestpath": {
+ "med": "{{ path }}",
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.cluster_id",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+cluster-id
+ \s+(?P<id>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters cluster-id {{ bgp_params.cluster_id }}",
+ "compval": "bgp_params.cluster_id",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "cluster_id": "{{ id }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.confederation",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+confederation
+ \s+(?P<type>identifier|peers)
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_params_confederation,
+ "compval": "bgp_params.always_compare_med",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "confederation": [
+ {
+ "peers": "{{ val if type == 'peers' }}",
+ "identifier": "{{ val if type == 'identifier' }}"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "bgp_params.dampening_half_life",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+dampening
+ \s+half-life
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters dampening half-life {{ bgp_params.dampening.half_life}}",
+ "compval": "bgp_params.dampening.half_life",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "dampening": {
+ "half_life": "{{ val }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.dampening_max_suppress_time",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+dampening
+ \s+max-suppress-time
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters dampening max-suppress-time {{ bgp_params.dampening.max_suppress_time}}",
+ "compval": "bgp_params.dampening.max_suppress_time",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "dampening": {
+ "max_suppress_time": "{{ val }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.dampening_re_use",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+dampening
+ \s+re-use
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters dampening re-use {{ bgp_params.dampening.re_use}}",
+ "compval": "bgp_params.dampening.re_use",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "dampening": {
+ "re_use": "{{ val }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.dampening_start_suppress_time",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+dampening
+ \s+start-suppress-time
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters dampening start-suppress-time {{ bgp_params.dampening.start_suppress_time}}",
+ "compval": "bgp_params.dampening.start_suppress_time",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "dampening": {
+ "start_suppress_time": "{{ val }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.default",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+default
+ \s*(?P<no_ipv4_unicast>no-ipv4-unicast)*
+ \s*(?P<local_pref>local-pref\s\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_params_default,
+ "remval": "protocols bgp {{ as_number }} parameters default",
+ "compval": "bgp_params.default",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "default": {
+ "no_ipv4_unicast": "{{ True if no_ipv4_unicast is defined }}",
+ "local_pref": "{{ local_pref.split(" " )[1] if local_pref is defined }}"
+ }
+ }
+ }
+ },
+ {
+ "name": "bgp_params.deterministic_med",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+deterministic-med
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters deterministic-med",
+ "compval": "bgp_params.deterministic_med",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "deterministic_med": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.disbale_network_import_check",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+disable-network-import-check
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters disable-network-import-check",
+ "compval": "bgp_params.disable_network_import_check",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "disable_network_import_check": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.distance.prefix",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+distance\sprefix
+ \s+(?P<prefix>\S+)
+ \s+distance
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters distance prefix {{ bgp_params.distance.prefix }} distance {{ bgp_params.distance.value }}",
+ "compval": "bgp_params.distance.prefix",
+ "remval": "protocols bgp {{ as_number }} parameters distance prefix",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "distance": [
+ {
+ "prefix": "{{ prefix }}",
+ "value": "{{ val }}"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "bgp_params.distance.global",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+distance\sglobal
+ \s+(?P<type>\S+)
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": _tmplt_bgp_params_distance,
+ "remval": "protocols bgp {{ as_number }} parameters distance global",
+ "compval": "bgp_params.distance",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "distance": [
+ {
+ "type": "{{ type }}",
+ "value": "{{ val }}"
+ }
+ ]
+ }
+ }
+ },
+ {
+ "name": "bgp_params.enforce_first_as",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+enforce-first-as
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters enforce-first-as",
+ "compval": "bgp_params.enforce_first_as",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "enforce_first_as": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.graceful_restart",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+graceful-restart\s+stalepath-time
+ \s+(?P<val>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters graceful-restart stalepath-time {{ bgp_params.graceful_restart }}",
+ "compval": "bgp_params.graceful_restart",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "graceful_restart": "{{ val }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.log_neighbor_changes",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+log-neighbor-changes
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters log-neighbor-changes",
+ "compval": "bgp_params.log_neighbor_changes",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "log_neighbor_changes": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.no_client_to_client_reflection",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+no-client-to-client-reflection
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters no-client-to-client-reflection",
+ "compval": "bgp_params.log_neighbor_changes",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "no_client_to_client_reflection": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.no_fast_external_failover",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+no-fast-external-failover
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters no-fast-external-failover",
+ "compval": "bgp_params.no_fast_external_failover",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "no_fast_external_failover": "{{ True }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.routerid",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+router-id
+ \s+(?P<id>\S+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters router-id {{ bgp_params.router_id }}",
+ "compval": "bgp_params.router_id",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "router_id": "{{ id }}",
+ }
+ }
+ },
+ {
+ "name": "bgp_params.scan_time",
+ "getval": re.compile(
+ r"""
+ ^set
+ \s+protocols
+ \s+bgp
+ \s+(?P<as_num>\d+)
+ \s+parameters
+ \s+scan-time
+ \s+(?P<sec>\d+)
+ *$""",
+ re.VERBOSE,
+ ),
+ "setval": "protocols bgp {{ as_number }} parameters scan-time {{ bgp_params.scan_time }}",
+ "compval": "bgp_params.scan_time",
+ "result": {
+ "as_number": "{{ as_num }}",
+ "bgp_params": {
+ "scan_time": "{{ val }}",
+ }
+ }
+ },
+
+ ]
+ # fmt: on
diff --git a/plugins/modules/vyos_bgp_global.py b/plugins/modules/vyos_bgp_global.py
new file mode 100644
index 0000000..aedbae1
--- /dev/null
+++ b/plugins/modules/vyos_bgp_global.py
@@ -0,0 +1,1440 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2021 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the resource
+# module builder playbook.
+#
+# Do not edit this file manually.
+#
+# Changes to this file will be over written
+# by the resource module builder.
+#
+# Changes should be made in the model used to
+# generate this file or in the resource module
+# builder template.
+#
+#############################################
+
+"""
+The module file for vyos_bgp_global
+"""
+
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: vyos_bgp_global
+version_added: 2.0.0
+short_description: BGP Global Resource Module.
+description:
+- This module manages BGP global configuration of interfaces on devices running VYOS.
+author: Gomathi Selvi Srinivasan (@GomathiselviS)
+options:
+ config:
+ description: A dict of BGP global configuration for interfaces.
+ type: dict
+ suboptions:
+ as_number:
+ description:
+ - AS number.
+ type: int
+ aggregate_address:
+ description:
+ - BGP aggregate network.
+ type: list
+ elements: dict
+ suboptions:
+ prefix:
+ description: BGP aggregate network.
+ type: str
+ as_set:
+ description: Generate AS-set path information for this aggregate address.
+ type: bool
+ summary_only:
+ description: Announce the aggregate summary network only.
+ type: bool
+ maximum_paths:
+ description: BGP multipaths
+ type: list
+ elements: dict
+ suboptions:
+ path:
+ description: BGP multipaths
+ type: str
+ count:
+ description: No. of paths.
+ type: int
+ neighbor:
+ description: BGP neighbor
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: BGP neighbor address (v4/v6).
+ type: str
+ advertisement_interval:
+ description: Minimum interval for sending routing updates.
+ type: int
+ allowas_in:
+ description: Number of occurrences of AS number.
+ type: int
+ as_override:
+ description: AS for routes sent to this neighbor to be the local AS.
+ type: bool
+ attribute_unchanged:
+ description: BGP attributes are sent unchanged.
+ type: dict
+ suboptions:
+ as_path:
+ description: as_path
+ type: bool
+ med:
+ description: med
+ type: bool
+ next_hop:
+ description: next_hop
+ type: bool
+ capability:
+ description: Advertise capabilities to this neighbor.
+ type: dict
+ suboptions:
+ dynamic:
+ description: Advertise dynamic capability to this neighbor.
+ type: bool
+ orf:
+ description: Advertise ORF capability to this neighbor.
+ type: str
+ choices: ['send', 'receive']
+ default_originate:
+ description: Send default route to this neighbor
+ type: str
+ description:
+ description: description text
+ type: str
+ disable_capability_negotiation:
+ description: Disbale capability negotiation with the neighbor
+ type: bool
+ disable_connected_check:
+ description: Disable check to see if EBGP peer's address is a connected route.
+ type: bool
+ disable_send_community:
+ description: Disable sending community attributes to this neighbor.
+ type: str
+ choices: ['extended', 'standard']
+ distribute_list:
+ description: Access-list to filter route updates to/from this neighbor.
+ type: list
+ elements: dict
+ suboptions:
+ action:
+ description: Access-list to filter outgoing/incoming route updates to this neighbor
+ type: str
+ choices: ['export', 'import']
+ acl:
+ description: Acess-list number.
+ type: int
+ ebgp_multihop:
+ description: Allow this EBGP neighbor to not be on a directly connected network. Specify
+ the number hops.
+ type: int
+ filter_list:
+ description: As-path-list to filter route updates to/from this neighbor.
+ type: list
+ elements: dict
+ suboptions:
+ action:
+ description: filter outgoing/incoming route updates
+ type: str
+ choices: ['export', 'import']
+ path_list:
+ description: As-path-list to filter
+ type: str
+ local_as:
+ description: local as number not to be prepended to updates from EBGP peers
+ type: int
+ maximum_prefix:
+ description: Maximum number of prefixes to accept from this neighbor
+ nexthop-self Nexthop for routes sent to this neighbor to be the local router.
+ type: int
+ nexthop_self:
+ description: Nexthop for routes sent to this neighbor to be the local router.
+ type: bool
+ override_capability:
+ description: Ignore capability negotiation with specified neighbor.
+ type: bool
+ passive:
+ description: Do not initiate a session with this neighbor
+ type: bool
+ password:
+ description: BGP MD5 password
+ type: str
+ peer_group_name:
+ description: IPv4 peer group for this peer
+ type: str
+ peer_group:
+ description: True if all the configs unde this neighbor key is for peer group template.
+ type: bool
+ port:
+ description: Neighbor's BGP port
+ type: int
+ prefix_list:
+ description: Prefix-list to filter route updates to/from this neighbor.
+ type: list
+ elements: dict
+ suboptions:
+ action:
+ description: filter outgoing/incoming route updates
+ type: str
+ choices: ['export', 'import']
+ prefix_list:
+ description: Prefix-list to filter
+ type: str
+ remote_as:
+ description: Neighbor BGP AS number
+ type: int
+ remove_private_as:
+ description: Remove private AS numbers from AS path in outbound route updates
+ type: bool
+ route_map:
+ description: Route-map to filter route updates to/from this neighbor.
+ type: list
+ elements: dict
+ suboptions:
+ action:
+ description: filter outgoing/incoming route updates
+ type: str
+ choices: ['export', 'import']
+ route_map:
+ description: route-map to filter
+ type: str
+ route_reflector_client:
+ description: Neighbor as a route reflector client
+ type: bool
+ route_server_client:
+ description: Neighbor is route server client
+ type: bool
+ shutdown:
+ description: Administratively shut down neighbor
+ type: bool
+ soft_reconfiguration:
+ description: Soft reconfiguration for neighbor
+ type: bool
+ strict_capability_match:
+ description: Enable strict capability negotiation
+ type: bool
+ unsuppress_map:
+ description: Route-map to selectively unsuppress suppressed routes
+ type: str
+ update_source:
+ description: Source IP of routing updates
+ type: str
+ weight:
+ description: Default weight for routes from this neighbor
+ type: int
+ ttl_security:
+ description: Ttl security mechanism for this BGP peer
+ type: int
+ timers:
+ description: Neighbor timers
+ type: dict
+ suboptions:
+ connect:
+ description: BGP connect timer for this neighbor.
+ type: int
+ holdtime:
+ description: BGP hold timer for this neighbor
+ type: int
+ keepalive:
+ description: BGP keepalive interval for this neighbor
+ type: int
+ network:
+ description: BGP network
+ type: list
+ elements: dict
+ suboptions:
+ address:
+ description: BGP network address
+ type: str
+ backdoor:
+ description: Network as a backdoor route
+ type: bool
+ route_map:
+ description: Route-map to modify route attributes
+ type: str
+ redistribute:
+ description: Redistribute routes from other protocols into BGP
+ type: list
+ elements: dict
+ suboptions:
+ protocol:
+ description: types of routes to be redistributed.
+ type: str
+ choices: ['connected', 'kernel', 'ospf', 'rip', 'static']
+ route_map:
+ description: Route map to filter redistributed routes
+ type: str
+ metric:
+ description: Metric for redistributed routes.
+ type: int
+ timers:
+ description: BGP protocol timers
+ type: dict
+ suboptions:
+ keepalive:
+ description: Keepalive interval
+ type: int
+ holdtime:
+ description: Hold time interval
+ type: int
+ bgp_params:
+ description: BGP parameters
+ type: dict
+ suboptions:
+ always_compare_med:
+ description: Always compare MEDs from different neighbors
+ type: bool
+ bestpath:
+ description: Default bestpath selection mechanism
+ type: dict
+ suboptions:
+ as_path:
+ description: AS-path attribute comparison parameters
+ type: str
+ choices: ['confed', 'ignore']
+ compare_routerid:
+ description: Compare the router-id for identical EBGP paths
+ type: bool
+ med:
+ description: MED attribute comparison parameters
+ type: str
+ choices: ['confed', 'missing-as-worst']
+ cluster_id:
+ description: Route-reflector cluster-id
+ type: str
+ confederation:
+ description: AS confederation parameters
+ type: list
+ elements: dict
+ suboptions:
+ identifier:
+ description: Confederation AS identifier
+ type: int
+ peers:
+ description: Peer ASs in the BGP confederation
+ type: int
+ dampening:
+ description: Enable route-flap dampening
+ type: dict
+ suboptions:
+ half_life:
+ description: Half-life penalty in seconds
+ type: int
+ max_suppress_time:
+ description: Maximum duration to suppress a stable route
+ type: int
+ re_use:
+ description: Time to start reusing a route
+ type: int
+ start_suppress_time:
+ description: When to start suppressing a route
+ type: int
+ default:
+ description: BGP defaults
+ type: dict
+ suboptions:
+ local_pref:
+ description: Default local preference
+ type: int
+ no_ipv4_unicast:
+ description: Deactivate IPv4 unicast for a peer by default
+ type: bool
+ deterministic_med:
+ description: Compare MEDs between different peers in the same AS
+ type: bool
+ disable_network_import_check:
+ description: Disable IGP route check for network statements
+ type: bool
+ distance:
+ description: Administratives distances for BGP routes
+ type: list
+ elements: dict
+ suboptions:
+ type:
+ description: Type of route
+ type: str
+ choices: ['external', 'internal', 'local']
+ value:
+ description: distance
+ type: int
+ prefix:
+ description: Administrative distance for a specific BGP prefix
+ type: int
+ enforce_first_as:
+ description: Require first AS in the path to match peer's AS
+ type: bool
+ graceful_restart:
+ description: Maximum time to hold onto restarting peer's stale paths
+ type: int
+ log_neighbor_changes:
+ description: Log neighbor up/down changes and reset reason
+ type: bool
+ no_client_to_client_reflection:
+ description: Disable client to client route reflection
+ type: bool
+ no_fast_external_failover:
+ description: Disable immediate sesison reset if peer's connected link goes down
+ type: bool
+ router_id:
+ description: BGP router-id
+ type: str
+ scan_time:
+ description: BGP route scanner interval
+ type: int
+ state:
+ description:
+ - The state the configuration should be left in.
+ - State I(purged) removes all the BGP configurations from the
+ target device. Use caution with this state.('delete protocols bgp <x>')
+ - State I(deleted) only removes BGP attributes that this modules
+ manages and does not negate the BGP process completely. Thereby, preserving
+ address-family related configurations under BGP context.
+ - Running states I(deleted) and I(replaced) will result in an error if there
+ are address-family configuration lines present under neighbor context that is
+ is to be removed. Please use the M(vyos.vyos.vyos_bgp_address_family)
+ module for prior cleanup.
+ - Refer to examples for more details.
+ type: str
+ choices: [deleted, merged, purged, replaced, gathered, rendered, parsed]
+ default: merged
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the EOS device by
+ executing the command B(show running-config | section bgp).
+ - The state I(parsed) reads the configuration from C(running_config) option and
+ transforms it into Ansible structured data as per the resource module's argspec
+ and the value is then returned in the I(parsed) key within the result.
+ type: str
+
+"""
+EXAMPLES = """
+# Using merged
+# Before state
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# vyos@vyos:~$
+
+ - name: Merge provided configuration with device configuration
+ vyos.vyos.vyos_bgp_global:
+ config:
+ as_number: "65536"
+ aggregate_address:
+ - prefix: "203.0.113.0/24"
+ as_set: true
+ - prefix: "192.0.2.0/24"
+ summary_only: true
+ network:
+ - address: "192.1.13.0/24"
+ backdoor: true
+ redistribute:
+ - protocol: "kernel"
+ metric: 45
+ - protocol: "connected"
+ route_map: "map01"
+ maximum_paths:
+ - path: "ebgp"
+ count: 20
+ - path: "ibgp"
+ count: 55
+ timers:
+ keepalive: 35
+ bgp_params:
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ router_id: "192.1.2.9"
+ confederation:
+ - peers: 20
+ - peers: 55
+ - identifier: 66
+ neighbor:
+ - address: "192.0.2.25"
+ disable_connected_check: true
+ timers:
+ holdtime: 30
+ keepalive: 10
+ - address: "203.0.113.5"
+ attribute_unchanged:
+ as_path: true
+ med: true
+ ebgp_multihop: 2
+ remote_as: 101
+ update_source: "192.0.2.25"
+ - address: "5001::64"
+ maximum_prefix: 34
+ distribute_list:
+ - acl: 20
+ action: "export"
+ - acl: 40
+ action: "import"
+
+ state: merged
+
+# After State
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 aggregate-address 192.0.2.0/24 'summary-only'
+# set protocols bgp 65536 aggregate-address 203.0.113.0/24 'as-set'
+# set protocols bgp 65536 maximum-paths ebgp '20'
+# set protocols bgp 65536 maximum-paths ibgp '55'
+# set protocols bgp 65536 neighbor 192.0.2.25 'disable-connected-check'
+# set protocols bgp 65536 neighbor 192.0.2.25 timers holdtime '30'
+# set protocols bgp 65536 neighbor 192.0.2.25 timers keepalive '10'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'as-path'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'med'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+# set protocols bgp 65536 neighbor 203.0.113.5 ebgp-multihop '2'
+# set protocols bgp 65536 neighbor 203.0.113.5 remote-as '101'
+# set protocols bgp 65536 neighbor 203.0.113.5 update-source '192.0.2.25'
+# set protocols bgp 65536 neighbor 5001::64 distribute-list export '20'
+# set protocols bgp 65536 neighbor 5001::64 distribute-list import '40'
+# set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+# set protocols bgp 65536 network 192.1.13.0/24 'backdoor'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 parameters bestpath 'compare-routerid'
+# set protocols bgp 65536 parameters confederation identifier '66'
+# set protocols bgp 65536 parameters confederation peers '20'
+# set protocols bgp 65536 parameters confederation peers '55'
+# set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+# set protocols bgp 65536 parameters router-id '192.1.2.9'
+# set protocols bgp 65536 redistribute connected route-map 'map01'
+# set protocols bgp 65536 redistribute kernel metric '45'
+# set protocols bgp 65536 timers keepalive '35'
+# vyos@vyos:~$
+#
+# # Module Execution:
+#
+# "after": {
+# "aggregate_address": [
+# {
+# "prefix": "192.0.2.0/24",
+# "summary_only": true
+# },
+# {
+# "prefix": "203.0.113.0/24",
+# "as_set": true
+# }
+# ],
+# "as_number": 65536,
+# "bgp_params": {
+# "bestpath": {
+# "as_path": "confed",
+# "compare_routerid": true
+# },
+# "confederation": [
+# {
+# "identifier": 66
+# },
+# {
+# "peers": 20
+# },
+# {
+# "peers": 55
+# }
+# ],
+# "default": {
+# "no_ipv4_unicast": true
+# },
+# "router_id": "192.1.2.9"
+# },
+# "maximum_paths": [
+# {
+# "count": 20,
+# "path": "ebgp"
+# },
+# {
+# "count": 55,
+# "path": "ibgp"
+# }
+# ],
+# "neighbor": [
+# {
+# "address": "192.0.2.25",
+# "disable_connected_check": true,
+# "timers": {
+# "holdtime": 30,
+# "keepalive": 10
+# }
+# },
+# {
+# "address": "203.0.113.5",
+# "attribute_unchanged": {
+# "as_path": true,
+# "med": true,
+# "next_hop": true
+# },
+# "ebgp_multihop": 2,
+# "remote_as": 101,
+# "update_source": "192.0.2.25"
+# },
+# {
+# "address": "5001::64",
+# "distribute_list": [
+# {
+# "acl": 20,
+# "action": "export"
+# },
+# {
+# "acl": 40,
+# "action": "import"
+# }
+# ],
+# "maximum_prefix": 34
+# }
+# ],
+# "network": [
+# {
+# "address": "192.1.13.0/24",
+# "backdoor": true
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "connected",
+# "route_map": "map01"
+# },
+# {
+# "metric": 45,
+# "protocol": "kernel"
+# }
+# ],
+# "timers": {
+# "keepalive": 35
+# }
+# },
+# "before": {},
+# "changed": true,
+# "commands": [
+# "set protocols bgp 65536 neighbor 192.0.2.25 disable-connected-check",
+# "set protocols bgp 65536 neighbor 192.0.2.25 timers holdtime 30",
+# "set protocols bgp 65536 neighbor 192.0.2.25 timers keepalive 10",
+# "set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged as-path",
+# "set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged med",
+# "set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged next-hop",
+# "set protocols bgp 65536 neighbor 203.0.113.5 ebgp-multihop 2",
+# "set protocols bgp 65536 neighbor 203.0.113.5 remote-as 101",
+# "set protocols bgp 65536 neighbor 203.0.113.5 update-source 192.0.2.25",
+# "set protocols bgp 65536 neighbor 5001::64 maximum-prefix 34",
+# "set protocols bgp 65536 neighbor 5001::64 distribute-list export 20",
+# "set protocols bgp 65536 neighbor 5001::64 distribute-list import 40",
+# "set protocols bgp 65536 redistribute kernel metric 45",
+# "set protocols bgp 65536 redistribute connected route-map map01",
+# "set protocols bgp 65536 network 192.1.13.0/24 backdoor",
+# "set protocols bgp 65536 aggregate-address 203.0.113.0/24 as-set",
+# "set protocols bgp 65536 aggregate-address 192.0.2.0/24 summary-only",
+# "set protocols bgp 65536 parameters bestpath as-path confed",
+# "set protocols bgp 65536 parameters bestpath compare-routerid",
+# "set protocols bgp 65536 parameters default no-ipv4-unicast",
+# "set protocols bgp 65536 parameters router-id 192.1.2.9",
+# "set protocols bgp 65536 parameters confederation peers 20",
+# "set protocols bgp 65536 parameters confederation peers 55",
+# "set protocols bgp 65536 parameters confederation identifier 66",
+# "set protocols bgp 65536 maximum-paths ebgp 20",
+# "set protocols bgp 65536 maximum-paths ibgp 55",
+# "set protocols bgp 65536 timers keepalive 35"
+# ],
+
+# Using replaced:
+# --------------
+
+# Before state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 aggregate-address 192.0.2.0/24 'summary-only'
+# set protocols bgp 65536 aggregate-address 203.0.113.0/24 'as-set'
+# set protocols bgp 65536 maximum-paths ebgp '20'
+# set protocols bgp 65536 maximum-paths ibgp '55'
+# set protocols bgp 65536 neighbor 192.0.2.25 'disable-connected-check'
+# set protocols bgp 65536 neighbor 192.0.2.25 timers holdtime '30'
+# set protocols bgp 65536 neighbor 192.0.2.25 timers keepalive '10'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'as-path'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'med'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+# set protocols bgp 65536 neighbor 203.0.113.5 ebgp-multihop '2'
+# set protocols bgp 65536 neighbor 203.0.113.5 remote-as '101'
+# set protocols bgp 65536 neighbor 203.0.113.5 update-source '192.0.2.25'
+# set protocols bgp 65536 neighbor 5001::64 distribute-list export '20'
+# set protocols bgp 65536 neighbor 5001::64 distribute-list import '40'
+# set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+# set protocols bgp 65536 network 192.1.13.0/24 'backdoor'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 parameters bestpath 'compare-routerid'
+# set protocols bgp 65536 parameters confederation identifier '66'
+# set protocols bgp 65536 parameters confederation peers '20'
+# set protocols bgp 65536 parameters confederation peers '55'
+# set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+# set protocols bgp 65536 parameters router-id '192.1.2.9'
+# set protocols bgp 65536 redistribute connected route-map 'map01'
+# set protocols bgp 65536 redistribute kernel metric '45'
+# set protocols bgp 65536 timers keepalive '35'
+# vyos@vyos:~$
+
+ - name: Replace
+ vyos.vyos.vyos_bgp_global:
+ config:
+ as_number: "65536"
+ network:
+ - address: "203.0.113.0/24"
+ route_map: map01
+ redistribute:
+ - protocol: "static"
+ route_map: "map01"
+ neighbor:
+ - address: "192.0.2.40"
+ advertisement_interval: 72
+ capability:
+ orf: "receive"
+ bgp_params:
+ bestpath:
+ as_path: "confed"
+
+ state: replaced
+# After state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 neighbor 192.0.2.40 advertisement-interval '72'
+# set protocols bgp 65536 neighbor 192.0.2.40 capability orf prefix-list 'receive'
+# set protocols bgp 65536 network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 redistribute static route-map 'map01'
+# vyos@vyos:~$
+#
+#
+# Module Execution:
+#
+# "after": {
+# "as_number": 65536,
+# "bgp_params": {
+# "bestpath": {
+# "as_path": "confed"
+# }
+# },
+# "neighbor": [
+# {
+# "address": "192.0.2.40",
+# "advertisement_interval": 72,
+# "capability": {
+# "orf": "receive"
+# }
+# }
+# ],
+# "network": [
+# {
+# "address": "203.0.113.0/24",
+# "route_map": "map01"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map01"
+# }
+# ]
+# },
+# "before": {
+# "aggregate_address": [
+# {
+# "prefix": "192.0.2.0/24",
+# "summary_only": true
+# },
+# {
+# "prefix": "203.0.113.0/24",
+# "as_set": true
+# }
+# ],
+# "as_number": 65536,
+# "bgp_params": {
+# "bestpath": {
+# "as_path": "confed",
+# "compare_routerid": true
+# },
+# "confederation": [
+# {
+# "identifier": 66
+# },
+# {
+# "peers": 20
+# },
+# {
+# "peers": 55
+# }
+# ],
+# "default": {
+# "no_ipv4_unicast": true
+# },
+# "router_id": "192.1.2.9"
+# },
+# "maximum_paths": [
+# {
+# "count": 20,
+# "path": "ebgp"
+# },
+# {
+# "count": 55,
+# "path": "ibgp"
+# }
+# ],
+# "neighbor": [
+# {
+# "address": "192.0.2.25",
+# "disable_connected_check": true,
+# "timers": {
+# "holdtime": 30,
+# "keepalive": 10
+# }
+# },
+# {
+# "address": "203.0.113.5",
+# "attribute_unchanged": {
+# "as_path": true,
+# "med": true,
+# "next_hop": true
+# },
+# "ebgp_multihop": 2,
+# "remote_as": 101,
+# "update_source": "192.0.2.25"
+# },
+# {
+# "address": "5001::64",
+# "distribute_list": [
+# {
+# "acl": 20,
+# "action": "export"
+# },
+# {
+# "acl": 40,
+# "action": "import"
+# }
+# ],
+# "maximum_prefix": 34
+# }
+# ],
+# "network": [
+# {
+# "address": "192.1.13.0/24",
+# "backdoor": true
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "connected",
+# "route_map": "map01"
+# },
+# {
+# "metric": 45,
+# "protocol": "kernel"
+# }
+# ],
+# "timers": {
+# "keepalive": 35
+# }
+# },
+# "changed": true,
+# "commands": [
+# "delete protocols bgp 65536 timers",
+# "delete protocols bgp 65536 maximum-paths ",
+# "delete protocols bgp 65536 maximum-paths ",
+# "delete protocols bgp 65536 parameters router-id 192.1.2.9",
+# "delete protocols bgp 65536 parameters default",
+# "delete protocols bgp 65536 parameters confederation",
+# "delete protocols bgp 65536 parameters bestpath compare-routerid",
+# "delete protocols bgp 65536 aggregate-address",
+# "delete protocols bgp 65536 network 192.1.13.0/24",
+# "delete protocols bgp 65536 redistribute kernel",
+# "delete protocols bgp 65536 redistribute kernel",
+# "delete protocols bgp 65536 redistribute connected",
+# "delete protocols bgp 65536 redistribute connected",
+# "delete protocols bgp 65536 neighbor 5001::64",
+# "delete protocols bgp 65536 neighbor 203.0.113.5",
+# "delete protocols bgp 65536 neighbor 192.0.2.25",
+# "set protocols bgp 65536 neighbor 192.0.2.40 advertisement-interval 72",
+# "set protocols bgp 65536 neighbor 192.0.2.40 capability orf prefix-list receive",
+# "set protocols bgp 65536 redistribute static route-map map01",
+# "set protocols bgp 65536 network 203.0.113.0/24 route-map map01"
+# ],
+
+# Using deleted:
+# -------------
+
+# Before state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 neighbor 192.0.2.40 advertisement-interval '72'
+# set protocols bgp 65536 neighbor 192.0.2.40 capability orf prefix-list 'receive'
+# set protocols bgp 65536 network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 redistribute static route-map 'map01'
+# vyos@vyos:~$
+
+ - name: Delete configuration
+ vyos.vyos.vyos_bgp_global:
+ config:
+ as_number: "65536"
+ state: deleted
+
+# After state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp '65536'
+# vyos@vyos:~$
+#
+#
+# Module Execution:
+#
+# "after": {
+# "as_number": 65536
+# },
+# "before": {
+# "as_number": 65536,
+# "bgp_params": {
+# "bestpath": {
+# "as_path": "confed"
+# }
+# },
+# "neighbor": [
+# {
+# "address": "192.0.2.40",
+# "advertisement_interval": 72,
+# "capability": {
+# "orf": "receive"
+# }
+# }
+# ],
+# "network": [
+# {
+# "address": "203.0.113.0/24",
+# "route_map": "map01"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map01"
+# }
+# ]
+# },
+# "changed": true,
+# "commands": [
+# "delete protocols bgp 65536 neighbor 192.0.2.40",
+# "delete protocols bgp 65536 redistribute",
+# "delete protocols bgp 65536 network",
+# "delete protocols bgp 65536 parameters"
+# ],
+
+# Using purged:
+
+# Before state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 aggregate-address 192.0.2.0/24 'summary-only'
+# set protocols bgp 65536 aggregate-address 203.0.113.0/24 'as-set'
+# set protocols bgp 65536 maximum-paths ebgp '20'
+# set protocols bgp 65536 maximum-paths ibgp '55'
+# set protocols bgp 65536 neighbor 192.0.2.25 'disable-connected-check'
+# set protocols bgp 65536 neighbor 192.0.2.25 timers holdtime '30'
+# set protocols bgp 65536 neighbor 192.0.2.25 timers keepalive '10'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'as-path'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'med'
+# set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+# set protocols bgp 65536 neighbor 203.0.113.5 ebgp-multihop '2'
+# set protocols bgp 65536 neighbor 203.0.113.5 remote-as '101'
+# set protocols bgp 65536 neighbor 203.0.113.5 update-source '192.0.2.25'
+# set protocols bgp 65536 neighbor 5001::64 distribute-list export '20'
+# set protocols bgp 65536 neighbor 5001::64 distribute-list import '40'
+# set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+# set protocols bgp 65536 network 192.1.13.0/24 'backdoor'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 parameters bestpath 'compare-routerid'
+# set protocols bgp 65536 parameters confederation identifier '66'
+# set protocols bgp 65536 parameters confederation peers '20'
+# set protocols bgp 65536 parameters confederation peers '55'
+# set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+# set protocols bgp 65536 parameters router-id '192.1.2.9'
+# set protocols bgp 65536 redistribute connected route-map 'map01'
+# set protocols bgp 65536 redistribute kernel metric '45'
+# set protocols bgp 65536 timers keepalive '35'
+# vyos@vyos:~$
+
+
+ - name: Purge configuration
+ vyos.vyos.vyos_bgp_global:
+ config:
+ as_number: "65536"
+ state: purged
+
+# After state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# vyos@vyos:~$
+#
+# Module Execution:
+#
+# "after": {},
+# "before": {
+# "aggregate_address": [
+# {
+# "prefix": "192.0.2.0/24",
+# "summary_only": true
+# },
+# {
+# "prefix": "203.0.113.0/24",
+# "as_set": true
+# }
+# ],
+# "as_number": 65536,
+# "bgp_params": {
+# "bestpath": {
+# "as_path": "confed",
+# "compare_routerid": true
+# },
+# "confederation": [
+# {
+# "identifier": 66
+# },
+# {
+# "peers": 20
+# },
+# {
+# "peers": 55
+# }
+# ],
+# "default": {
+# "no_ipv4_unicast": true
+# },
+# "router_id": "192.1.2.9"
+# },
+# "maximum_paths": [
+# {
+# "count": 20,
+# "path": "ebgp"
+# },
+# {
+# "count": 55,
+# "path": "ibgp"
+# }
+# ],
+# "neighbor": [
+# {
+# "address": "192.0.2.25",
+# "disable_connected_check": true,
+# "timers": {
+# "holdtime": 30,
+# "keepalive": 10
+# }
+# },
+# {
+# "address": "203.0.113.5",
+# "attribute_unchanged": {
+# "as_path": true,
+# "med": true,
+# "next_hop": true
+# },
+# "ebgp_multihop": 2,
+# "remote_as": 101,
+# "update_source": "192.0.2.25"
+# },
+# {
+# "address": "5001::64",
+# "distribute_list": [
+# {
+# "acl": 20,
+# "action": "export"
+# },
+# {
+# "acl": 40,
+# "action": "import"
+# }
+# ],
+# "maximum_prefix": 34
+# }
+# ],
+# "network": [
+# {
+# "address": "192.1.13.0/24",
+# "backdoor": true
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "connected",
+# "route_map": "map01"
+# },
+# {
+# "metric": 45,
+# "protocol": "kernel"
+# }
+# ],
+# "timers": {
+# "keepalive": 35
+# }
+# },
+# "changed": true,
+# "commands": [
+# "delete protocols bgp 65536"
+# ],
+
+
+# Deleted in presence of address family under neighbors:
+
+# Before state:
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 neighbor 192.0.2.43 advertisement-interval '72'
+# set protocols bgp 65536 neighbor 192.0.2.43 capability 'dynamic'
+# set protocols bgp 65536 neighbor 192.0.2.43 'disable-connected-check'
+# set protocols bgp 65536 neighbor 192.0.2.43 timers holdtime '30'
+# set protocols bgp 65536 neighbor 192.0.2.43 timers keepalive '10'
+# set protocols bgp 65536 neighbor 203.0.113.0 address-family 'ipv6-unicast'
+# set protocols bgp 65536 neighbor 203.0.113.0 capability orf prefix-list 'receive'
+# set protocols bgp 65536 network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp 65536 parameters 'always-compare-med'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 parameters bestpath 'compare-routerid'
+# set protocols bgp 65536 parameters dampening half-life '33'
+# set protocols bgp 65536 parameters dampening max-suppress-time '20'
+# set protocols bgp 65536 parameters dampening re-use '60'
+# set protocols bgp 65536 parameters dampening start-suppress-time '5'
+# set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+# set protocols bgp 65536 parameters distance global external '66'
+# set protocols bgp 65536 parameters distance global internal '20'
+# set protocols bgp 65536 parameters distance global local '10'
+# set protocols bgp 65536 redistribute static route-map 'map01'
+# vyos@vyos:~$ ^C
+# vyos@vyos:~$
+
+
+ - name: Delete configuration
+ vyos.vyos.vyos_bgp_global:
+ config:
+ as_number: "65536"
+ state: deleted
+
+# Module Execution:
+#
+# "changed": false,
+# "invocation": {
+# "module_args": {
+# "config": {
+# "aggregate_address": null,
+# "as_number": 65536,
+# "bgp_params": null,
+# "maximum_paths": null,
+# "neighbor": null,
+# "network": null,
+# "redistribute": null,
+# "timers": null
+# },
+# "running_config": null,
+# "state": "deleted"
+# }
+# },
+# "msg": "Use the _bgp_address_family module to delete the address_family under neighbor 203.0.113.0, before replacing/deleting the neighbor."
+# }
+
+# using gathered:
+# --------------
+
+# Before state:
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp 65536 neighbor 192.0.2.43 advertisement-interval '72'
+# set protocols bgp 65536 neighbor 192.0.2.43 capability 'dynamic'
+# set protocols bgp 65536 neighbor 192.0.2.43 'disable-connected-check'
+# set protocols bgp 65536 neighbor 192.0.2.43 timers holdtime '30'
+# set protocols bgp 65536 neighbor 192.0.2.43 timers keepalive '10'
+# set protocols bgp 65536 neighbor 203.0.113.0 address-family 'ipv6-unicast'
+# set protocols bgp 65536 neighbor 203.0.113.0 capability orf prefix-list 'receive'
+# set protocols bgp 65536 network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp 65536 parameters 'always-compare-med'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 parameters bestpath 'compare-routerid'
+# set protocols bgp 65536 parameters dampening half-life '33'
+# set protocols bgp 65536 parameters dampening max-suppress-time '20'
+# set protocols bgp 65536 parameters dampening re-use '60'
+# set protocols bgp 65536 parameters dampening start-suppress-time '5'
+# set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+# set protocols bgp 65536 parameters distance global external '66'
+# set protocols bgp 65536 parameters distance global internal '20'
+# set protocols bgp 65536 parameters distance global local '10'
+# set protocols bgp 65536 redistribute static route-map 'map01'
+# vyos@vyos:~$ ^C
+
+ - name: gather configs
+ vyos.vyos.vyos_bgp_global:
+ state: gathered
+
+# Module Execution:
+# "gathered": {
+# "as_number": 65536,
+# "bgp_params": {
+# "always_compare_med": true,
+# "bestpath": {
+# "as_path": "confed",
+# "compare_routerid": true
+# },
+# "default": {
+# "no_ipv4_unicast": true
+# },
+# "distance": [
+# {
+# "type": "external",
+# "value": 66
+# },
+# {
+# "type": "internal",
+# "value": 20
+# },
+# {
+# "type": "local",
+# "value": 10
+# }
+# ]
+# },
+# "neighbor": [
+# {
+# "address": "192.0.2.43",
+# "advertisement_interval": 72,
+# "capability": {
+# "dynamic": true
+# },
+# "disable_connected_check": true,
+# "timers": {
+# "holdtime": 30,
+# "keepalive": 10
+# }
+# },
+# {
+# "address": "203.0.113.0",
+# "capability": {
+# "orf": "receive"
+# }
+# }
+# ],
+# "network": [
+# {
+# "address": "203.0.113.0/24",
+# "route_map": "map01"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map01"
+# }
+# ]
+# },
+#
+
+# Using parsed:
+# ------------
+
+# parsed.cfg
+
+# set protocols bgp 65536 neighbor 192.0.2.43 advertisement-interval '72'
+# set protocols bgp 65536 neighbor 192.0.2.43 capability 'dynamic'
+# set protocols bgp 65536 neighbor 192.0.2.43 'disable-connected-check'
+# set protocols bgp 65536 neighbor 192.0.2.43 timers holdtime '30'
+# set protocols bgp 65536 neighbor 192.0.2.43 timers keepalive '10'
+# set protocols bgp 65536 neighbor 203.0.113.0 address-family 'ipv6-unicast'
+# set protocols bgp 65536 neighbor 203.0.113.0 capability orf prefix-list 'receive'
+# set protocols bgp 65536 network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp 65536 parameters 'always-compare-med'
+# set protocols bgp 65536 parameters bestpath as-path 'confed'
+# set protocols bgp 65536 parameters bestpath 'compare-routerid'
+# set protocols bgp 65536 parameters dampening half-life '33'
+# set protocols bgp 65536 parameters dampening max-suppress-time '20'
+# set protocols bgp 65536 parameters dampening re-use '60'
+# set protocols bgp 65536 parameters dampening start-suppress-time '5'
+# set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+# set protocols bgp 65536 parameters distance global external '66'
+# set protocols bgp 65536 parameters distance global internal '20'
+# set protocols bgp 65536 parameters distance global local '10'
+# set protocols bgp 65536 redistribute static route-map 'map01'
+
+ - name: parse configs
+ vyos.vyos.vyos_bgp_global:
+ running_config: "{{ lookup('file', './parsed.cfg') }}"
+ state: parsed
+ tags:
+ - parsed
+
+# Module execution:
+# "parsed": {
+# "as_number": 65536,
+# "bgp_params": {
+# "always_compare_med": true,
+# "bestpath": {
+# "as_path": "confed",
+# "compare_routerid": true
+# },
+# "default": {
+# "no_ipv4_unicast": true
+# },
+# "distance": [
+# {
+# "type": "external",
+# "value": 66
+# },
+# {
+# "type": "internal",
+# "value": 20
+# },
+# {
+# "type": "local",
+# "value": 10
+# }
+# ]
+# },
+# "neighbor": [
+# {
+# "address": "192.0.2.43",
+# "advertisement_interval": 72,
+# "capability": {
+# "dynamic": true
+# },
+# "disable_connected_check": true,
+# "timers": {
+# "holdtime": 30,
+# "keepalive": 10
+# }
+# },
+# {
+# "address": "203.0.113.0",
+# "capability": {
+# "orf": "receive"
+# }
+# }
+# ],
+# "network": [
+# {
+# "address": "203.0.113.0/24",
+# "route_map": "map01"
+# }
+# ],
+# "redistribute": [
+# {
+# "protocol": "static",
+# "route_map": "map01"
+# }
+# ]
+# }
+#
+
+# Using rendered:
+# --------------
+
+ - name: Render
+ vyos.vyos.vyos_bgp_global:
+ config:
+ as_number: "65536"
+ network:
+ - address: "203.0.113.0/24"
+ route_map: map01
+ redistribute:
+ - protocol: "static"
+ route_map: "map01"
+ bgp_params:
+ always_compare_med: true
+ dampening:
+ start_suppress_time: 5
+ max_suppress_time: 20
+ half_life: 33
+ re_use: 60
+ distance:
+ - type: "internal"
+ value: 20
+ - type: "local"
+ value: 10
+ - type: "external"
+ value: 66
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ neighbor:
+ - address: "192.0.2.43"
+ disable_connected_check: true
+ advertisement_interval: 72
+ capability:
+ dynamic: true
+ timers:
+ holdtime: 30
+ keepalive: 10
+ - address: "203.0.113.0"
+ capability:
+ orf: "receive"
+
+ state: rendered
+
+# Module Execution:
+# "rendered": [
+# "set protocols bgp 65536 neighbor 192.0.2.43 disable-connected-check",
+# "set protocols bgp 65536 neighbor 192.0.2.43 advertisement-interval 72",
+# "set protocols bgp 65536 neighbor 192.0.2.43 capability dynamic",
+# "set protocols bgp 65536 neighbor 192.0.2.43 timers holdtime 30",
+# "set protocols bgp 65536 neighbor 192.0.2.43 timers keepalive 10",
+# "set protocols bgp 65536 neighbor 203.0.113.0 capability orf prefix-list receive",
+# "set protocols bgp 65536 redistribute static route-map map01",
+# "set protocols bgp 65536 network 203.0.113.0/24 route-map map01",
+# "set protocols bgp 65536 parameters always-compare-med",
+# "set protocols bgp 65536 parameters dampening half-life 33",
+# "set protocols bgp 65536 parameters dampening max-suppress-time 20",
+# "set protocols bgp 65536 parameters dampening re-use 60",
+# "set protocols bgp 65536 parameters dampening start-suppress-time 5",
+# "set protocols bgp 65536 parameters distance global internal 20",
+# "set protocols bgp 65536 parameters distance global local 10",
+# "set protocols bgp 65536 parameters distance global external 66",
+# "set protocols bgp 65536 parameters bestpath as-path confed",
+# "set protocols bgp 65536 parameters bestpath compare-routerid",
+# "set protocols bgp 65536 parameters default no-ipv4-unicast"
+# ]
+
+
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.bgp_global.bgp_global import (
+ Bgp_globalArgs,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global import (
+ Bgp_global,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=Bgp_globalArgs.argument_spec,
+ mutually_exclusive=[],
+ required_if=[],
+ supports_check_mode=False,
+ )
+
+ result = Bgp_global(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/integration/targets/vyos_bgp_global/defaults/main.yaml b/tests/integration/targets/vyos_bgp_global/defaults/main.yaml
new file mode 100644
index 0000000..852a6be
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/defaults/main.yaml
@@ -0,0 +1,3 @@
+---
+testcase: '[^_].*'
+test_items: []
diff --git a/tests/integration/targets/vyos_bgp_global/meta/main.yaml b/tests/integration/targets/vyos_bgp_global/meta/main.yaml
new file mode 100644
index 0000000..7413320
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/meta/main.yaml
@@ -0,0 +1,3 @@
+---
+dependencies:
+ - prepare_vyos_tests
diff --git a/tests/integration/targets/vyos_bgp_global/tasks/cli.yaml b/tests/integration/targets/vyos_bgp_global/tasks/cli.yaml
new file mode 100644
index 0000000..93eb2fe
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tasks/cli.yaml
@@ -0,0 +1,19 @@
+---
+- name: Collect all cli test cases
+ find:
+ paths: '{{ role_path }}/tests/cli'
+ patterns: '{{ testcase }}.yaml'
+ use_regex: true
+ register: test_cases
+ delegate_to: localhost
+
+- name: Set test_items
+ set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"
+
+- name: Run test case (connection=ansible.netcommon.network_cli)
+ include: '{{ test_case_to_run }}'
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
+ with_items: '{{ test_items }}'
+ loop_control:
+ loop_var: test_case_to_run
diff --git a/tests/integration/targets/vyos_bgp_global/tasks/main.yaml b/tests/integration/targets/vyos_bgp_global/tasks/main.yaml
new file mode 100644
index 0000000..b957d2f
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tasks/main.yaml
@@ -0,0 +1,4 @@
+---
+- include: cli.yaml
+ tags:
+ - network_cli
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/_parsed_config.cfg b/tests/integration/targets/vyos_bgp_global/tests/cli/_parsed_config.cfg
new file mode 100644
index 0000000..2338b03
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/_parsed_config.cfg
@@ -0,0 +1,30 @@
+set policy access-list 20 description 'acl20'
+set policy access-list 40 description 'acl40'
+set policy route-map map01 description 'map01'
+set protocols bgp 65536 aggregate-address 192.0.2.0/24 'summary-only'
+set protocols bgp 65536 aggregate-address 203.0.113.0/24 'as-set'
+set protocols bgp 65536 maximum-paths ebgp '20'
+set protocols bgp 65536 maximum-paths ibgp '55'
+set protocols bgp 65536 neighbor 192.0.2.25 'disable-connected-check'
+set protocols bgp 65536 neighbor 192.0.2.25 timers holdtime '30'
+set protocols bgp 65536 neighbor 192.0.2.25 timers keepalive '10'
+set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'as-path'
+set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'med'
+set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+set protocols bgp 65536 neighbor 203.0.113.5 ebgp-multihop '2'
+set protocols bgp 65536 neighbor 203.0.113.5 remote-as '101'
+set protocols bgp 65536 neighbor 203.0.113.5 update-source '192.0.2.25'
+set protocols bgp 65536 neighbor 5001::64 distribute-list export '20'
+set protocols bgp 65536 neighbor 5001::64 distribute-list import '40'
+set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+set protocols bgp 65536 network 192.1.13.0/24 'backdoor'
+set protocols bgp 65536 parameters bestpath as-path 'confed'
+set protocols bgp 65536 parameters bestpath 'compare-routerid'
+set protocols bgp 65536 parameters confederation identifier '66'
+set protocols bgp 65536 parameters confederation peers '20'
+set protocols bgp 65536 parameters confederation peers '55'
+set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+set protocols bgp 65536 parameters router-id '192.1.2.9'
+set protocols bgp 65536 redistribute connected route-map 'map01'
+set protocols bgp 65536 redistribute kernel metric '45'
+set protocols bgp 65536 timers keepalive '35'
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/_populate.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/_populate.yaml
new file mode 100644
index 0000000..ec237d9
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/_populate.yaml
@@ -0,0 +1,37 @@
+---
+- name: setup
+ vyos.vyos.vyos_config:
+ lines:
+ - set policy access-list 20 description 'acl20'
+ - set policy access-list 40 description 'acl40'
+ - set policy route-map map01 description 'map01'
+ - set protocols bgp 65536 aggregate-address 192.0.2.0/24 'summary-only'
+ - set protocols bgp 65536 aggregate-address 203.0.113.0/24 'as-set'
+ - set protocols bgp 65536 maximum-paths ebgp '20'
+ - set protocols bgp 65536 maximum-paths ibgp '55'
+ - set protocols bgp 65536 neighbor 192.0.2.25 'disable-connected-check'
+ - set protocols bgp 65536 neighbor 192.0.2.25 timers holdtime '30'
+ - set protocols bgp 65536 neighbor 192.0.2.25 timers keepalive '10'
+ - set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'as-path'
+ - set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'med'
+ - set protocols bgp 65536 neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+ - set protocols bgp 65536 neighbor 203.0.113.5 ebgp-multihop '2'
+ - set protocols bgp 65536 neighbor 203.0.113.5 remote-as '101'
+ - set protocols bgp 65536 neighbor 203.0.113.5 update-source '192.0.2.25'
+ - set protocols bgp 65536 neighbor 5001::64 distribute-list export '20'
+ - set protocols bgp 65536 neighbor 5001::64 distribute-list import '40'
+ - set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+ - set protocols bgp 65536 network 192.1.13.0/24 'backdoor'
+ - set protocols bgp 65536 parameters bestpath as-path 'confed'
+ - set protocols bgp 65536 parameters bestpath 'compare-routerid'
+ - set protocols bgp 65536 parameters confederation identifier '66'
+ - set protocols bgp 65536 parameters confederation peers '20'
+ - set protocols bgp 65536 parameters confederation peers '55'
+ - set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+ - set protocols bgp 65536 parameters router-id '192.1.2.9'
+ - set protocols bgp 65536 redistribute connected route-map 'map01'
+ - set protocols bgp 65536 redistribute kernel metric '45'
+ - set protocols bgp 65536 timers keepalive '35'
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/_populate_af.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/_populate_af.yaml
new file mode 100644
index 0000000..59f3d92
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/_populate_af.yaml
@@ -0,0 +1,12 @@
+---
+- name: setup
+ vyos.vyos.vyos_config:
+ lines:
+ - set protocols bgp 65536 neighbor 5001::64 address-family 'ipv6-unicast'
+ - set protocols bgp 65536 neighbor 5001::64 ebgp-multihop '2'
+ - set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+ - set protocols bgp 65536 neighbor 5001::64 remote-as '65535'
+ - set protocols bgp 65536 neighbor 5001::64 update-source '2001:db8::1'
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/_preconfig.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/_preconfig.yaml
new file mode 100644
index 0000000..8ab69e0
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/_preconfig.yaml
@@ -0,0 +1,10 @@
+---
+- name: setup
+ vyos.vyos.vyos_config:
+ lines:
+ - set policy access-list 20 description 'acl20'
+ - set policy access-list 40 description 'acl40'
+ - set policy route-map map01 description 'map01'
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/_remove_config.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/_remove_config.yaml
new file mode 100644
index 0000000..07d4aa4
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/_remove_config.yaml
@@ -0,0 +1,11 @@
+---
+- name: Remove pre-existing bgp processes
+ vyos.vyos.vyos_config:
+ lines:
+ - delete protocols bgp 65536
+ - delete policy access-list 20
+ - delete policy access-list 40
+ - delete policy route-map map01
+ ignore_errors: true
+ vars:
+ ansible_connection: ansible.netcommon.network_cli
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/deleted.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/deleted.yaml
new file mode 100644
index 0000000..e1a7754
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/deleted.yaml
@@ -0,0 +1,42 @@
+---
+- debug:
+ msg: START vyos_bgp_global deleted integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Delete the provided configuration
+ register: result
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ state: deleted
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: bgp_global
+
+ - assert:
+ that:
+ - result.commands|length == 9
+ - result.changed == true
+ - result.commands|symmetric_difference(deleted.commands) == []
+ - result.after == ansible_facts['network_resources']['bgp_global']
+
+ - name: Delete the existing configuration with the provided running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_bgp_global: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/deleted_af.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/deleted_af.yaml
new file mode 100644
index 0000000..9792125
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/deleted_af.yaml
@@ -0,0 +1,26 @@
+---
+- debug:
+ msg: START vyos_bgp_global replaced integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate_af.yaml
+
+- block:
+
+ - name: Delete the existing configuration, in presence of an af under neighbor.
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ state: deleted
+
+ - assert:
+ that:
+ - result.msg == 'Use the _bgp_address_family module to delete the address_family under neighbor 5001::64, before replacing/deleting the neighbor.'
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/empty_config.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/empty_config.yaml
new file mode 100644
index 0000000..7e52d1c
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/empty_config.yaml
@@ -0,0 +1,49 @@
+---
+- debug:
+ msg: START vyos_bgp_global empty_config integration tests on connection={{
+ ansible_connection }}
+
+- name: Merged with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_bgp_global:
+ config:
+ state: merged
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state merged'
+
+- name: Replaced with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_bgp_global:
+ config:
+ state: replaced
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state replaced'
+
+- name: Parsed with empty running_config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_bgp_global:
+ running_config:
+ state: parsed
+
+- assert:
+ that:
+ - result.msg == 'value of running_config parameter must not be empty for state
+ parsed'
+
+- name: Rendered with empty config should give appropriate error message
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_bgp_global:
+ config:
+ state: rendered
+
+- assert:
+ that:
+ - result.msg == 'value of config parameter must not be empty for state rendered'
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/gathered.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/gathered.yaml
new file mode 100644
index 0000000..7ec1da8
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/gathered.yaml
@@ -0,0 +1,24 @@
+---
+- debug:
+ msg: START vyos_bgp_global gathered integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Gather config from the device in structured format.
+ register: result
+ vyos.vyos.vyos_bgp_global:
+ state: gathered
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: bgp_global
+
+ - assert:
+ that:
+ - result.changed == false
+ - result.gathered == ansible_facts['network_resources']['bgp_global']
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/merged.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/merged.yaml
new file mode 100644
index 0000000..8a09c01
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/merged.yaml
@@ -0,0 +1,71 @@
+---
+- debug:
+ msg: START vyos_bgp_global merged integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _preconfig.yaml
+
+- block:
+
+ - name: Merge the provided configuration with the exisiting running configuration
+ register: result
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ aggregate_address:
+ - prefix: "203.0.113.0/24"
+ as_set: true
+ - prefix: "192.0.2.0/24"
+ summary_only: true
+ network:
+ - address: "192.1.13.0/24"
+ backdoor: true
+ redistribute:
+ - protocol: "kernel"
+ metric: 45
+ - protocol: "connected"
+ route_map: "map01"
+ maximum_paths:
+ - path: "ebgp"
+ count: 20
+ - path: "ibgp"
+ count: 55
+ timers:
+ keepalive: 35
+ bgp_params:
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ router_id: "192.1.2.9"
+ state: merged
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: bgp_global
+
+ - assert:
+ that:
+ - result.commands|length == 12
+ - result.changed == true
+ - result.commands|symmetric_difference(merged.commands) == []
+ - result.after == ansible_facts['network_resources']['bgp_global']
+ - result.before == {}
+ - result.after == merged.after
+
+ - name: Merge the provided configuration with the existing running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_bgp_global: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/parsed.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/parsed.yaml
new file mode 100644
index 0000000..419df6a
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/parsed.yaml
@@ -0,0 +1,16 @@
+---
+- debug:
+ msg: START vyos_bgp_global parsed integration tests on connection={{ ansible_connection
+ }}
+
+- name: Provide the running configuration for parsing (config to be parsed)
+ become: true
+ register: result
+ vyos.vyos.vyos_bgp_global:
+ running_config: "{{ lookup('file', '_parsed_config.cfg') }}"
+ state: parsed
+
+- assert:
+ that:
+ - result.changed == false
+ - result.parsed == populate.global
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/purged.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/purged.yaml
new file mode 100644
index 0000000..9588e80
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/purged.yaml
@@ -0,0 +1,32 @@
+---
+- debug:
+ msg: START vyos_bgp_global purged integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Purge the provided configuration
+ register: result
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ state: purged
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: bgp_global
+
+ - assert:
+ that:
+ - result.commands|length == 1
+ - result.changed == true
+ - "'delete protocols bgp 65536' in result.commands"
+ - ansible_facts.network_resources.bgp_global == []
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/rendered.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/rendered.yaml
new file mode 100644
index 0000000..3a44a5e
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/rendered.yaml
@@ -0,0 +1,45 @@
+---
+- debug:
+ msg: START vyos_bgp_global merged integration tests on connection={{
+ ansible_connection }}
+
+- block:
+
+ - name: Render given bgp_global configuration
+ register: result
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ aggregate_address:
+ - prefix: "203.0.113.0/24"
+ as_set: true
+ - prefix: "192.0.2.0/24"
+ summary_only: true
+ network:
+ - address: "192.1.13.0/24"
+ backdoor: true
+ redistribute:
+ - protocol: "kernel"
+ metric: 45
+ - protocol: "connected"
+ route_map: "map01"
+ maximum_paths:
+ - path: "ebgp"
+ count: 20
+ - path: "ibgp"
+ count: 55
+ timers:
+ keepalive: 35
+ bgp_params:
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ router_id: "192.1.2.9"
+ state: rendered
+
+ - assert:
+ that:
+ - result.changed == false
+ - result.rendered|symmetric_difference(merged.commands) == []
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/replaced.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/replaced.yaml
new file mode 100644
index 0000000..2a8b407
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/replaced.yaml
@@ -0,0 +1,72 @@
+---
+- debug:
+ msg: START vyos_bgp_global replaced integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate.yaml
+
+- block:
+
+ - name: Replace the existing configuration with the provided running configuration
+ register: result
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ network:
+ - address: "203.0.113.0/24"
+ route_map: map01
+ redistribute:
+ - protocol: "static"
+ route_map: "map01"
+ bgp_params:
+ always_compare_med: true
+ dampening:
+ start_suppress_time: 5
+ max_suppress_time: 20
+ half_life: 33
+ re_use: 60
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ neighbor:
+ - address: "192.0.2.43"
+ disable_connected_check: true
+ advertisement_interval: 72
+ capability:
+ dynamic: true
+ timers:
+ holdtime: 30
+ keepalive: 10
+ - address: "203.0.113.0"
+ capability:
+ orf: "receive"
+ state: replaced
+
+ - become: true
+ vyos.vyos.vyos_facts:
+ gather_network_resources: bgp_global
+
+ - assert:
+ that:
+ - result.commands|length == 24
+ - result.changed == true
+ - result.commands|symmetric_difference(replaced.commands) == []
+ - result.after == ansible_facts['network_resources']['bgp_global']
+
+ - name: Replace the existing configuration with the provided running configuration
+ (IDEMPOTENT)
+ register: result
+ vyos.vyos.vyos_bgp_global: *id001
+
+ - name: Assert that the previous task was idempotent
+ assert:
+ that:
+ - result['changed'] == false
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_bgp_global/tests/cli/replaced_af.yaml b/tests/integration/targets/vyos_bgp_global/tests/cli/replaced_af.yaml
new file mode 100644
index 0000000..abcb177
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/tests/cli/replaced_af.yaml
@@ -0,0 +1,56 @@
+---
+- debug:
+ msg: START vyos_bgp_global replaced integration tests on connection={{
+ ansible_connection }}
+
+- include_tasks: _remove_config.yaml
+
+- include_tasks: _populate_af.yaml
+
+- block:
+
+ - name: Replace the existing af configuration with the provided running configuration
+ register: result
+ ignore_errors: true
+ vyos.vyos.vyos_bgp_global: &id001
+ config:
+ as_number: "65536"
+ network:
+ - address: "203.0.113.0/24"
+ route_map: map01
+ redistribute:
+ - protocol: "static"
+ route_map: "map01"
+ bgp_params:
+ always_compare_med: true
+ dampening:
+ start_suppress_time: 5
+ max_suppress_time: 20
+ half_life: 33
+ re_use: 60
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ neighbor:
+ - address: "192.0.2.43"
+ disable_connected_check: true
+ advertisement_interval: 72
+ capability:
+ dynamic: true
+ timers:
+ holdtime: 30
+ keepalive: 10
+ - address: "203.0.113.0"
+ capability:
+ orf: "receive"
+ state: replaced
+
+ - assert:
+ that:
+ - result.msg == 'Use the _bgp_address_family module to delete the address_family under neighbor 5001::64, before replacing/deleting the neighbor.'
+
+ always:
+
+ - include_tasks: _remove_config.yaml
diff --git a/tests/integration/targets/vyos_bgp_global/vars/main.yaml b/tests/integration/targets/vyos_bgp_global/vars/main.yaml
new file mode 100644
index 0000000..fec5e43
--- /dev/null
+++ b/tests/integration/targets/vyos_bgp_global/vars/main.yaml
@@ -0,0 +1,150 @@
+---
+merged:
+ commands:
+ - set protocols bgp 65536 redistribute kernel metric 45
+ - set protocols bgp 65536 redistribute connected route-map map01
+ - set protocols bgp 65536 network 192.1.13.0/24 backdoor
+ - set protocols bgp 65536 aggregate-address 203.0.113.0/24 as-set
+ - set protocols bgp 65536 aggregate-address 192.0.2.0/24 summary-only
+ - set protocols bgp 65536 parameters bestpath as-path confed
+ - set protocols bgp 65536 parameters bestpath compare-routerid
+ - set protocols bgp 65536 parameters default no-ipv4-unicast
+ - set protocols bgp 65536 parameters router-id 192.1.2.9
+ - set protocols bgp 65536 maximum-paths ebgp 20
+ - set protocols bgp 65536 maximum-paths ibgp 55
+ - set protocols bgp 65536 timers keepalive 35
+ after:
+ aggregate_address:
+ - prefix: "192.0.2.0/24"
+ summary_only: true
+ - prefix: "203.0.113.0/24"
+ as_set: true
+ as_number: 65536
+ bgp_params:
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ default:
+ no_ipv4_unicast: true
+ router_id: "192.1.2.9"
+ maximum_paths:
+ - count: 20
+ path: "ebgp"
+ - count: 55
+ path: "ibgp"
+ network:
+ - address: "192.1.13.0/24"
+ backdoor: true
+ redistribute:
+ - protocol: "connected"
+ route_map: "map01"
+ - metric: 45
+ protocol: "kernel"
+ timers:
+ keepalive: 35
+
+replaced:
+ commands:
+ - delete protocols bgp 65536 timers
+ - delete protocols bgp 65536 maximum-paths
+ - delete protocols bgp 65536 parameters router-id 192.1.2.9
+ - delete protocols bgp 65536 parameters confederation
+ - delete protocols bgp 65536 aggregate-address
+ - delete protocols bgp 65536 network 192.1.13.0/24
+ - delete protocols bgp 65536 redistribute kernel
+ - delete protocols bgp 65536 redistribute connected
+ - delete protocols bgp 65536 neighbor 5001::64
+ - delete protocols bgp 65536 neighbor 203.0.113.5
+ - delete protocols bgp 65536 neighbor 192.0.2.25
+ - set protocols bgp 65536 neighbor 192.0.2.43 disable-connected-check
+ - set protocols bgp 65536 neighbor 192.0.2.43 advertisement-interval 72
+ - set protocols bgp 65536 neighbor 192.0.2.43 capability dynamic
+ - set protocols bgp 65536 neighbor 192.0.2.43 timers holdtime 30
+ - set protocols bgp 65536 neighbor 192.0.2.43 timers keepalive 10
+ - set protocols bgp 65536 neighbor 203.0.113.0 capability orf prefix-list receive
+ - set protocols bgp 65536 redistribute static route-map map01
+ - set protocols bgp 65536 network 203.0.113.0/24 route-map map01
+ - set protocols bgp 65536 parameters always-compare-med
+ - set protocols bgp 65536 parameters dampening half-life 33
+ - set protocols bgp 65536 parameters dampening max-suppress-time 20
+ - set protocols bgp 65536 parameters dampening re-use 60
+ - set protocols bgp 65536 parameters dampening start-suppress-time 5
+
+deleted:
+ commands:
+ - delete protocols bgp 65536 timers
+ - delete protocols bgp 65536 maximum-paths
+ - delete protocols bgp 65536 parameters
+ - delete protocols bgp 65536 aggregate-address
+ - delete protocols bgp 65536 network
+ - delete protocols bgp 65536 redistribute
+ - delete protocols bgp 65536 neighbor 5001::64
+ - delete protocols bgp 65536 neighbor 203.0.113.5
+ - delete protocols bgp 65536 neighbor 192.0.2.25
+
+rendered:
+ commands:
+ - set interfaces ethernet eth1 firewall in name 'INBOUND'
+ - set interfaces ethernet eth1 firewall out name 'OUTBOUND'
+ - set interfaces ethernet eth1 firewall local name 'LOCAL'
+ - set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'
+ - set interfaces ethernet eth2 firewall in name 'INBOUND'
+ - set interfaces ethernet eth2 firewall out name 'OUTBOUND'
+ - set interfaces ethernet eth2 firewall local name 'LOCAL'
+ - set interfaces ethernet eth2 firewall local ipv6-name 'V6-LOCAL'
+
+populate:
+ global:
+ aggregate_address:
+ - prefix: "192.0.2.0/24"
+ summary_only: true
+ - prefix: "203.0.113.0/24"
+ as_set: true
+ as_number: 65536
+ bgp_params:
+ bestpath:
+ as_path: "confed"
+ compare_routerid: true
+ confederation:
+ - identifier: 66
+ - peers: 20
+ - peers: 55
+ default:
+ no_ipv4_unicast: true
+ router_id: "192.1.2.9"
+ maximum_paths:
+ - count: 20
+ path: "ebgp"
+ - count: 55
+ path: "ibgp"
+ neighbor:
+ - address: "192.0.2.25"
+ disable_connected_check: true
+ timers:
+ holdtime: 30
+ keepalive: 10
+ - address: "203.0.113.5"
+ attribute_unchanged:
+ as_path: true
+ med: true
+ next_hop: true
+ ebgp_multihop: 2
+ remote_as: 101
+ update_source: "192.0.2.25"
+ - address: "5001::64"
+ distribute_list:
+ - acl: 20
+ action: "export"
+ - acl: 40
+ action: "import"
+ maximum_prefix: 34
+ network:
+ - address: "192.1.13.0/24"
+ backdoor: true
+ redistribute:
+ - protocol: "connected"
+ route_map: "map01"
+ - metric: 45
+ protocol: "kernel"
+ timers:
+ keepalive: 35
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_af_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_af_config.cfg
new file mode 100644
index 0000000..7d990d6
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_af_config.cfg
@@ -0,0 +1,5 @@
+set protocols bgp 65536 neighbor 5001::64 address-family 'ipv6-unicast'
+set protocols bgp 65536 neighbor 5001::64 ebgp-multihop '2'
+set protocols bgp 65536 neighbor 5001::64 maximum-prefix '34'
+set protocols bgp 65536 neighbor 5001::64 remote-as '65535'
+set protocols bgp 65536 neighbor 5001::64 update-source '2001:db8::1'
diff --git a/tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_config.cfg b/tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_config.cfg
new file mode 100644
index 0000000..00c615f
--- /dev/null
+++ b/tests/unit/modules/network/vyos/fixtures/vyos_bgp_global_config.cfg
@@ -0,0 +1,23 @@
+set protocols bgp 65536 neighbor 10.0.0.4 'disable-connected-check'
+set protocols bgp 65536 neighbor 10.0.0.4 timers holdtime '30'
+set protocols bgp 65536 neighbor 10.0.0.4 timers keepalive '10'
+set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged 'as-path'
+set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged 'med'
+set protocols bgp 65536 neighbor 192.168.0.2 ebgp-multihop '2'
+set protocols bgp 65536 neighbor 192.168.0.2 remote-as '65535'
+set protocols bgp 65536 neighbor 192.168.0.2 soft-reconfiguration 'inbound'
+set protocols bgp 65536 neighbor 192.168.0.2 update-source '192.168.0.1'
+set protocols bgp 65536 neighbor 2001:db8::2 ebgp-multihop '2'
+set protocols bgp 65536 neighbor 2001:db8::2 maximum-prefix '34'
+set protocols bgp 65536 neighbor 2001:db8::2 remote-as '65535'
+set protocols bgp 65536 neighbor 2001:db8::2 update-source '2001:db8::1'
+set protocols bgp 65536 network 172.16.42.32/27 'backdoor'
+set protocols bgp 65536 network 172.16.42.251/32 route-map 'map01'
+set protocols bgp 65536 parameters bestpath as-path 'confed'
+set protocols bgp 65536 parameters bestpath 'compare-routerid'
+set protocols bgp 65536 parameters default 'no-ipv4-unicast'
+set protocols bgp 65536 parameters router-id '10.1.1.1'
+set protocols bgp 65536 neighbor 10.0.0.4 capability orf prefix-list 'receive'
+set protocols bgp 65536 redistribute kernel route-map 'map01'
+set protocols bgp 65536 redistribute static metric '20'
+set protocols bgp 65536 redistribute static route-map 'map01'
diff --git a/tests/unit/modules/network/vyos/test_vyos_bgp_global.py b/tests/unit/modules/network/vyos/test_vyos_bgp_global.py
new file mode 100644
index 0000000..bdb29c0
--- /dev/null
+++ b/tests/unit/modules/network/vyos/test_vyos_bgp_global.py
@@ -0,0 +1,562 @@
+# (c) 2016 Red Hat Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
+
+# Make coding more python3-ish
+from __future__ import absolute_import, division, print_function
+
+__metaclass__ = type
+
+from ansible_collections.vyos.vyos.tests.unit.compat.mock import patch
+from ansible_collections.vyos.vyos.plugins.modules import vyos_bgp_global
+from ansible_collections.vyos.vyos.tests.unit.modules.utils import (
+ set_module_args,
+)
+from .vyos_module import TestVyosModule, load_fixture
+
+
+class TestVyosBgpglobalModule(TestVyosModule):
+
+ module = vyos_bgp_global
+
+ def setUp(self):
+ super(TestVyosBgpglobalModule, self).setUp()
+
+ self.mock_get_resource_connection_config = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module_base.get_resource_connection"
+ )
+ self.get_resource_connection_config = (
+ self.mock_get_resource_connection_config.start()
+ )
+
+ self.mock_execute_show_command_config = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.bgp_global.bgp_global.Bgp_global._get_config"
+ )
+ self.execute_show_command_config = (
+ self.mock_execute_show_command_config.start()
+ )
+
+ self.mock_get_resource_connection_facts = patch(
+ "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection"
+ )
+ self.get_resource_connection_facts = (
+ self.mock_get_resource_connection_facts.start()
+ )
+
+ self.mock_execute_show_command = patch(
+ "ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_global.bgp_global.Bgp_globalFacts.get_device_data"
+ )
+
+ self.execute_show_command = self.mock_execute_show_command.start()
+
+ def tearDown(self):
+ super(TestVyosBgpglobalModule, self).tearDown()
+ self.mock_get_resource_connection_config.stop()
+ self.mock_get_resource_connection_facts.stop()
+ self.mock_execute_show_command.stop()
+ self.mock_execute_show_command_config.stop()
+
+ def load_fixtures(self, commands=None, transport="cli", filename=None):
+ if filename is None:
+ filename = "vyos_bgp_global_config.cfg"
+
+ def load_from_file(*args, **kwargs):
+ output = load_fixture(filename)
+ return output
+
+ self.execute_show_command.side_effect = load_from_file
+ self.execute_show_command_config.side_effect = load_from_file
+
+ def test_vyos_bgp_global_merged_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ neighbor=[
+ dict(
+ address="10.0.0.4",
+ disable_connected_check=True,
+ timers=dict(holdtime=30, keepalive=10),
+ capability=dict(orf="receive"),
+ ),
+ dict(
+ address="192.168.0.2",
+ attribute_unchanged=dict(as_path=True, med=True),
+ ebgp_multihop=2,
+ remote_as="65535",
+ soft_reconfiguration=True,
+ update_source="192.168.0.1",
+ ),
+ dict(
+ address="2001:db8::2",
+ ebgp_multihop=2,
+ remote_as="65535",
+ maximum_prefix=34,
+ update_source="2001:db8::1",
+ ),
+ ],
+ network=[
+ dict(address="172.16.42.32/27", backdoor=True),
+ dict(address="172.16.42.251/32", route_map="map01"),
+ ],
+ bgp_params=dict(
+ bestpath=dict(as_path="confed", compare_routerid=True),
+ default=dict(no_ipv4_unicast=True),
+ router_id="10.1.1.1",
+ ),
+ redistribute=[
+ dict(protocol="kernel", route_map="map01"),
+ dict(protocol="static", metric=20),
+ dict(protocol="static", route_map="map01"),
+ ],
+ ),
+ state="merged",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ def test_vyos_bgp_global_merged(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ maximum_paths=[
+ dict(path="ebgp", count=20),
+ dict(path="ibgp", count=45),
+ ],
+ neighbor=[
+ dict(
+ address="2001:db8::2",
+ ebgp_multihop=2,
+ remote_as="65535",
+ maximum_prefix=34,
+ update_source="2001:db8::1",
+ distribute_list=[
+ dict(action="export", acl=31),
+ dict(action="import", acl=9),
+ ],
+ )
+ ],
+ bgp_params=dict(
+ confederation=[dict(peers=20), dict(identifier=66)],
+ router_id="10.1.1.1",
+ ),
+ ),
+ state="merged",
+ )
+ )
+ commands = [
+ "set protocols bgp 65536 neighbor 2001:db8::2 distribute-list export 31",
+ "set protocols bgp 65536 neighbor 2001:db8::2 distribute-list import 9",
+ "set protocols bgp 65536 parameters confederation peers 20",
+ "set protocols bgp 65536 parameters confederation identifier 66",
+ "set protocols bgp 65536 maximum-paths ebgp 20",
+ "set protocols bgp 65536 maximum-paths ibgp 45",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ def test_vyos_bgp_global_replaced_idempotent(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ neighbor=[
+ dict(
+ address="10.0.0.4",
+ disable_connected_check=True,
+ timers=dict(holdtime=30, keepalive=10),
+ capability=dict(orf="receive"),
+ ),
+ dict(
+ address="192.168.0.2",
+ attribute_unchanged=dict(as_path=True, med=True),
+ ebgp_multihop=2,
+ remote_as="65535",
+ soft_reconfiguration=True,
+ update_source="192.168.0.1",
+ ),
+ dict(
+ address="2001:db8::2",
+ ebgp_multihop=2,
+ remote_as="65535",
+ maximum_prefix=34,
+ update_source="2001:db8::1",
+ ),
+ ],
+ network=[
+ dict(address="172.16.42.32/27", backdoor=True),
+ dict(address="172.16.42.251/32", route_map="map01"),
+ ],
+ bgp_params=dict(
+ bestpath=dict(as_path="confed", compare_routerid=True),
+ default=dict(no_ipv4_unicast=True),
+ router_id="10.1.1.1",
+ ),
+ redistribute=[
+ dict(protocol="kernel", route_map="map01"),
+ dict(protocol="static", metric=20),
+ dict(protocol="static", route_map="map01"),
+ ],
+ ),
+ state="replaced",
+ )
+ )
+ self.execute_module(changed=False, commands=[])
+
+ #
+ def test_vyos_bgp_global_replaced(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ timers=dict(holdtime=30, keepalive=10),
+ neighbor=[
+ dict(
+ address="200.11.155.3",
+ prefix_list=[
+ dict(action="export", prefix_list=10),
+ ],
+ allowas_in=10,
+ ),
+ dict(
+ address="2001:db8::2",
+ remote_as="65535",
+ as_override=True,
+ default_originate="map01",
+ route_map=[
+ dict(action="export", route_map="map01"),
+ ],
+ ),
+ ],
+ bgp_params=dict(
+ log_neighbor_changes=True,
+ no_client_to_client_reflection=True,
+ confederation=[dict(peers=20), dict(identifier=66)],
+ router_id="10.1.1.1",
+ ),
+ ),
+ state="replaced",
+ )
+ )
+ commands = [
+ "delete protocols bgp 65536 parameters default",
+ "delete protocols bgp 65536 parameters bestpath compare-routerid",
+ "delete protocols bgp 65536 parameters bestpath as-path confed",
+ "delete protocols bgp 65536 network",
+ "delete protocols bgp 65536 redistribute",
+ "delete protocols bgp 65536 neighbor 2001:db8::2 update-source 2001:db8::1",
+ "delete protocols bgp 65536 neighbor 2001:db8::2 maximum-prefix 34",
+ "delete protocols bgp 65536 neighbor 2001:db8::2 ebgp-multihop 2",
+ "delete protocols bgp 65536 neighbor 192.168.0.2",
+ "delete protocols bgp 65536 neighbor 10.0.0.4",
+ "set protocols bgp 65536 neighbor 200.11.155.3 prefix-list export 10",
+ "set protocols bgp 65536 neighbor 200.11.155.3 allowas-in number 10",
+ "set protocols bgp 65536 neighbor 2001:db8::2 as-override",
+ "set protocols bgp 65536 neighbor 2001:db8::2 route-map export map01",
+ "set protocols bgp 65536 parameters log-neighbor-changes",
+ "set protocols bgp 65536 parameters no-client-to-client-reflection",
+ "set protocols bgp 65536 parameters confederation peers 20",
+ "set protocols bgp 65536 parameters confederation identifier 66",
+ "set protocols bgp 65536 timers holdtime 30",
+ "set protocols bgp 65536 timers keepalive 10",
+ ]
+ self.execute_module(changed=True, commands=commands)
+
+ #
+ def test_vyos_bgp_global_purged(self):
+ set_module_args(dict(config=dict(as_number="65536"), state="purged"))
+ #
+ commands = ["delete protocols bgp 65536"]
+ self.execute_module(changed=True, commands=commands)
+
+ #
+ def test_vyos_bgp_global_incorrect_instance(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="100",
+ timers=dict(holdtime=30, keepalive=10),
+ neighbor=[
+ dict(
+ address="200.11.155.3",
+ prefix_list=[
+ dict(action="export", prefix_list=10),
+ ],
+ allowas_in=10,
+ ),
+ dict(
+ address="2001:db8::2",
+ remote_as="65535",
+ as_override=True,
+ default_originate="map01",
+ route_map=[
+ dict(action="export", route_map="map01"),
+ ],
+ ),
+ ],
+ bgp_params=dict(
+ log_neighbor_changes=True,
+ no_client_to_client_reflection=True,
+ confederation=[dict(peers=20), dict(identifier=66)],
+ router_id="10.1.1.1",
+ ),
+ ),
+ state="replaced",
+ )
+ )
+ result = self.execute_module(failed=True)
+ self.assertIn(
+ "Only one bgp instance is allowed per device", result["msg"]
+ )
+
+ def test_vyos_bgp_global_replaced_af(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ timers=dict(holdtime=30, keepalive=10),
+ neighbor=[
+ dict(
+ address="200.11.155.3",
+ prefix_list=[
+ dict(action="export", prefix_list=10),
+ ],
+ allowas_in=10,
+ ),
+ dict(
+ address="2001:db8::2",
+ remote_as="65535",
+ as_override=True,
+ default_originate="map01",
+ route_map=[
+ dict(action="export", route_map="map01"),
+ ],
+ ),
+ ],
+ bgp_params=dict(
+ log_neighbor_changes=True,
+ no_client_to_client_reflection=True,
+ confederation=[dict(peers=20), dict(identifier=66)],
+ router_id="10.1.1.1",
+ ),
+ ),
+ state="replaced",
+ )
+ )
+ result = self.execute_module(
+ failed=True, filename="vyos_bgp_global_af_config.cfg"
+ )
+ self.assertIn(
+ "Use the _bgp_address_family module to delete the address_family under neighbor 5001::64, before replacing/deleting the neighbor.",
+ result["msg"],
+ )
+
+ def test_vyos_bgp_global_rendered(self):
+ set_module_args(
+ dict(
+ config=dict(
+ as_number="65536",
+ neighbor=[
+ dict(
+ address="10.0.0.4",
+ disable_connected_check=True,
+ timers=dict(holdtime=30, keepalive=10),
+ capability=dict(orf="receive"),
+ ),
+ dict(
+ address="192.168.0.2",
+ attribute_unchanged=dict(as_path=True, med=True),
+ ebgp_multihop=2,
+ remote_as="65535",
+ soft_reconfiguration=True,
+ update_source="192.168.0.1",
+ ),
+ dict(
+ address="2001:db8::2",
+ ebgp_multihop=2,
+ remote_as="65535",
+ maximum_prefix=34,
+ update_source="2001:db8::1",
+ ),
+ ],
+ network=[
+ dict(address="172.16.42.32/27", backdoor=True),
+ dict(address="172.16.42.251/32", route_map="map01"),
+ ],
+ bgp_params=dict(
+ bestpath=dict(as_path="confed", compare_routerid=True),
+ default=dict(no_ipv4_unicast=True),
+ router_id="10.1.1.1",
+ ),
+ redistribute=[
+ dict(protocol="kernel", route_map="map01"),
+ dict(protocol="static", metric=20),
+ dict(protocol="static", route_map="map01"),
+ ],
+ ),
+ state="rendered",
+ )
+ )
+ rendered_cmds = [
+ "set protocols bgp 65536 neighbor 10.0.0.4 disable-connected-check",
+ "set protocols bgp 65536 neighbor 10.0.0.4 timers holdtime 30",
+ "set protocols bgp 65536 neighbor 10.0.0.4 timers keepalive 10",
+ "set protocols bgp 65536 neighbor 10.0.0.4 capability orf prefix-list receive",
+ "set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged as-path",
+ "set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged med",
+ "set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged next-hop",
+ "set protocols bgp 65536 neighbor 192.168.0.2 ebgp-multihop 2",
+ "set protocols bgp 65536 neighbor 192.168.0.2 remote-as 65535",
+ "set protocols bgp 65536 neighbor 192.168.0.2 soft-reconfiguration",
+ "set protocols bgp 65536 neighbor 192.168.0.2 update-source 192.168.0.1",
+ "set protocols bgp 65536 neighbor 2001:db8::2 ebgp-multihop 2",
+ "set protocols bgp 65536 neighbor 2001:db8::2 remote-as 65535",
+ "set protocols bgp 65536 neighbor 2001:db8::2 maximum-prefix 34",
+ "set protocols bgp 65536 neighbor 2001:db8::2 update-source 2001:db8::1",
+ "set protocols bgp 65536 redistribute kernel route-map map01",
+ "set protocols bgp 65536 redistribute static route-map map01",
+ "set protocols bgp 65536 network 172.16.42.32/27 backdoor",
+ "set protocols bgp 65536 network 172.16.42.251/32 route-map map01",
+ "set protocols bgp 65536 parameters bestpath as-path confed",
+ "set protocols bgp 65536 parameters bestpath compare-routerid",
+ "set protocols bgp 65536 parameters default no-ipv4-unicast",
+ "set protocols bgp 65536 parameters router-id 10.1.1.1",
+ ]
+ result = self.execute_module(changed=False)
+ self.assertEqual(
+ sorted(result["rendered"]),
+ sorted(rendered_cmds),
+ result["rendered"],
+ )
+
+ def test_vyos_bgp_global_parsed(self):
+
+ commands = [
+ "set protocols bgp 65536 neighbor 10.0.0.4 disable-connected-check",
+ "set protocols bgp 65536 neighbor 10.0.0.4 timers holdtime 30",
+ "set protocols bgp 65536 neighbor 10.0.0.4 timers keepalive 10",
+ "set protocols bgp 65536 neighbor 10.0.0.4 capability orf prefix-list receive",
+ "set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged as-path",
+ "set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged med",
+ "set protocols bgp 65536 neighbor 192.168.0.2 attribute-unchanged next-hop",
+ "set protocols bgp 65536 neighbor 192.168.0.2 ebgp-multihop 2",
+ "set protocols bgp 65536 neighbor 192.168.0.2 remote-as 65535",
+ "set protocols bgp 65536 neighbor 192.168.0.2 soft-reconfiguration",
+ "set protocols bgp 65536 neighbor 192.168.0.2 update-source 192.168.0.1",
+ "set protocols bgp 65536 neighbor 2001:db8::2 ebgp-multihop 2",
+ "set protocols bgp 65536 neighbor 2001:db8::2 remote-as 65535",
+ "set protocols bgp 65536 neighbor 2001:db8::2 maximum-prefix 34",
+ "set protocols bgp 65536 neighbor 2001:db8::2 update-source 2001:db8::1",
+ "set protocols bgp 65536 redistribute kernel route-map map01",
+ "set protocols bgp 65536 redistribute static route-map map01",
+ "set protocols bgp 65536 network 172.16.42.32/27 backdoor",
+ "set protocols bgp 65536 network 172.16.42.251/32 route-map map01",
+ "set protocols bgp 65536 parameters bestpath as-path confed",
+ "set protocols bgp 65536 parameters bestpath compare-routerid",
+ "set protocols bgp 65536 parameters default no-ipv4-unicast",
+ "set protocols bgp 65536 parameters router-id 10.1.1.1",
+ ]
+ parsed_str = "\n".join(commands)
+ set_module_args(dict(running_config=parsed_str, state="parsed"))
+ result = self.execute_module(changed=False)
+ parsed_list = {
+ "as_number": 65536,
+ "bgp_params": {
+ "bestpath": {"as_path": "confed", "compare_routerid": True},
+ "default": {"no_ipv4_unicast": True},
+ "router_id": "10.1.1.1",
+ },
+ "neighbor": [
+ {
+ "address": "10.0.0.4",
+ "capability": {"orf": "receive"},
+ "disable_connected_check": True,
+ "timers": {"holdtime": 30, "keepalive": 10},
+ },
+ {
+ "address": "192.168.0.2",
+ "attribute_unchanged": {
+ "as_path": True,
+ "med": True,
+ "next_hop": True,
+ },
+ "ebgp_multihop": 2,
+ "remote_as": 65535,
+ "update_source": "192.168.0.1",
+ },
+ {
+ "address": "2001:db8::2",
+ "ebgp_multihop": 2,
+ "maximum_prefix": 34,
+ "remote_as": 65535,
+ "update_source": "2001:db8::1",
+ },
+ ],
+ "network": [
+ {"address": "172.16.42.32/27", "backdoor": True},
+ {"address": "172.16.42.251/32", "route_map": "map01"},
+ ],
+ "redistribute": [
+ {"protocol": "kernel", "route_map": "map01"},
+ {"protocol": "static", "route_map": "map01"},
+ ],
+ }
+ self.assertEqual(sorted(parsed_list), sorted(result["parsed"]))
+
+ def test_vyos_bgp_global_gathered(self):
+ set_module_args(dict(state="gathered"))
+ result = self.execute_module(changed=False)
+ gather_list = {
+ "as_number": 65536,
+ "bgp_params": {
+ "bestpath": {"as_path": "confed", "compare_routerid": True},
+ "default": {"no_ipv4_unicast": True},
+ "router_id": "10.1.1.1",
+ },
+ "neighbor": [
+ {
+ "address": "10.0.0.4",
+ "capability": {"orf": "receive"},
+ "disable_connected_check": True,
+ "timers": {"holdtime": 30, "keepalive": 10},
+ },
+ {
+ "address": "192.168.0.2",
+ "attribute_unchanged": {"as_path": True, "med": True},
+ "ebgp_multihop": 2,
+ "remote_as": 65535,
+ "soft_reconfiguration": True,
+ "update_source": "192.168.0.1",
+ },
+ {
+ "address": "2001:db8::2",
+ "ebgp_multihop": 2,
+ "maximum_prefix": 34,
+ "remote_as": 65535,
+ "update_source": "2001:db8::1",
+ },
+ ],
+ "network": [
+ {"address": "172.16.42.32/27", "backdoor": True},
+ {"address": "172.16.42.251/32", "route_map": "map01"},
+ ],
+ "redistribute": [
+ {"protocol": "kernel", "route_map": "map01"},
+ {"metric": 20, "protocol": "static"},
+ {"protocol": "static", "route_map": "map01"},
+ ],
+ }
+ self.assertEqual(sorted(gather_list), sorted(result["gathered"]))
diff --git a/tests/unit/modules/network/vyos/vyos_module.py b/tests/unit/modules/network/vyos/vyos_module.py
index 49d4652..cb7874f 100644
--- a/tests/unit/modules/network/vyos/vyos_module.py
+++ b/tests/unit/modules/network/vyos/vyos_module.py
@@ -62,7 +62,11 @@ class TestVyosModule(ModuleTestCase):
defaults=False,
filename=None,
):
- self.load_fixtures(commands)
+
+ if filename is None:
+ self.load_fixtures(commands)
+ else:
+ self.load_fixtures(commands, filename=filename)
if failed:
result = self.failed()
@@ -101,5 +105,5 @@ class TestVyosModule(ModuleTestCase):
self.assertEqual(result["changed"], changed, result)
return result
- def load_fixtures(self, commands=None):
+ def load_fixtures(self, commands=None, filename=None):
pass