Page MenuHomeVyOS Platform

No OneTemporary

Size
95 KB
Referenced Files
None
Subscribers
None
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index d5617c09..57f1810b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,56 +1,58 @@
---
ci:
# format compatible with commitlint
autoupdate_commit_msg: "chore: pre-commit autoupdate"
autoupdate_schedule: monthly
autofix_commit_msg: "chore: auto fixes from pre-commit.com hooks"
repos:
- repo: https://github.com/ansible-network/collection_prep
- rev: 1.1.1
+ rev: 1.1.2
hooks:
- id: update-docs
+ additional_dependencies:
+ - "ansible-core==2.18.*"
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-merge-conflict
- id: check-symlinks
- id: debug-statements
- id: end-of-file-fixer
- id: no-commit-to-branch
args: [--branch, main]
- id: trailing-whitespace
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.1.0
hooks:
- id: add-trailing-comma
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v4.0.0-alpha.8
hooks:
- id: prettier
entry: env CI=1 bash -c "prettier --list-different . || ec=$? && prettier --loglevel=error --write . && exit $ec"
pass_filenames: false
args: []
additional_dependencies:
- prettier
- prettier-plugin-toml
- repo: https://github.com/PyCQA/isort
rev: 6.0.0
hooks:
- id: isort
name: Sort import statements using isort
args: [--filter-files]
- repo: https://github.com/psf/black
rev: 25.1.0
hooks:
- id: black
- repo: https://github.com/pycqa/flake8
rev: 7.1.2
hooks:
- id: flake8
diff --git a/README.md b/README.md
index 6650cb67..73c6330e 100644
--- a/README.md
+++ b/README.md
@@ -1,264 +1,263 @@
# VyOS Collection
[![codecov](https://codecov.io/gh/vyos/vyos.vyos/graph/badge.svg?token=J217GFD69W)](https://codecov.io/gh/vyos/vyos.vyos)
[![CI](https://github.com/vyos/vyos.vyos/actions/workflows/tests.yml/badge.svg?branch=main&event=schedule)](https://github.com/vyos/vyos.vyos/actions/workflows/tests.yml)
The Ansible VyOS collection includes a variety of Ansible content to help automate the management of VyOS network appliances.
This collection has been tested against VyOS 1.3.8, 1.4.1 and the current rolling release for 1.5. Where possible,
compatibility with older versions of VyOS are maintained but not guaranteed.
## Communication
* Join the VyOS forum:
* [FAQ](https://forum.vyos.io/faq): find answers to frequently asked questions.
* [Guides and How To](https://forum.vyos.io/c/howto-guies/27): find guides and how-to articles.
* [News & Announcements](https://forum.vyos.io/c/announcements/6): track project-wide announcements .
<!--start requires_ansible-->
## Ansible version compatibility
-This collection has been tested against following Ansible versions: **>=2.15.0**.
+This collection has been tested against the following Ansible versions: **>=2.15.0**.
-For collections that support Ansible 2.9, please ensure you update your `network_os` to use the
-fully qualified collection name (for example, `cisco.ios.ios`).
Plugins and modules within a collection may be tested with only specific Ansible versions.
A collection may contain metadata that identifies these versions.
PEP440 is the schema used to describe the versions of Ansible.
<!--end requires_ansible-->
### Supported connections
The VyOS collection supports ``network_cli`` connections.
## Included content
<!--start collection content-->
### Cliconf plugins
Name | Description
--- | ---
[vyos.vyos.vyos](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_cliconf.rst)|Use vyos cliconf to run command on VyOS platform
### Modules
Name | Description
--- | ---
[vyos.vyos.vyos_banner](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_banner_module.rst)|Manage multiline banners on VyOS devices
[vyos.vyos.vyos_bgp_address_family](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_bgp_address_family_module.rst)|BGP Address Family resource module
[vyos.vyos.vyos_bgp_global](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_bgp_global_module.rst)|BGP global resource module
[vyos.vyos.vyos_command](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_command_module.rst)|Run one or more commands on VyOS devices
[vyos.vyos.vyos_config](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_config_module.rst)|Manage VyOS configuration on remote device
[vyos.vyos.vyos_facts](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_facts_module.rst)|Get facts about vyos devices.
[vyos.vyos.vyos_firewall_global](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_global_module.rst)|Firewall global resource module
[vyos.vyos.vyos_firewall_interfaces](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_interfaces_module.rst)|Firewall interfaces resource module
[vyos.vyos.vyos_firewall_rules](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_rules_module.rst)|Firewall rules resource module
[vyos.vyos.vyos_hostname](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_hostname_module.rst)|Manages hostname resource module
[vyos.vyos.vyos_interfaces](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_interfaces_module.rst)|Manages interface attributes of VyOS network devices.
[vyos.vyos.vyos_l3_interfaces](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_l3_interfaces_module.rst)|Layer 3 interfaces resource module.
[vyos.vyos.vyos_lag_interfaces](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lag_interfaces_module.rst)|LAG interfaces resource module
[vyos.vyos.vyos_lldp_global](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lldp_global_module.rst)|LLDP global resource module
[vyos.vyos.vyos_lldp_interfaces](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_lldp_interfaces_module.rst)|LLDP interfaces resource module
[vyos.vyos.vyos_logging_global](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_logging_global_module.rst)|Logging resource module
[vyos.vyos.vyos_ntp_global](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ntp_global_module.rst)|NTP global resource module
[vyos.vyos.vyos_ospf_interfaces](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ospf_interfaces_module.rst)|OSPF Interfaces Resource Module.
[vyos.vyos.vyos_ospfv2](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ospfv2_module.rst)|OSPFv2 resource module
[vyos.vyos.vyos_ospfv3](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ospfv3_module.rst)|OSPFv3 resource module
[vyos.vyos.vyos_ping](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_ping_module.rst)|Tests reachability using ping from VyOS network devices
[vyos.vyos.vyos_prefix_lists](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_prefix_lists_module.rst)|Prefix-Lists resource module for VyOS
[vyos.vyos.vyos_route_maps](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_route_maps_module.rst)|Route Map resource module
[vyos.vyos.vyos_snmp_server](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_snmp_server_module.rst)|Manages snmp_server resource module
[vyos.vyos.vyos_static_routes](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_static_routes_module.rst)|Static routes resource module
[vyos.vyos.vyos_system](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_system_module.rst)|Run `set system` commands on VyOS devices
[vyos.vyos.vyos_user](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_user_module.rst)|Manage the collection of local users on VyOS device
[vyos.vyos.vyos_vlan](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_vlan_module.rst)|Manage VLANs on VyOS network devices
+[vyos.vyos.vyos_vrrp](https://github.com/vyos/vyos.vyos/blob/main/docs/vyos.vyos.vyos_vrrp_module.rst)|High Availability (VRRP) resource module
<!--end collection content-->
Click the ``Content`` button to see the list of content included in this collection.
## Installing this collection
You can install the VyOS collection with the Ansible Galaxy CLI:
ansible-galaxy collection install vyos.vyos
You can also include it in a `requirements.yml` file and install it with `ansible-galaxy collection install -r requirements.yml`, using the format:
```yaml
---
collections:
- name: vyos.vyos
```
## Using this collection
This collection includes [network resource modules](https://docs.ansible.com/ansible/latest/network/user_guide/network_resource_modules.html).
### Using modules from the VyOS collection in your playbooks
You can call modules by their Fully Qualified Collection Namespace (FQCN), such as `vyos.vyos.vyos_static_routes`.
The following example task replaces configuration changes in the existing configuration on a VyOS network device, using the FQCN:
```yaml
---
- name: Replace device configurations of listed static routes with provided
configurations
register: result
vyos.vyos.vyos_static_routes: &id001
config:
- address_families:
- afi: ipv4
routes:
- dest: 192.0.2.32/28
blackhole_config:
distance: 2
next_hops:
- forward_router_address: 192.0.2.7
- forward_router_address: 192.0.2.8
- forward_router_address: 192.0.2.9
state: replaced
```
**NOTE**: For Ansible 2.9, you may not see deprecation warnings when you run your playbooks with this collection. Use this documentation to track when a module is deprecated.
### See Also:
* [VyOS Platform Options](https://docs.ansible.com/ansible/latest/network/user_guide/platform_vyos.html)
* [Ansible Using collections](https://docs.ansible.com/ansible/latest/user_guide/collections_using.html) for more details.
## Contributing to this collection
We welcome community contributions to this collection. If you find problems, please open an issue or create a PR against the [VyOS collection repository](https://github.com/vyos/vyos.vyos). See [Contributing to VyOS](https://vyos.net/contribute/) for complete details.
You can also join us on:
- Forum - https://forum.vyos.io
See the [Contributing to VyOS](https://vyos.net/contribute/) for details on contributing to Ansible.
### Code of Conduct
This collection follows the Ansible project's
[Code of Conduct](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html).
Please read and familiarize yourself with this document.
### Updating from resource module models
Some of our modules were templated using `resource_module_builder`, but some use
the newer [`cli_rm_builder`](https://github.com/ansible-network/cli_rm_builder)
which tempaltes baed on in-place device information, but also uses a new network
parsing engine designed to simplify and standardize the parsing of network
configuration.
#### Using older *resource_module_builder* modules
Last build was with a slightly-modified version of resource_module_builder.
This changes the calling parameters for the resources.
To update the collection from the resource module models, run the following command:
```bash
ansible-playbook -e rm_dest=`pwd` \
-e structure=collection \
-e collection_org=vyos \
-e collection_name=vyos \
-e model=../../../resource_module_models/models/vyos/firewall_rules/vyos_firewall_rules.yaml \
../../../resource_module_builder/site.yml
```
#### Using *cli_rm_builder* modules
The newer `cli_rm_builder` works similarly to the older `resource_module_builder`, but
pulls the information directly from the `DOCUMENTATION`, `EXAMPLES` and `RETURN`
blocks in the module itself.
To update the collection from the `cli_rm_builder` models, run the following command:
```bash
ansible-playbook -e rm_dest=`pwd` \
-e collection_org=vyos \
-e collection_name=vyos \
-e resource=bgp_address_family \
../../../cli_rm_builder/run.yml
```
Unlike the `resource_module_builder`, the `cli_rm_builder` does not require the `model` parameter. Instead, it uses the `resource` parameter to specify the resource to build.
### Testing playbooks
You can use `ANSIBLE_COLLECTIONS_PATH` to test the collection locally. For example:
```
ANSIBLE_COLLECTIONS_PATHS=~/my_dev_path ansible-playbook -i inventory.network test.yml
```
### Integration Tests
Integration tests are run using `ansible-test` and require that there be an inventory
defined (you can pass this in with `--inventory <filename>`) and that the system be
configured for access (recommended to use SSH keys).
Additionally:
- eth0 should be configured for `address dhcp` and should have an assigned address
on the local network
- eth1 and eth2 should be defined and uncofirgured (they'll be overwritten by the tests)
- eth3 and beyond should not be present or interface-related tests will fail
- when using VMs for testing, ensure that the interfaces don't use `virtio`, as it will supress
some interface configurations. `e1000e` is a good choice for testing.
- eth0 is also expected to show `duplex auto` and `speed auto` in the output of `show interfaces`,
however others are not due to the fact that they are repeatedly deleted and recreated
which causes the default values to be hidden.
## Changelogs
Change logs are available [here](https://github.com/vyos/vyos.vyos/blob/main/CHANGELOG.rst).
## Release notes
Release notes are available [here](https://github.com/vyos/vyos.vyos/blob/main/CHANGELOG.rst).
## Roadmap
<!-- Optional. Include the roadmap for this collection, and the proposed release/versioning strategy so users can anticipate the upgrade/update cycle. -->
Major Version | Ansible Support | VyOS Support | Details
--- | --- | --- | ---
4.1.0 | 2.15 | 1.1.2 | Final release for the 4.x series
5.0.0 | 2.16 | 1.1.2 | First relase under VyOS control as a separate collection
6.0.0 | 2.18 | 1.3.8 | *Planned* release for supporting VyOS 1.3.8+
7.0.0 | x.xx | 1.4.x | *Prospective* release deprecating incompatible 1.3.x modules
Note:
- Unreleased versions are not guaranteed to be released as described.
- Some modules may support a wider variety of versions depending upon the compatibility
with prior versions of VyOS.
- The roadmap is subject to change based on community feedback and contributions.
## More information
VyOS resources
- [Contributing to VyOS](https://vyos.net/contribute)
- [VyOS documentation](https://docs.vyos.io/en/latest/)
- [VyOS forum](https://forum.vyos.io)
Ansible Resources
- [Ansible network resources](https://docs.ansible.com/ansible/latest/network/getting_started/network_resources.html)
- [Ansible Collection overview](https://github.com/ansible-collections/overview)
- [Ansible User guide](https://docs.ansible.com/ansible/latest/user_guide/index.html)
- [Ansible Developer guide](https://docs.ansible.com/ansible/latest/dev_guide/index.html)
- [Ansible Community code of conduct](https://docs.ansible.com/ansible/latest/community/code_of_conduct.html)
## Licensing
GNU General Public License v3.0 or later.
See [LICENSE](https://www.gnu.org/licenses/gpl-3.0.txt) to see the full text.
diff --git a/changelogs/fragments/t6820_vrrp.yml b/changelogs/fragments/t6820_vrrp.yml
new file mode 100644
index 00000000..34343bbf
--- /dev/null
+++ b/changelogs/fragments/t6820_vrrp.yml
@@ -0,0 +1,3 @@
+---
+minor_changes:
+ - vyos_vrrp - Add VRRP (High Availability) support
diff --git a/plugins/action/vyos_vrrp.py b/plugins/action/vyos_vrrp.py
new file mode 120000
index 00000000..331a791f
--- /dev/null
+++ b/plugins/action/vyos_vrrp.py
@@ -0,0 +1 @@
+vyos.py
\ No newline at end of file
diff --git a/plugins/module_utils/network/vyos/argspec/vrrp/__init__.py b/plugins/module_utils/network/vyos/argspec/vrrp/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/plugins/module_utils/network/vyos/argspec/vrrp/vrrp.py b/plugins/module_utils/network/vyos/argspec/vrrp/vrrp.py
new file mode 100644
index 00000000..41cd47ac
--- /dev/null
+++ b/plugins/module_utils/network/vyos/argspec/vrrp/vrrp.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+# Copyright 2024 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+#############################################
+# WARNING #
+#############################################
+#
+# This file is auto generated by the
+# cli_rm_builder.
+#
+# Manually editing this file is not advised.
+#
+# To update the argspec make the desired changes
+# in the module docstring and re-run
+# cli_rm_builder.
+#
+#############################################
+
+"""
+The arg spec for the vyos_vrrp module
+"""
+
+
+class VrrpArgs(object): # pylint: disable=R0903
+ """The arg spec for the vyos_vrrp module"""
+
+ argument_spec = {
+ "config": {
+ "type": "dict",
+ "options": {
+ "disable": {"aliases": ["disabled"], "type": "bool", "default": False},
+ },
+ },
+ "state": {
+ "type": "str",
+ "choices": [
+ "deleted",
+ "merged",
+ "purged",
+ "replaced",
+ "gathered",
+ "rendered",
+ "parsed",
+ ],
+ "default": "merged",
+ },
+ "running_config": {"type": "str"},
+ } # pylint: disable=C0301
diff --git a/plugins/module_utils/network/vyos/config/vrrp/__init__.py b/plugins/module_utils/network/vyos/config/vrrp/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/plugins/module_utils/network/vyos/config/vrrp/vrrp.py b/plugins/module_utils/network/vyos/config/vrrp/vrrp.py
new file mode 100644
index 00000000..5f51e276
--- /dev/null
+++ b/plugins/module_utils/network/vyos/config/vrrp/vrrp.py
@@ -0,0 +1,404 @@
+#
+# -*- 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_vrrp config file.
+It is in this file where the current configuration (as dict)
+is compared to the provided configuration (as dict) and the command set
+necessary to bring the current configuration to its desired end-state is
+created.
+"""
+
+from ansible.module_utils.six import iteritems
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.resource_module import (
+ ResourceModule,
+)
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrrp import (
+ VrrpTemplate,
+)
+
+
+# from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.utils import (
+# dict_merge,
+# )
+
+
+class Vrrp(ResourceModule):
+ """
+ The vyos_vrrp config class
+ """
+
+ def __init__(self, module):
+ super(Vrrp, self).__init__(
+ empty_fact_val={},
+ facts_module=Facts(module),
+ module=module,
+ resource="vrrp",
+ tmplt=VrrpTemplate(),
+ )
+ self.parsers = []
+
+ def _validate_template(self):
+ self._tmplt = VrrpTemplate()
+
+ def parse(self):
+ """override parse to check template"""
+ self._validate_template()
+ return super().parse()
+
+ def get_parser(self, name):
+ """get_parsers"""
+ self._validate_template()
+ return super().get_parser(name)
+
+ def execute_module(self):
+ """Execute the module
+
+ :rtype: A dictionary
+ :returns: The result from module execution
+ """
+ self._validate_template()
+ if self.state not in ["parsed", "gathered"]:
+ self.generate_commands()
+ self.run_commands()
+ 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
+ # or LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4")
+ # ):
+ # 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._vrrp_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 vrrp network resource.
+ """
+ # if LooseVersion(get_os_version(self._module)) >= LooseVersion("1.4"):
+ # self._compare_asn(want, have)
+ #
+ parsers = ["maximum_paths", "timers"]
+ self._compare_neighbor(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",
+ ]
+
+ 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" + self._asn_mod + " 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" + self._asn_mod + " parameters")
+ hbgp = {}
+ for name, entry in iteritems(hbgp):
+ if name == "confederation":
+ self.commands.append(
+ "delete protocols bgp" + self._asn_mod + " 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_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 _vrrp_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 _compare_asn(self, want, have):
+ if want.get("as_number") and not have.get("as_number"):
+ self.commands.append(
+ "set protocols bgp " + "system-as" + " " + str(want.get("as_number")),
+ )
+
+ 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 neighbor in line:
+ 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/facts.py b/plugins/module_utils/network/vyos/facts/facts.py
index 74bbda74..8cd7cbce 100644
--- a/plugins/module_utils/network/vyos/facts/facts.py
+++ b/plugins/module_utils/network/vyos/facts/facts.py
@@ -1,131 +1,135 @@
# Copyright 2019 Red Hat
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
The facts class for vyos
this file validates each subset of facts and selectively
calls the appropriate facts gathering function
"""
from __future__ import absolute_import, division, print_function
__metaclass__ = type
from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts import (
FactsBase,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.bgp_address_family.bgp_address_family import (
Bgp_address_familyFacts,
)
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.firewall_global.firewall_global import (
Firewall_globalFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_interfaces.firewall_interfaces import (
Firewall_interfacesFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.firewall_rules.firewall_rules import (
Firewall_rulesFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.hostname.hostname import (
HostnameFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.interfaces.interfaces import (
InterfacesFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.l3_interfaces.l3_interfaces import (
L3_interfacesFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lag_interfaces.lag_interfaces import (
Lag_interfacesFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.legacy.base import (
Config,
Default,
Neighbors,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lldp_global.lldp_global import (
Lldp_globalFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.lldp_interfaces.lldp_interfaces import (
Lldp_interfacesFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.logging_global.logging_global import (
Logging_globalFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ntp_global.ntp_global import (
Ntp_globalFacts,
)
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.ospfv2.ospfv2 import (
Ospfv2Facts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.ospfv3.ospfv3 import (
Ospfv3Facts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.prefix_lists.prefix_lists import (
Prefix_listsFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.route_maps.route_maps import (
Route_mapsFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.snmp_server.snmp_server import (
Snmp_serverFacts,
)
from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.static_routes.static_routes import (
Static_routesFacts,
)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.vrrp.vrrp import (
+ VrrpFacts,
+)
FACT_LEGACY_SUBSETS = dict(default=Default, neighbors=Neighbors, config=Config)
FACT_RESOURCE_SUBSETS = dict(
interfaces=InterfacesFacts,
l3_interfaces=L3_interfacesFacts,
lag_interfaces=Lag_interfacesFacts,
lldp_global=Lldp_globalFacts,
lldp_interfaces=Lldp_interfacesFacts,
static_routes=Static_routesFacts,
firewall_rules=Firewall_rulesFacts,
firewall_global=Firewall_globalFacts,
firewall_interfaces=Firewall_interfacesFacts,
ospfv3=Ospfv3Facts,
ospfv2=Ospfv2Facts,
ospf_interfaces=Ospf_interfacesFacts,
bgp_global=Bgp_globalFacts,
bgp_address_family=Bgp_address_familyFacts,
route_maps=Route_mapsFacts,
prefix_lists=Prefix_listsFacts,
logging_global=Logging_globalFacts,
ntp_global=Ntp_globalFacts,
snmp_server=Snmp_serverFacts,
hostname=HostnameFacts,
+ vrrp=VrrpFacts,
)
class Facts(FactsBase):
"""The fact class for vyos"""
VALID_LEGACY_GATHER_SUBSETS = frozenset(FACT_LEGACY_SUBSETS.keys())
VALID_RESOURCE_SUBSETS = frozenset(FACT_RESOURCE_SUBSETS.keys())
def __init__(self, module):
super(Facts, self).__init__(module)
def get_facts(self, legacy_facts_type=None, resource_facts_type=None, data=None):
"""Collect the facts for vyos
:param legacy_facts_type: List of legacy facts types
:param resource_facts_type: List of resource fact types
:param data: previously collected conf
:rtype: dict
:return: the facts gathered
"""
if self.VALID_RESOURCE_SUBSETS:
self.get_network_resources_facts(FACT_RESOURCE_SUBSETS, resource_facts_type, data)
if self.VALID_LEGACY_GATHER_SUBSETS:
self.get_network_legacy_facts(FACT_LEGACY_SUBSETS, legacy_facts_type)
return self.ansible_facts, self._warnings
diff --git a/plugins/module_utils/network/vyos/facts/vrrp/__init__.py b/plugins/module_utils/network/vyos/facts/vrrp/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py b/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py
new file mode 100644
index 00000000..43a70b95
--- /dev/null
+++ b/plugins/module_utils/network/vyos/facts/vrrp/vrrp.py
@@ -0,0 +1,104 @@
+# -*- 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 vrrp fact class
+It is in this file the configuration is collected from the device
+for a given resource, parsed, and the facts tree is populated
+based on the configuration.
+"""
+
+import re
+
+from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vrrp.vrrp import (
+ VrrpArgs,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.vrrp import (
+ VrrpTemplate,
+)
+
+
+class VrrpFacts(object):
+ """The vyos vrrp facts class"""
+
+ def __init__(self, module, subspec="config", options="options"):
+ self._module = module
+ self.argument_spec = VrrpArgs.argument_spec
+
+ def get_device_data(self, connection):
+ return connection.get('show configuration commands | match "set high-availability"')
+
+ def get_config_set(self, data, connection):
+ """To classify the configurations beased on vrrp"""
+ config_dict = {}
+ for config_line in data.splitlines():
+ vrrp_grp = re.search(r"set high-availability vrrp group (\S+).*", config_line)
+ vrrp_vsrv = re.search(r"set high-availability virtual-server (\S+).*", config_line)
+ vrrp_disable = re.search(r"set high-availability disable", config_line)
+ if vrrp_disable:
+ config_dict["disable"] = config_dict.get("disable", "") + config_line + "\n"
+ if vrrp_grp:
+ config_dict[vrrp_grp.group(1)] = (
+ config_dict.get(vrrp_grp.group(1), "") + config_line + "\n"
+ )
+ return list(config_dict.values())
+
+ def populate_facts(self, connection, ansible_facts, data=None):
+ """Populate the facts for vrrp 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)
+
+ vrrp_facts = {}
+ resources = self.get_config_set(data, connection)
+
+ for resource in resources:
+ vrrp_parser = VrrpTemplate(
+ lines=resource.split("\n"),
+ module=self._module,
+ )
+ objs = vrrp_parser.parse()
+ self._module.fail_json(msg=str(resource.split("\n")) + str(objs))
+ if objs:
+ self._module.fail_json(msg=str(objs))
+
+ # for resource in data.splitlines():
+ # if "address-family" not in resource:
+ # config_lines.append(re.sub("'", "", resource))
+ #
+ # vrrp_parser = VrrpTemplate(lines=config_lines, module=self._module)
+ #
+ # objs = vrrp_parser.parse()
+ # self._module.fail_json(msg=objs)
+
+ ansible_facts["ansible_network_resources"].pop("vrrp", None)
+
+ params = utils.remove_empties(
+ vrrp_parser.validate_config(self.argument_spec, {"config": objs}, redact=True),
+ )
+
+ facts["vrrp"] = params.get("config", [])
+ ansible_facts["ansible_network_resources"].update(facts)
+ self._module.fail_json(msg=ansible_facts)
+
+ return ansible_facts
diff --git a/plugins/module_utils/network/vyos/rm_templates/vrrp.py b/plugins/module_utils/network/vyos/rm_templates/vrrp.py
new file mode 100644
index 00000000..c285416e
--- /dev/null
+++ b/plugins/module_utils/network/vyos/rm_templates/vrrp.py
@@ -0,0 +1,473 @@
+# -*- 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.rm_base.network_template import (
+ NetworkTemplate,
+)
+
+
+class VrrpTemplate(NetworkTemplate):
+ def __init__(self, lines=None, module=None):
+ prefix = {"set": "set", "remove": "delete"}
+ super(VrrpTemplate, self).__init__(
+ lines=lines,
+ tmplt=self,
+ prefix=prefix,
+ module=module,
+ )
+
+ # fmt: off
+ PARSERS = [
+ {
+ "name": "disable",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \s(?P<disable>disable)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability disable",
+ "result": {
+ "disable": "{{ True if disable is defined }}",
+ },
+ },
+ {
+ "name": "vg_global_garp_interval",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \s(?P<disable>disable)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability disable",
+ "result": {
+ "disable": "{{ True if disable is defined }}",
+ },
+ },
+ {
+ "name": "vg_addr",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \saddress
+ \s(?P<address>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} address {{address}}",
+ "compval": "address",
+ "result": {
+ "group": "{{ group }}",
+ "address": "{{ address }}",
+ },
+ },
+ {
+ "name": "vg_addr_addr_int",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \saddress
+ \s(?P<address>\S+)
+ \sinterface
+ \s(?P<interface>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} address {{address}} interface {{interface}}",
+ "compval": "interface",
+ "result": {
+ "group": "{{ group }}",
+ "address": "{{ address }}",
+ "interface": "{{ interface }}",
+ },
+ },
+ {
+ "name": "vg_excluded_addr",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sexcluded-address
+ \s(?P<excluded_addr>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} excluded-address {{excluded_addr}}",
+ "compval": "excluded_address",
+ "result": {
+ "group": "{{ group }}",
+ "excluded_address": "{{ excluded_addr }}",
+ },
+ },
+ {
+ "name": "vg_excluded_addr_int",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sexcluded-address
+ \s(?P<excluded_addr>\S+)
+ \sinterface
+ \s(?P<excluded_addr_int>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} excluded-address {{excluded_addr}} interface {{excluded_addr_interface}}",
+ "compval": "excluded_address_interface",
+ "result": {
+ "group": "{{ group }}",
+ "excluded_address_interface": "{{ excluded_address_int }}",
+ },
+ },
+ {
+ "name": "vg_priority",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \spriority
+ \s(?P<priority>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} priority {{priority}}",
+ "compval": "priority",
+ "result": {
+ "group": "{{ group }}",
+ "priority": "{{ priority }}",
+ },
+ },
+ {
+ "name": "vg_advertise_interval",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sadvertise-interval
+ \s(?P<adv_int>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} advertise-interval {{adv_int}}",
+ "compval": "advertise_interval",
+ "result": {
+ "group": "{{ group }}",
+ "advertise_interval": "{{ adv_int }}",
+ },
+ },
+ {
+ "name": "vg_description",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sdescription
+ \s(?P<adv_int>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} description {{description}}",
+ "compval": "description",
+ "result": {
+ "group": "{{ group }}",
+ "description": "{{ description }}",
+ },
+ },
+ {
+ "name": "vg_vrid",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \svrid
+ \s(?P<vrid>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} vrid {{vrid}}",
+ "compval": "vrid",
+ "result": {
+ "group": "{{ group }}",
+ "vrid": "{{ vrid }}",
+ },
+ },
+ {
+ "name": "vg_no_preempt",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \s(?P<np>no-preempt)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} no-preempt",
+ "compval": "no_preempt",
+ "result": {
+ "group": "{{ group }}",
+ "no_preempt": "{{ True if np is defined }}",
+ },
+ },
+ {
+ "name": "vg_preempt_delay",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \spreempt-delay
+ \s(?P<prd>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} preempt-delay {{prd}}",
+ "compval": "preempt_delay",
+ "result": {
+ "group": "{{ group }}",
+ "preempt-delay": "{{ prd }}",
+ },
+ },
+ {
+ "name": "vg_authentication_password",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sauthentication
+ \spassword
+ \s(?P<pass>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} authentication password {{pass}}",
+ "compval": "pass",
+ "result": {
+ "group": "{{ group }}",
+ "authentication": {
+ "password": "{{ pass }}",
+ },
+ },
+ },
+ {
+ "name": "vg_authentication_type",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sauthentication
+ \stype
+ \s(?P<type>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} authentication type {{type}}",
+ "compval": "type",
+ "result": {
+ "group": "{{ group }}",
+ "authentication": {
+ "password": "{{ type }}",
+ },
+ },
+ },
+ {
+ "name": "vg_rfc3768",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \srfc3768-compatibility
+ \s(?P<rfc3768>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} rfc3768-compatibility {{rfc3768}}",
+ "compval": "rfc3768_compatibility",
+ "result": {
+ "group": "{{ group }}",
+ "rfc3768_compatibility": "{{ True if rfc3768 is defined }}",
+ },
+ },
+ {
+ "name": "vg_garp_interval",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sgarp
+ \sinterval
+ \s(?P<garp_int>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} garp interval {{garp_int}}",
+ "compval": "interval",
+ "result": {
+ "group": "{{ group }}",
+ "garp": {
+ "interval": "{{ garp_int}}",
+ },
+ },
+ },
+ {
+ "name": "vg_garp_master_delay",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sgarp
+ \smaster-delay
+ \s(?P<garp_mdelay>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} garp master-delay {{garp_mdelay}}",
+ "compval": "master_delay",
+ "result": {
+ "group": "{{ group }}",
+ "garp": {
+ "master_delay": "{{ garp_mdelay }}",
+ },
+ },
+ },
+ {
+ "name": "vg_garp_master_refresh",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sgarp
+ \smaster-refresh
+ \s(?P<garp_mrefresh>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} garp master-refresh {{garp_mrefresh}}",
+ "compval": "master_refresh",
+ "result": {
+ "group": "{{ group }}",
+ "garp": {
+ "master_refresh": "{{ garp_mrefresh }}",
+ },
+ },
+ },
+ {
+ "name": "vg_garp_master_refresh_repeat",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sgarp
+ \smaster-refresh-repeat
+ \s(?P<garp_mrefresh_repeat>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} garp master-refresh-repeat {{garp_mrefresh_repeat}}",
+ "compval": "master_refresh_repeat",
+ "result": {
+ "group": "{{ group }}",
+ "garp": {
+ "master_refresh_repeat": "{{ garp_mrefresh_repeat }}",
+ },
+ },
+ },
+ {
+ "name": "vg_garp_master_repeat",
+ "getval": re.compile(
+ r"""
+ ^set
+ \shigh-availability
+ \svrrp
+ \sgroup
+ \s(?P<group>\S+)
+ \sgarp
+ \smaster-repeat
+ \s(?P<garp_mrepeat>\S+)
+ $""",
+ re.VERBOSE,
+ ),
+ "setval": "high-availability vrrp group {{group}} garp master-repeat {{garp_mrepeat}}",
+ "compval": "master_repeat",
+ "result": {
+ "group": "{{ group }}",
+ "garp": {
+ "master_repeat": "{{ garp_mrepeat }}",
+ },
+ },
+ },
+
+ ]
+ # fmt: on
diff --git a/plugins/modules/vyos_vrrp.py b/plugins/modules/vyos_vrrp.py
new file mode 100644
index 00000000..e56b84f7
--- /dev/null
+++ b/plugins/modules/vyos_vrrp.py
@@ -0,0 +1,1128 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# Copyright 2024 Red Hat
+# GNU General Public License v3.0+
+# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+The module file for vyos_vrrp
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: vyos_vrrp
+version_added: 1.0.0
+short_description: High Availability (VRRP) resource module
+description:
+- This module manages VRRP configuration of interfaces on devices running VYOS.
+- The provided examples of commands are valid for VyOS 1.4+
+author:
+- Evgeny Molotkov (@omnom62)
+options:
+ config:
+ description: A dict of VRRP configuration.
+ type: dict
+ suboptions:
+ disable:
+ default: false
+ description: Disable instance
+ type: bool
+ 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_vrrp:
+ 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 system-as 65536
+# set protocols bgp aggregate-address 192.0.2.0/24 'summary-only'
+# set protocols bgp aggregate-address 203.0.113.0/24 'as-set'
+# set protocols bgp maximum-paths ebgp '20'
+# set protocols bgp maximum-paths ibgp '55'
+# set protocols bgp neighbor 192.0.2.25 'disable-connected-check'
+# set protocols bgp neighbor 192.0.2.25 timers holdtime '30'
+# set protocols bgp neighbor 192.0.2.25 timers keepalive '10'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'as-path'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'med'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+# set protocols bgp neighbor 203.0.113.5 ebgp-multihop '2'
+# set protocols bgp neighbor 203.0.113.5 remote-as '101'
+# set protocols bgp neighbor 203.0.113.5 update-source '192.0.2.25'
+# set protocols bgp neighbor 5001::64 distribute-list export '20'
+# set protocols bgp neighbor 5001::64 distribute-list import '40'
+# set protocols bgp neighbor 5001::64 maximum-prefix '34'
+# set protocols bgp network 192.1.13.0/24 'backdoor'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp parameters bestpath 'compare-routerid'
+# set protocols bgp parameters confederation identifier '66'
+# set protocols bgp parameters confederation peers '20'
+# set protocols bgp parameters confederation peers '55'
+# set protocols bgp parameters default 'no-ipv4-unicast'
+# set protocols bgp parameters router-id '192.1.2.9'
+# set protocols bgp redistribute connected route-map 'map01'
+# set protocols bgp redistribute kernel metric '45'
+# set protocols bgp 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 neighbor 192.0.2.25 disable-connected-check",
+# "set protocols bgp neighbor 192.0.2.25 timers holdtime 30",
+# "set protocols bgp neighbor 192.0.2.25 timers keepalive 10",
+# "set protocols bgp neighbor 203.0.113.5 attribute-unchanged as-path",
+# "set protocols bgp neighbor 203.0.113.5 attribute-unchanged med",
+# "set protocols bgp neighbor 203.0.113.5 attribute-unchanged next-hop",
+# "set protocols bgp neighbor 203.0.113.5 ebgp-multihop 2",
+# "set protocols bgp neighbor 203.0.113.5 remote-as 101",
+# "set protocols bgp neighbor 203.0.113.5 update-source 192.0.2.25",
+# "set protocols bgp neighbor 5001::64 maximum-prefix 34",
+# "set protocols bgp neighbor 5001::64 distribute-list export 20",
+# "set protocols bgp neighbor 5001::64 distribute-list import 40",
+# "set protocols bgp redistribute kernel metric 45",
+# "set protocols bgp redistribute connected route-map map01",
+# "set protocols bgp network 192.1.13.0/24 backdoor",
+# "set protocols bgp aggregate-address 203.0.113.0/24 as-set",
+# "set protocols bgp aggregate-address 192.0.2.0/24 summary-only",
+# "set protocols bgp parameters bestpath as-path confed",
+# "set protocols bgp parameters bestpath compare-routerid",
+# "set protocols bgp parameters default no-ipv4-unicast",
+# "set protocols bgp parameters router-id 192.1.2.9",
+# "set protocols bgp parameters confederation peers 20",
+# "set protocols bgp parameters confederation peers 55",
+# "set protocols bgp parameters confederation identifier 66",
+# "set protocols bgp maximum-paths ebgp 20",
+# "set protocols bgp maximum-paths ibgp 55",
+# "set protocols bgp timers keepalive 35"
+# ],
+
+# Using replaced:
+# --------------
+
+# Before state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp system-as 65536
+# set protocols bgp aggregate-address 192.0.2.0/24 'summary-only'
+# set protocols bgp aggregate-address 203.0.113.0/24 'as-set'
+# set protocols bgp maximum-paths ebgp '20'
+# set protocols bgp maximum-paths ibgp '55'
+# set protocols bgp neighbor 192.0.2.25 'disable-connected-check'
+# set protocols bgp neighbor 192.0.2.25 timers holdtime '30'
+# set protocols bgp neighbor 192.0.2.25 timers keepalive '10'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'as-path'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'med'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+# set protocols bgp neighbor 203.0.113.5 ebgp-multihop '2'
+# set protocols bgp neighbor 203.0.113.5 remote-as '101'
+# set protocols bgp neighbor 203.0.113.5 update-source '192.0.2.25'
+# set protocols bgp neighbor 5001::64 distribute-list export '20'
+# set protocols bgp neighbor 5001::64 distribute-list import '40'
+# set protocols bgp neighbor 5001::64 maximum-prefix '34'
+# set protocols bgp network 192.1.13.0/24 'backdoor'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp parameters bestpath 'compare-routerid'
+# set protocols bgp parameters confederation identifier '66'
+# set protocols bgp parameters confederation peers '20'
+# set protocols bgp parameters confederation peers '55'
+# set protocols bgp parameters default 'no-ipv4-unicast'
+# set protocols bgp parameters router-id '192.1.2.9'
+# set protocols bgp redistribute connected route-map 'map01'
+# set protocols bgp redistribute kernel metric '45'
+# set protocols bgp timers keepalive '35'
+# vyos@vyos:~$
+
+- name: Replace
+ vyos.vyos.vyos_vrrp:
+ 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 system-as 65536
+# set protocols bgp neighbor 192.0.2.40 advertisement-interval '72'
+# set protocols bgp neighbor 192.0.2.40 capability orf prefix-list 'receive'
+# set protocols bgp network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp 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 timers",
+# "delete protocols bgp maximum-paths ",
+# "delete protocols bgp maximum-paths ",
+# "delete protocols bgp parameters router-id 192.1.2.9",
+# "delete protocols bgp parameters default",
+# "delete protocols bgp parameters confederation",
+# "delete protocols bgp parameters bestpath compare-routerid",
+# "delete protocols bgp aggregate-address",
+# "delete protocols bgp network 192.1.13.0/24",
+# "delete protocols bgp redistribute kernel",
+# "delete protocols bgp redistribute kernel",
+# "delete protocols bgp redistribute connected",
+# "delete protocols bgp redistribute connected",
+# "delete protocols bgp neighbor 5001::64",
+# "delete protocols bgp neighbor 203.0.113.5",
+# "delete protocols bgp neighbor 192.0.2.25",
+# "set protocols bgp neighbor 192.0.2.40 advertisement-interval 72",
+# "set protocols bgp neighbor 192.0.2.40 capability orf prefix-list receive",
+# "set protocols bgp redistribute static route-map map01",
+# "set protocols bgp 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 system-as 65536
+# set protocols bgp neighbor 192.0.2.40 advertisement-interval '72'
+# set protocols bgp neighbor 192.0.2.40 capability orf prefix-list 'receive'
+# set protocols bgp network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp redistribute static route-map 'map01'
+# vyos@vyos:~$
+
+- name: Delete configuration
+ vyos.vyos.vyos_vrrp:
+ 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 neighbor 192.0.2.40",
+# "delete protocols bgp redistribute",
+# "delete protocols bgp network",
+# "delete protocols bgp parameters"
+# ],
+
+# Using purged:
+
+# Before state:
+
+# vyos@vyos:~$ show configuration commands | match "set protocols bgp"
+# set protocols bgp system-as 65536
+# set protocols bgp aggregate-address 192.0.2.0/24 'summary-only'
+# set protocols bgp aggregate-address 203.0.113.0/24 'as-set'
+# set protocols bgp maximum-paths ebgp '20'
+# set protocols bgp maximum-paths ibgp '55'
+# set protocols bgp neighbor 192.0.2.25 'disable-connected-check'
+# set protocols bgp neighbor 192.0.2.25 timers holdtime '30'
+# set protocols bgp neighbor 192.0.2.25 timers keepalive '10'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'as-path'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'med'
+# set protocols bgp neighbor 203.0.113.5 attribute-unchanged 'next-hop'
+# set protocols bgp neighbor 203.0.113.5 ebgp-multihop '2'
+# set protocols bgp neighbor 203.0.113.5 remote-as '101'
+# set protocols bgp neighbor 203.0.113.5 update-source '192.0.2.25'
+# set protocols bgp neighbor 5001::64 distribute-list export '20'
+# set protocols bgp neighbor 5001::64 distribute-list import '40'
+# set protocols bgp neighbor 5001::64 maximum-prefix '34'
+# set protocols bgp network 192.1.13.0/24 'backdoor'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp parameters bestpath 'compare-routerid'
+# set protocols bgp parameters confederation identifier '66'
+# set protocols bgp parameters confederation peers '20'
+# set protocols bgp parameters confederation peers '55'
+# set protocols bgp parameters default 'no-ipv4-unicast'
+# set protocols bgp parameters router-id '192.1.2.9'
+# set protocols bgp redistribute connected route-map 'map01'
+# set protocols bgp redistribute kernel metric '45'
+# set protocols bgp timers keepalive '35'
+# vyos@vyos:~$
+
+
+- name: Purge configuration
+ vyos.vyos.vyos_vrrp:
+ 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 system-as 65536
+# set protocols bgp neighbor 192.0.2.43 advertisement-interval '72'
+# set protocols bgp neighbor 192.0.2.43 capability 'dynamic'
+# set protocols bgp neighbor 192.0.2.43 'disable-connected-check'
+# set protocols bgp neighbor 192.0.2.43 timers holdtime '30'
+# set protocols bgp neighbor 192.0.2.43 timers keepalive '10'
+# set protocols bgp neighbor 203.0.113.0 address-family 'ipv6-unicast'
+# set protocols bgp neighbor 203.0.113.0 capability orf prefix-list 'receive'
+# set protocols bgp network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp parameters 'always-compare-med'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp parameters bestpath 'compare-routerid'
+# set protocols bgp parameters dampening half-life '33'
+# set protocols bgp parameters dampening max-suppress-time '20'
+# set protocols bgp parameters dampening re-use '60'
+# set protocols bgp parameters dampening start-suppress-time '5'
+# set protocols bgp parameters default 'no-ipv4-unicast'
+# set protocols bgp parameters distance global external '66'
+# set protocols bgp parameters distance global internal '20'
+# set protocols bgp parameters distance global local '10'
+# set protocols bgp redistribute static route-map 'map01'
+# vyos@vyos:~$ ^C
+# vyos@vyos:~$
+
+- name: Delete configuration
+ vyos.vyos.vyos_vrrp:
+ 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 system-as 65536
+# set protocols bgp neighbor 192.0.2.43 advertisement-interval '72'
+# set protocols bgp neighbor 192.0.2.43 capability 'dynamic'
+# set protocols bgp neighbor 192.0.2.43 'disable-connected-check'
+# set protocols bgp neighbor 192.0.2.43 timers holdtime '30'
+# set protocols bgp neighbor 192.0.2.43 timers keepalive '10'
+# set protocols bgp neighbor 203.0.113.0 address-family 'ipv6-unicast'
+# set protocols bgp neighbor 203.0.113.0 capability orf prefix-list 'receive'
+# set protocols bgp network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp parameters 'always-compare-med'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp parameters bestpath 'compare-routerid'
+# set protocols bgp parameters dampening half-life '33'
+# set protocols bgp parameters dampening max-suppress-time '20'
+# set protocols bgp parameters dampening re-use '60'
+# set protocols bgp parameters dampening start-suppress-time '5'
+# set protocols bgp parameters default 'no-ipv4-unicast'
+# set protocols bgp parameters distance global external '66'
+# set protocols bgp parameters distance global internal '20'
+# set protocols bgp parameters distance global local '10'
+# set protocols bgp redistribute static route-map 'map01'
+# vyos@vyos:~$ ^C
+
+- name: gather configs
+ vyos.vyos.vyos_vrrp:
+ 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 neighbor 192.0.2.43 advertisement-interval '72'
+# set protocols bgp neighbor 192.0.2.43 capability 'dynamic'
+# set protocols bgp neighbor 192.0.2.43 'disable-connected-check'
+# set protocols bgp neighbor 192.0.2.43 timers holdtime '30'
+# set protocols bgp neighbor 192.0.2.43 timers keepalive '10'
+# set protocols bgp neighbor 203.0.113.0 address-family 'ipv6-unicast'
+# set protocols bgp neighbor 203.0.113.0 capability orf prefix-list 'receive'
+# set protocols bgp network 203.0.113.0/24 route-map 'map01'
+# set protocols bgp parameters 'always-compare-med'
+# set protocols bgp parameters bestpath as-path 'confed'
+# set protocols bgp parameters bestpath 'compare-routerid'
+# set protocols bgp parameters dampening half-life '33'
+# set protocols bgp parameters dampening max-suppress-time '20'
+# set protocols bgp parameters dampening re-use '60'
+# set protocols bgp parameters dampening start-suppress-time '5'
+# set protocols bgp parameters default 'no-ipv4-unicast'
+# set protocols bgp parameters distance global external '66'
+# set protocols bgp parameters distance global internal '20'
+# set protocols bgp parameters distance global local '10'
+# set protocols bgp redistribute static route-map 'map01'
+
+- name: parse configs
+ vyos.vyos.vyos_vrrp:
+ 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_vrrp:
+ 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 neighbor 192.0.2.43 disable-connected-check",
+# "set protocols bgp neighbor 192.0.2.43 advertisement-interval 72",
+# "set protocols bgp neighbor 192.0.2.43 capability dynamic",
+# "set protocols bgp neighbor 192.0.2.43 timers holdtime 30",
+# "set protocols bgp neighbor 192.0.2.43 timers keepalive 10",
+# "set protocols bgp neighbor 203.0.113.0 capability orf prefix-list receive",
+# "set protocols bgp redistribute static route-map map01",
+# "set protocols bgp network 203.0.113.0/24 route-map map01",
+# "set protocols bgp parameters always-compare-med",
+# "set protocols bgp parameters dampening half-life 33",
+# "set protocols bgp parameters dampening max-suppress-time 20",
+# "set protocols bgp parameters dampening re-use 60",
+# "set protocols bgp parameters dampening start-suppress-time 5",
+# "set protocols bgp parameters distance global internal 20",
+# "set protocols bgp parameters distance global local 10",
+# "set protocols bgp parameters distance global external 66",
+# "set protocols bgp parameters bestpath as-path confed",
+# "set protocols bgp parameters bestpath compare-routerid",
+# "set protocols bgp parameters default no-ipv4-unicast"
+# ]
+"""
+
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+after:
+ description: The resulting configuration after module execution.
+ returned: when changed
+ type: dict
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+commands:
+ description: The set of commands pushed to the remote device.
+ returned: when I(state) is C(merged), C(replaced), C(overridden), C(deleted) or C(purged)
+ type: list
+ sample:
+ - set protocols bgp redistribute static route-map map01
+ - set protocols bgp network 203.0.113.0/24 route-map map01
+ - set protocols bgp parameters always-compare-med
+rendered:
+ description: The provided configuration in the task rendered in device-native format (offline).
+ returned: when I(state) is C(rendered)
+ type: list
+ sample:
+ - set protocols bgp redistribute static route-map map01
+ - set protocols bgp network 203.0.113.0/24 route-map map01
+ - set protocols bgp parameters always-compare-med
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+parsed:
+ description: The device native config provided in I(running_config) option parsed into structured data as per module argspec.
+ returned: when I(state) is C(parsed)
+ type: list
+ sample: >
+ This output will always be in the same format as the
+ module argspec.
+"""
+
+from ansible.module_utils.basic import AnsibleModule
+
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.argspec.vrrp.vrrp import (
+ VrrpArgs,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.vrrp.vrrp import (
+ Vrrp,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=VrrpArgs.argument_spec,
+ mutually_exclusive=[["config", "running_config"]],
+ required_if=[
+ ["state", "merged", ["config"]],
+ ["state", "replaced", ["config"]],
+ ["state", "overridden", ["config"]],
+ ["state", "rendered", ["config"]],
+ ["state", "parsed", ["running_config"]],
+ ],
+ supports_check_mode=True,
+ )
+
+ result = Vrrp(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()

File Metadata

Mime Type
text/x-diff
Expires
Sat, Oct 17, 12:58 AM (1 d, 1 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4416771
Default Alt Text
(95 KB)

Event Timeline