summaryrefslogtreecommitdiff
path: root/plugins/modules
diff options
context:
space:
mode:
authoromnom62 <75066712+omnom62@users.noreply.github.com>2026-09-01 22:37:23 +1000
committerGitHub <noreply@github.com>2026-09-01 15:37:23 +0300
commit497022e13c372ed68afe49aeafca66285e2f8001 (patch)
treebb01d4dbe45e34a465244e2f89778012ee65a6cf /plugins/modules
parent61d27bc11d3f64ad4ad66ec42ff5ae83ccd30732 (diff)
downloadvyos.vyos-497022e13c372ed68afe49aeafca66285e2f8001.tar.gz
vyos.vyos-497022e13c372ed68afe49aeafca66285e2f8001.zip
T8323: vyos_nat module (#451)
Add NAT module
Diffstat (limited to 'plugins/modules')
-rw-r--r--plugins/modules/vyos_nat.py934
-rw-r--r--plugins/modules/vyos_vrf.py4
2 files changed, 935 insertions, 3 deletions
diff --git a/plugins/modules/vyos_nat.py b/plugins/modules/vyos_nat.py
new file mode 100644
index 00000000..7715cb76
--- /dev/null
+++ b/plugins/modules/vyos_nat.py
@@ -0,0 +1,934 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
+
+"""
+The module file for vyos_nat
+"""
+
+from __future__ import absolute_import, division, print_function
+
+
+__metaclass__ = type
+
+DOCUMENTATION = """
+module: vyos_nat
+version_added: 6.0.0
+short_description: NAT resource module
+description:
+- This module manages NAT configuration on devices running VyOS.
+author:
+- Evgeny Molotkov (@omnom62)
+notes:
+- Tested against VyOS 1.4.3 and 1.5.0.
+- This module works with connection C(network_cli).
+options:
+ config:
+ description:
+ - The desired configuration for the NAT resource represented as a dictionary.
+ type: dict
+ suboptions:
+ nat:
+ type: dict
+ description: Configuration for NAT rules.
+ suboptions:
+ cgnat:
+ type: dict
+ description: Configuration for Carrier Grade NAT (CGNAT).
+ suboptions:
+ log_allocation:
+ type: bool
+ description: Log CGNAT address allocations.
+ pool:
+ type: dict
+ description: Configuration for CGNAT pools.
+ suboptions:
+ external:
+ type: list
+ elements: dict
+ description: List of external NAT pools for CGNAT.
+ suboptions:
+ name:
+ type: str
+ required: true
+ description: Name of the external NAT pool.
+ external_port_range:
+ type: str
+ description: Port range to use for NAT translations in this external pool.
+ per_user_limit:
+ type: dict
+ description: Per-user limit configuration for the external pool.
+ suboptions:
+ port:
+ type: str
+ description: Maximum number of ports allocated per user.
+ range:
+ type: list
+ elements: dict
+ description: List of external IP address ranges in the pool.
+ suboptions:
+ value:
+ type: str
+ required: true
+ description: IP address, prefix, or range (e.g. 203.0.113.0/24 or 203.0.113.1-203.0.113.60).
+ seq:
+ type: str
+ description: Optional sequence number for this range entry.
+ internal:
+ type: list
+ elements: dict
+ description: List of internal NAT pools for CGNAT.
+ suboptions:
+ name:
+ type: str
+ required: true
+ description: Name of the internal NAT pool.
+ range:
+ type: list
+ elements: str
+ description: List of internal IP addresses or prefixes in the pool.
+ rule:
+ type: list
+ elements: dict
+ description: List of CGNAT rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for CGNAT.
+ source:
+ type: dict
+ description: Source pool configuration for CGNAT translation.
+ suboptions:
+ pool:
+ type: str
+ description: Source pool name to use for CGNAT translation.
+ translation:
+ type: dict
+ description: Translation pool configuration for CGNAT.
+ suboptions:
+ pool:
+ type: str
+ description: Translation pool name to use for CGNAT translation.
+ destination:
+ type: dict
+ description: Configuration for destination NAT rules.
+ suboptions:
+ rule:
+ type: list
+ elements: dict
+ description: List of destination NAT rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for destination NAT.
+ description:
+ type: str
+ description: User-friendly description of the destination NAT rule.
+ protocol:
+ type: str
+ description: Protocol to NAT (default all).
+ packet_type:
+ type: str
+ description: Packet type to match.
+ exclude:
+ type: bool
+ description: Exclude packets matching this rule from NAT.
+ log:
+ type: bool
+ description: Log packets hitting this rule.
+ disable:
+ type: bool
+ description: Disable this destination NAT rule.
+ inbound_interface:
+ type: dict
+ description: Match inbound interface.
+ suboptions:
+ name:
+ type: str
+ description: Interface name to match.
+ group:
+ type: str
+ description: Interface group to match.
+ destination:
+ type: dict
+ description: Match criteria for destination NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address, subnet, or range to match.
+ fqdn:
+ type: str
+ description: Fully qualified domain name to match.
+ port:
+ type: str
+ description: Port number or range to match.
+ address_group:
+ type: str
+ description: Address group name to match.
+ domain_group:
+ type: str
+ description: Domain group name to match.
+ mac_group:
+ type: str
+ description: MAC address group name to match.
+ network_group:
+ type: str
+ description: Network group name to match.
+ port_group:
+ type: str
+ description: Port group name to match.
+ translation:
+ type: dict
+ description: Translation configuration for destination NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address or prefix to translate destination to.
+ port:
+ type: str
+ description: Port number or range to translate destination port to.
+ redirect_port:
+ type: str
+ description: Redirect to local port number.
+ address_mapping:
+ type: str
+ choices:
+ - random
+ - persistent
+ description: Address mapping mode for translation.
+ port_mapping:
+ type: str
+ choices:
+ - random
+ - none
+ description: Port mapping mode for translation.
+ load_balance:
+ type: dict
+ description: Load balancing configuration for this NAT rule.
+ suboptions:
+ hash:
+ type: list
+ elements: str
+ description: Fields to hash on for load balancing. Mutually exclusive with I(translation.address).
+ choices:
+ - source-address
+ - destination-address
+ - source-port
+ - destination-port
+ - random
+ backend:
+ type: list
+ elements: dict
+ description: List of backends to load-balance across. Weights should sum to 100.
+ suboptions:
+ ip:
+ type: str
+ description: IP address of the backend translation target.
+ weight:
+ type: int
+ description: Relative weight (1-100) for this backend's share of load-balanced traffic.
+ source:
+ type: dict
+ description: Configuration for source NAT rules.
+ suboptions:
+ rule:
+ type: list
+ elements: dict
+ description: List of source NAT rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for source NAT.
+ description:
+ type: str
+ description: User-friendly description of the source NAT rule.
+ protocol:
+ type: str
+ description: Protocol to NAT (default all).
+ packet_type:
+ type: str
+ description: Packet type to match.
+ exclude:
+ type: bool
+ description: Exclude packets matching this rule from NAT.
+ log:
+ type: bool
+ description: Log packets hitting this rule.
+ disable:
+ type: bool
+ description: Disable this source NAT rule.
+ outbound_interface:
+ type: dict
+ description: Match outbound interface.
+ suboptions:
+ name:
+ type: str
+ description: Interface name to match.
+ group:
+ type: str
+ description: Interface group to match.
+ destination:
+ type: dict
+ description: Destination match criteria for source NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address, subnet, or range to match.
+ fqdn:
+ type: str
+ description: Fully qualified domain name to match.
+ port:
+ type: str
+ description: Port number or range to match.
+ address_group:
+ type: str
+ description: Address group name to match.
+ domain_group:
+ type: str
+ description: Domain group name to match.
+ mac_group:
+ type: str
+ description: MAC address group name to match.
+ network_group:
+ type: str
+ description: Network group name to match.
+ port_group:
+ type: str
+ description: Port group name to match.
+ source:
+ type: dict
+ description: Source match criteria for source NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address, subnet, or range to match.
+ fqdn:
+ type: str
+ description: Fully qualified domain name to match.
+ port:
+ type: str
+ description: Port number or range to match.
+ address_group:
+ type: str
+ description: Address group name to match.
+ domain_group:
+ type: str
+ description: Domain group name to match.
+ mac_group:
+ type: str
+ description: MAC address group name to match.
+ network_group:
+ type: str
+ description: Network group name to match.
+ port_group:
+ type: str
+ description: Port group name to match.
+ translation:
+ type: dict
+ description: Translation configuration for source NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address or prefix to translate source to. Use masquerade to masquerade as the outbound interface address.
+ port:
+ type: str
+ description: Port number or range to translate source port to.
+ address_mapping:
+ type: str
+ choices:
+ - random
+ - persistent
+ description: Address mapping mode for translation.
+ port_mapping:
+ type: str
+ choices:
+ - random
+ - none
+ description: Port mapping mode for translation.
+ load_balance:
+ type: dict
+ description: Load balancing configuration for this NAT rule.
+ suboptions:
+ hash:
+ type: list
+ elements: str
+ description: Fields to hash on for load balancing. Mutually exclusive with I(translation.address).
+ choices:
+ - source-address
+ - destination-address
+ - source-port
+ - destination-port
+ - random
+ backend:
+ type: list
+ elements: dict
+ description: List of backends to load-balance across. Weights should sum to 100.
+ suboptions:
+ ip:
+ type: str
+ description: IP address of the backend translation target.
+ weight:
+ type: int
+ description: Relative weight (1-100) for this backend's share of load-balanced traffic.
+ static:
+ type: dict
+ description: Configuration for static one-to-one NAT rules.
+ suboptions:
+ rule:
+ type: list
+ elements: dict
+ description: List of static NAT rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for static NAT.
+ description:
+ type: str
+ description: User-friendly description of the static NAT rule.
+ destination:
+ type: dict
+ description: Match criteria for static NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address, subnet, or range to match.
+ inbound_interface:
+ type: str
+ description: Inbound interface that this static NAT rule applies to.
+ log:
+ type: bool
+ description: Log packets hitting this static NAT rule.
+ translation:
+ type: dict
+ description: Translation configuration for static NAT.
+ suboptions:
+ address:
+ type: str
+ description: IP address or prefix to translate to.
+ nat64:
+ type: dict
+ description: Configuration for NAT64 (IPv6-to-IPv4) rules.
+ suboptions:
+ source:
+ type: dict
+ description: Configuration for NAT64 source rules.
+ suboptions:
+ rule:
+ type: list
+ elements: dict
+ description: List of NAT64 source rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for NAT64 source rule (1-999999).
+ description:
+ type: str
+ description: User-friendly description of the NAT64 source rule.
+ disable:
+ type: bool
+ description: Disable this NAT64 source rule.
+ match:
+ type: dict
+ description: Match criteria for NAT64 source rule.
+ suboptions:
+ mark:
+ type: int
+ description: Match on firewall mark value (1-2147483647).
+ source:
+ type: dict
+ description: IPv6 source prefix to match for NAT64 translation.
+ suboptions:
+ prefix:
+ type: str
+ description: IPv6 source prefix to match (h:h:h:h:h:h:h:h/x).
+ translation:
+ type: dict
+ description: Translation configuration for NAT64 source rule.
+ suboptions:
+ pool:
+ type: list
+ elements: dict
+ description: List of translation pools for NAT64.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Pool number (1-999999).
+ address:
+ type: str
+ description: IPv4 address or prefix for translation pool.
+ description:
+ type: str
+ description: User-friendly description of the translation pool.
+ disable:
+ type: bool
+ description: Disable this translation pool.
+ port:
+ type: str
+ description: Port number or range for translation pool.
+ protocol:
+ type: str
+ choices:
+ - icmp
+ - tcp
+ - udp
+ description: Protocol for this translation pool entry.
+ nat66:
+ type: dict
+ description: Configuration for NAT66 (IPv6-to-IPv6) rules.
+ suboptions:
+ destination:
+ type: dict
+ description: Configuration for NAT66 destination rules.
+ suboptions:
+ rule:
+ type: list
+ elements: dict
+ description: List of NAT66 destination rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for NAT66 destination rule.
+ description:
+ type: str
+ description: User-friendly description of the NAT66 destination rule.
+ destination:
+ type: dict
+ description: Match criteria for NAT66 destination rule.
+ suboptions:
+ address:
+ type: str
+ description: IPv6 address or prefix to match.
+ port:
+ type: str
+ description: Port number or range to match.
+ disable:
+ type: bool
+ description: Disable this NAT66 destination rule.
+ exclude:
+ type: bool
+ description: Exclude packets matching this rule from NAT66.
+ inbound_interface:
+ type: dict
+ description: Inbound interface to match for NAT66 destination rule.
+ suboptions:
+ name:
+ type: str
+ description: Interface name to match.
+ log:
+ type: bool
+ description: Log packets hitting this NAT66 destination rule.
+ protocol:
+ type: str
+ description: Protocol to match.
+ source:
+ type: dict
+ description: Source match criteria for NAT66 destination rule.
+ suboptions:
+ address:
+ type: str
+ description: IPv6 source address or prefix to match.
+ port:
+ type: str
+ description: Source port number or range to match.
+ translation:
+ type: dict
+ description: Translation configuration for NAT66 destination rule.
+ suboptions:
+ address:
+ type: str
+ description: IPv6 address or prefix to translate destination to.
+ port:
+ type: str
+ description: Port number or range to translate destination port to.
+ source:
+ type: dict
+ description: Configuration for NAT66 source rules.
+ suboptions:
+ rule:
+ type: list
+ elements: dict
+ description: List of NAT66 source rules.
+ suboptions:
+ id:
+ type: int
+ required: true
+ description: Rule number for NAT66 source rule.
+ description:
+ type: str
+ description: User-friendly description of the NAT66 source rule.
+ destination:
+ type: dict
+ description: Destination match criteria for NAT66 source rule.
+ suboptions:
+ port:
+ type: str
+ description: Destination port number or range to match.
+ prefix:
+ type: str
+ description: IPv6 destination prefix to match (h:h:h:h:h:h:h:h/x).
+ disable:
+ type: bool
+ description: Disable this NAT66 source rule.
+ exclude:
+ type: bool
+ description: Exclude packets matching this rule from NAT66.
+ log:
+ type: bool
+ description: Log packets hitting this NAT66 source rule.
+ outbound_interface:
+ type: dict
+ description: Outbound interface to match for NAT66 source rule.
+ suboptions:
+ name:
+ type: str
+ description: Interface name to match.
+ protocol:
+ type: str
+ description: Protocol to match.
+ source:
+ type: dict
+ description: Source match criteria for NAT66 source rule.
+ suboptions:
+ port:
+ type: str
+ description: Source port number or range to match.
+ prefix:
+ type: str
+ description: IPv6 source prefix to match (h:h:h:h:h:h:h:h/x).
+ translation:
+ type: dict
+ description: Translation configuration for NAT66 source rule.
+ suboptions:
+ address:
+ type: str
+ description: IPv6 address or prefix to translate source to. Use masquerade to masquerade as the outbound interface address.
+ port:
+ type: str
+ description: Port number or range to translate source port to.
+ running_config:
+ description:
+ - This option is used only with state I(parsed).
+ - The value of this option should be the output received from the VyOS device by
+ executing the command B(show configuration commands | match 'nat').
+ - The state I(parsed) reads the configuration from C(show configuration commands | match 'nat')
+ and transforms it into Ansible structured data as per the module argspec.
+ The value is then returned in the I(parsed) key within the result.
+ - The state I(replaced) replaces only the provided configuration, while I(overridden) removes any
+ existing NAT configuration not specified in I(config).
+ type: str
+ state:
+ description:
+ - The state the configuration should be left in.
+ type: str
+ choices:
+ - deleted
+ - merged
+ - overridden
+ - replaced
+ - gathered
+ - rendered
+ - parsed
+ default: merged
+"""
+EXAMPLES = """
+# Using merged - configure CGNAT
+- name: Merge CGNAT configuration
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ cgnat:
+ log_allocation: true
+ pool:
+ external:
+ - name: ext-pool-1
+ external_port_range: "10000-20000"
+ per_user_limit:
+ port: "200"
+ range:
+ - value: 203.0.113.0/24
+ internal:
+ - name: int-pool-1
+ range:
+ - 10.0.0.0/24
+ rule:
+ - id: 1
+ source:
+ pool: int-pool-1
+ translation:
+ pool: ext-pool-1
+ state: merged
+
+# Using merged - configure destination NAT
+- name: Merge destination NAT rule
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ destination:
+ rule:
+ - id: 100
+ description: "Web server NAT"
+ protocol: tcp
+ log: true
+ destination:
+ address: 198.51.100.10
+ port: "80"
+ translation:
+ address: 192.168.1.10
+ port: "8080"
+ state: merged
+
+# Using merged - configure source NAT
+- name: Merge source NAT rule
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ source:
+ rule:
+ - id: 200
+ description: "Outbound masquerade"
+ protocol: tcp
+ log: true
+ outbound_interface:
+ name: eth0
+ translation:
+ address: masquerade
+ state: merged
+
+# Using merged - configure static NAT
+- name: Merge static NAT rule
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ static:
+ rule:
+ - id: 300
+ description: "Static mapping"
+ inbound_interface: eth2
+ destination:
+ address: 198.51.100.20
+ translation:
+ address: 192.168.1.20
+ log: true
+ state: merged
+
+# Using merged - configure NAT64
+- name: Merge NAT64 source rule
+ vyos.vyos.vyos_nat:
+ config:
+ nat64:
+ source:
+ rule:
+ - id: 10
+ description: "NAT64 example"
+ source:
+ prefix: 2001:db8::/96
+ match:
+ mark: 100
+ translation:
+ pool:
+ - id: 1
+ address: 192.168.100.10
+ port: "1-65535"
+ protocol: udp
+ state: merged
+
+# Using merged - configure NAT66
+- name: Merge NAT66 destination rule
+ vyos.vyos.vyos_nat:
+ config:
+ nat66:
+ destination:
+ rule:
+ - id: 20
+ description: "NAT66 DNAT"
+ protocol: tcp
+ inbound_interface:
+ name: eth1
+ destination:
+ address: 2001:db8::1
+ translation:
+ address: 2001:db8:1::10
+ port: "8443"
+ state: merged
+
+# Using replaced - replace specific NAT rules
+- name: Replace destination NAT rule
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ destination:
+ rule:
+ - id: 100
+ description: "Replaced web server NAT"
+ protocol: tcp
+ destination:
+ address: 198.51.100.10
+ port: "443"
+ translation:
+ address: 192.168.1.10
+ port: "8443"
+ state: replaced
+
+# Using overridden - override entire NAT configuration
+- name: Override entire NAT configuration
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ destination:
+ rule:
+ - id: 100
+ description: "Only rule after override"
+ protocol: tcp
+ destination:
+ address: 198.51.100.10
+ port: "80"
+ translation:
+ address: 192.168.1.10
+ port: "8080"
+ state: overridden
+
+# Using deleted - delete all NAT configuration
+- name: Delete all NAT configuration
+ vyos.vyos.vyos_nat:
+ state: deleted
+
+# Using deleted - delete specific NAT rules
+- name: Delete specific NAT rules
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ destination:
+ rule:
+ - id: 100
+ source:
+ rule:
+ - id: 200
+ nat64:
+ source:
+ rule:
+ - id: 10
+ state: deleted
+
+# Using gathered
+- name: Gather NAT configuration from device
+ vyos.vyos.vyos_nat:
+ state: gathered
+
+# Using rendered
+- name: Render NAT configuration offline
+ vyos.vyos.vyos_nat:
+ config:
+ nat:
+ destination:
+ rule:
+ - id: 100
+ description: "Rendered rule"
+ protocol: tcp
+ destination:
+ address: 198.51.100.10
+ port: "80"
+ translation:
+ address: 192.168.1.10
+ port: "8080"
+ state: rendered
+
+# Using parsed
+- name: Parse NAT configuration from file
+ vyos.vyos.vyos_nat:
+ running_config: "{{ lookup('file', './nat_config.cfg') }}"
+ state: parsed
+"""
+RETURN = """
+before:
+ description: The configuration prior to the module execution.
+ returned: when I(state) is C(merged), C(replaced), C(overridden) or C(deleted)
+ 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) or C(deleted)
+ type: list
+ sample:
+ - set nat destination rule 100 description 'Web server NAT'
+ - set nat destination rule 100 protocol tcp
+ - set nat destination rule 100 inbound-interface name eth2
+ - set nat destination rule 100 destination address 198.51.100.10
+ - set nat destination rule 100 translation address 192.168.1.10
+ - delete nat source rule 200
+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 nat destination rule 100 description 'Web server NAT'
+ - set nat destination rule 100 protocol tcp
+ - set nat destination rule 100 inbound-interface name eth2
+ - set nat destination rule 100 destination address 198.51.100.10
+ - set nat destination rule 100 translation address 192.168.1.10
+gathered:
+ description: Facts about the network resource gathered from the remote device as structured data.
+ returned: when I(state) is C(gathered)
+ type: dict
+ 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: dict
+ 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.nat.nat import (
+ NatArgs,
+)
+from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.config.nat.nat import (
+ Nat,
+)
+
+
+def main():
+ """
+ Main entry point for module execution
+
+ :returns: the result form module invocation
+ """
+ module = AnsibleModule(
+ argument_spec=NatArgs.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 = Nat(module).execute_module()
+ module.exit_json(**result)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/plugins/modules/vyos_vrf.py b/plugins/modules/vyos_vrf.py
index defe24bb..3f7ae10e 100644
--- a/plugins/modules/vyos_vrf.py
+++ b/plugins/modules/vyos_vrf.py
@@ -1,8 +1,6 @@
#!/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)
+# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
The module file for vyos_vrf