diff --git a/docs/vyos.vyos.vyos_nat_module.rst b/docs/vyos.vyos.vyos_nat_module.rst index fa2a890c..607ad0ca 100644 --- a/docs/vyos.vyos.vyos_nat_module.rst +++ b/docs/vyos.vyos.vyos_nat_module.rst @@ -1,1560 +1,301 @@ .. _vyos.vyos.vyos_nat_module: ****************** vyos.vyos.vyos_nat ****************** **NAT resource module** Version added: 1.0.0 .. contents:: :local: :depth: 1 Synopsis -------- - This module manages NAT configuration on devices running Vyos Parameters ---------- .. raw:: html - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterParameter Choices/Defaults Comments
-
- config - -
- dictionary -
-
- -
The desired configuration for the NAT resource represented as a dictionary.
-
-
- cgnat - -
- dictionary -
-
- -
Configuration for Carrier Grade NAT (CGNAT).
-
-
- log_allocation - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Whether to log CGNAT address allocations.
-
-
- pool - -
- dictionary -
-
- -
Configuration for CGNAT pools.
-
-
- external - -
- list - / elements=dictionary -
-
- -
List of external NAT pools for CGNAT.
-
-
- external_port_range - -
- string -
-
- -
Port range to use for NAT translations in this external pool.
-
-
- name - -
- string - / required -
-
- -
Name of the external NAT pool.
-
-
- per_user_limit - -
- dictionary -
-
- -
Per-user limit configuration for the external pool.
-
-
- port - -
- integer -
-
- -
Maximum number of ports allocated per user.
-
-
- range - -
- list - / elements=string -
-
- -
List of external IP addresses or prefixes in the pool.
-
-
- internal - -
- list - / elements=dictionary -
-
- -
List of internal NAT pools for CGNAT.
-
-
- name - -
- string - / required -
-
- -
Name of the internal NAT pool.
-
-
- range - -
- list - / elements=string -
-
- -
List of internal IP addresses or prefixes in the pool.
-
-
- rule - -
- list - / elements=dictionary -
-
- -
List of CGNAT rules.
-
-
- id - -
- integer - / required -
-
- -
Rule number for CGNAT.
-
-
- source - -
- dictionary -
-
- -
Source configuration for CGNAT translation.
-
-
- pool - -
- string -
-
- -
Source pool to use for CGNAT translation.
-
-
- translation - -
- dictionary -
-
- -
Translation configuration for CGNAT.
-
-
- pool - -
- string -
-
- -
Translation pool to use for CGNAT translation.
-
-
- destination - -
- dictionary -
-
- -
Configuration for destination NAT rules.
-
-
- rule - -
- list - / elements=dictionary -
-
- -
List of destination NAT rules.
-
-
- description - -
- string -
-
- -
User-friendly description of the destination NAT rule.
-
-
- destination - -
- dictionary -
-
- -
Match criteria for destination NAT.
-
-
- address - -
- string -
-
- -
IP address, subnet, or range to match for destination NAT.
-
-
- disable - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Disable this destination NAT rule.
-
-
- exclude - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Exclude packets matching this rule from NAT.
-
-
- fqdn - -
- string -
-
- -
Fully qualified domain name to match for destination NAT.
-
-
- group - -
- dictionary -
-
- -
Address/network/port group to match for destination NAT.
-
-
- address_group - -
- string -
-
- -
Address group name to match.
-
-
- domain_group - -
- string -
-
- -
Domain group name to match.
-
-
- mac_group - -
- string -
-
- -
MAC address group name to match.
-
-
- network_group - -
- string -
-
- -
Network group name to match.
-
-
- port_group - -
- string -
-
- -
Port group name to match.
-
-
- log - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Log packets hitting this destination NAT rule.
-
-
- port - -
- string -
-
- -
Port number or range for destination NAT.
-
-
- protocol - -
- string -
-
- -
Protocol to match (TCP, UDP, ICMP, etc.).
-
-
- id - -
- integer - / required -
-
- -
Rule number for destination NAT.
-
-
- source - -
- dictionary -
-
- -
Configuration for source NAT rules.
-
-
- rule - -
- list - / elements=dictionary -
-
- -
List of source NAT rules.
-
-
- description - -
- string -
-
- -
User-friendly description of the source NAT rule.
-
-
- destination - -
- dictionary -
-
- -
Match criteria for source NAT.
-
-
- address - -
- string -
-
- -
IP address, subnet, or range to match for source NAT.
-
-
- disable - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Disable this source NAT rule.
-
-
- exclude - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Exclude packets matching this rule from NAT.
-
-
- fqdn - -
- string -
-
- -
Fully qualified domain name to match for source NAT.
-
-
- group - -
- dictionary -
-
- -
Address/network/port group to match for source NAT.
-
-
- address_group - -
- string -
-
- -
Address group name to match.
-
-
- domain_group - -
- string -
-
- -
Domain group name to match.
-
-
- mac_group - -
- string -
-
- -
MAC address group name to match.
-
-
- network_group - -
- string -
-
- -
Network group name to match.
-
-
- port_group - -
- string -
-
- -
Port group name to match.
-
-
- log - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Log packets hitting this source NAT rule.
-
-
- port - -
- string -
-
- -
Port number or range for source NAT.
-
- protocol - -
- string -
-
- -
Protocol to match (TCP, UDP, ICMP, etc.).
-
-
- id - -
- integer - / required -
-
- -
Rule number for source NAT.
-
-
- static + config
dictionary
-
Configuration for static NAT rules.
-
-
- rule - -
- list - / elements=dictionary -
-
- -
List of static NAT rules.
+
The desired configuration for the NAT resource represented as a dictionary.
-
- description - -
- string -
-
- -
User-friendly description of the static NAT rule.
-
+
- destination + nat
dictionary
-
Match criteria for static NAT.
-
-
- address - -
- string -
-
- -
IP address, subnet, or range to match for static NAT.
+
Configuration for NAT rules.
-
- disable - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Disable this static NAT rule.
-
-
- id - -
- integer - / required -
-
- -
Rule number for static NAT (one-to-one).
-
-
- inbound_interface - -
- list - / elements=string -
-
- -
List of inbound interfaces that this static NAT rule applies to.
-
-
- log - -
- boolean -
-
-
    Choices: -
  • no
  • -
  • yes
  • -
-
-
Log packets hitting this static NAT rule.
-
-
- translation - -
- dictionary -
-
- -
Translation configuration for static NAT.
-
-
- address - -
- string -
-
- -
IP address or prefix to translate to.
-
running_config
string
This option is used only with state parsed.
The value of this option should be the output received from the VYOS device by executing the command show configuration commands | grep nat.
The states replaced and overridden have identical behaviour for this module.
The state parsed reads the configuration from show configuration commands | grep nat option and transforms it into Ansible structured data as per the resource module's argspec and the value is then returned in the parsed key within the result.
+
state
string
    Choices:
  • deleted
  • merged ←
  • overridden
  • replaced
  • gathered
  • rendered
  • parsed
The state the configuration should be left in.

Notes ----- .. note:: - Tested against VyOS 1.3.8, 1.4.2, the upcoming 1.5, and the rolling release of spring 2025 - This module works with connection ``network_cli``. Examples -------- .. code-block:: yaml # Using merged - name: Merge NAT source rule vyos.vyos.vyos_nat: config: source: rule: - id: 100 description: "Outbound masquerade" state: merged # Using gathered - name: Gather NAT config vyos.vyos.vyos_nat: state: gathered # Using deleted - name: Delete NAT config vyos.vyos.vyos_nat: state: deleted # Using replaced - name: Replace NAT config vyos.vyos.vyos_nat: config: source: rule: - id: 100 description: "Replaced rule" state: replaced # Using parsed - name: Parse NAT config vyos.vyos.vyos_nat: running_config: "{{ lookup('file', './nat_config.cfg') }}" state: parsed # Using rendered - name: Render NAT config offline vyos.vyos.vyos_nat: config: source: rule: - id: 100 description: "Rendered rule" state: rendered Return Values ------------- Common return values are documented `here `_, the following are the fields unique to this module: .. raw:: html
Key Returned Description
after
dictionary
when changed
The resulting configuration after module execution.

Sample:
This output will always be in the same format as the module argspec.
before
dictionary
when state is merged, replaced, overridden, deleted or purged
The configuration prior to the module execution.

Sample:
This output will always be in the same format as the module argspec.
commands
list
when state is merged, replaced, overridden, deleted or purged
The set of commands pushed to the remote device.

Sample:
["set nat source rule 100 description 'Outbound masquerade'"]
gathered
dictionary
when state is gathered
Facts about the network resource gathered from the remote device as structured data.

Sample:
This output will always be in the same format as the module argspec.
parsed
dictionary
when state is parsed
The device native config provided in running_config option parsed into structured data as per module argspec.

Sample:
This output will always be in the same format as the module argspec.
rendered
list
when state is rendered
The provided configuration in the task rendered in device-native format (offline).

Sample:
["set nat source rule 100 description 'Rendered rule'"]


Status ------ Authors ~~~~~~~ - Evgeny Molotkov (@omnom62) diff --git a/plugins/module_utils/network/vyos/argspec/nat/nat.py b/plugins/module_utils/network/vyos/argspec/nat/nat.py index 6ff5b579..ada8a1cd 100644 --- a/plugins/module_utils/network/vyos/argspec/nat/nat.py +++ b/plugins/module_utils/network/vyos/argspec/nat/nat.py @@ -1,304 +1,307 @@ # -*- 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_nat module """ class NatArgs(object): # pylint: disable=R0903 """The arg spec for the vyos_nat module""" argument_spec = { "config": { "type": "dict", - "options": { - "cgnat": { - "type": "dict", - "options": { - "log_allocation": { - "type": "bool", - }, - "pool": { - "type": "dict", - "options": { - "external": { - "type": "list", - "elements": "dict", - "options": { - "name": { - "type": "str", - "required": True, - }, - "external_port_range": { - "type": "str", - }, - "per_user_limit": { - "type": "dict", - "options": { - "port": { - "type": "int", + "nat": { + "type": "dict", + "options": { + "cgnat": { + "type": "dict", + "options": { + "log_allocation": { + "type": "bool", + }, + "pool": { + "type": "dict", + "options": { + "external": { + "type": "list", + "elements": "dict", + "options": { + "name": { + "type": "str", + "required": True, + }, + "external_port_range": { + "type": "str", + }, + "per_user_limit": { + "type": "dict", + "options": { + "port": { + "type": "int", + }, }, }, - }, - "range": { - "type": "list", - "elements": "str", + "range": { + "type": "list", + "elements": "str", + }, }, }, - }, - "internal": { - "type": "list", - "elements": "dict", - "options": { - "name": { - "type": "str", - "required": True, - }, - "range": { - "type": "list", - "elements": "str", + "internal": { + "type": "list", + "elements": "dict", + "options": { + "name": { + "type": "str", + "required": True, + }, + "range": { + "type": "list", + "elements": "str", + }, }, }, }, }, - }, - "rule": { - "type": "list", - "elements": "dict", - "options": { - "id": { - "type": "int", - "required": True, - }, - "source": { - "type": "dict", - "options": { - "pool": { - "type": "str", + "rule": { + "type": "list", + "elements": "dict", + "options": { + "id": { + "type": "int", + "required": True, + }, + "source": { + "type": "dict", + "options": { + "pool": { + "type": "str", + }, }, }, - }, - "translation": { - "type": "dict", - "options": { - "pool": { - "type": "str", + "translation": { + "type": "dict", + "options": { + "pool": { + "type": "str", + }, }, }, }, }, }, }, - }, - "destination": { - "type": "dict", - "options": { - "rule": { - "type": "list", - "elements": "dict", - "options": { - "id": { - "type": "int", - "required": True, - }, - "description": { - "type": "str", - }, - "destination": { - "type": "dict", - "options": { - "address": { - "type": "str", - }, - "fqdn": { - "type": "str", - }, - "group": { - "type": "dict", - "options": { - "address_group": { - "type": "str", - }, - "domain_group": { - "type": "str", - }, - "mac_group": { - "type": "str", - }, - "network_group": { - "type": "str", - }, - "port_group": { - "type": "str", + "destination": { + "type": "dict", + "options": { + "rule": { + "type": "list", + "elements": "dict", + "options": { + "id": { + "type": "int", + "required": True, + }, + "description": { + "type": "str", + }, + "destination": { + "type": "dict", + "options": { + "address": { + "type": "str", + }, + "fqdn": { + "type": "str", + }, + "group": { + "type": "dict", + "options": { + "address_group": { + "type": "str", + }, + "domain_group": { + "type": "str", + }, + "mac_group": { + "type": "str", + }, + "network_group": { + "type": "str", + }, + "port_group": { + "type": "str", + }, }, }, - }, - "port": { - "type": "str", - }, - "protocol": { - "type": "str", - }, - "exclude": { - "type": "bool", - }, - "log": { - "type": "bool", - }, - "disable": { - "type": "bool", + "port": { + "type": "str", + }, + "protocol": { + "type": "str", + }, + "exclude": { + "type": "bool", + }, + "log": { + "type": "bool", + }, + "disable": { + "type": "bool", + }, }, }, }, }, }, }, - }, - "source": { - "type": "dict", - "options": { - "rule": { - "type": "list", - "elements": "dict", - "options": { - "id": { - "type": "int", - "required": True, - }, - "description": { - "type": "str", - }, - "destination": { - "type": "dict", - "options": { - "address": { - "type": "str", - }, - "fqdn": { - "type": "str", - }, - "group": { - "type": "dict", - "options": { - "address_group": { - "type": "str", - }, - "domain_group": { - "type": "str", - }, - "mac_group": { - "type": "str", - }, - "network_group": { - "type": "str", - }, - "port_group": { - "type": "str", + "source": { + "type": "dict", + "options": { + "rule": { + "type": "list", + "elements": "dict", + "options": { + "id": { + "type": "int", + "required": True, + }, + "description": { + "type": "str", + }, + "destination": { + "type": "dict", + "options": { + "address": { + "type": "str", + }, + "fqdn": { + "type": "str", + }, + "group": { + "type": "dict", + "options": { + "address_group": { + "type": "str", + }, + "domain_group": { + "type": "str", + }, + "mac_group": { + "type": "str", + }, + "network_group": { + "type": "str", + }, + "port_group": { + "type": "str", + }, }, }, - }, - "port": { - "type": "str", - }, - "protocol": { - "type": "str", - }, - "exclude": { - "type": "bool", - }, - "log": { - "type": "bool", - }, - "disable": { - "type": "bool", + "port": { + "type": "str", + }, + "protocol": { + "type": "str", + }, + "exclude": { + "type": "bool", + }, + "log": { + "type": "bool", + }, + "disable": { + "type": "bool", + }, }, }, }, }, }, }, - }, - "static": { - "type": "dict", - "options": { - "rule": { - "type": "list", - "elements": "dict", - "options": { - "id": { - "type": "int", - "required": True, - }, - "description": { - "type": "str", - }, - "destination": { - "type": "dict", - "options": { - "address": { - "type": "str", + "static": { + "type": "dict", + "options": { + "rule": { + "type": "list", + "elements": "dict", + "options": { + "id": { + "type": "int", + "required": True, + }, + "description": { + "type": "str", + }, + "destination": { + "type": "dict", + "options": { + "address": { + "type": "str", + }, }, }, - }, - "inbound_interface": { - "type": "list", - "elements": "str", - }, - "log": { - "type": "bool", - }, - "disable": { - "type": "bool", - }, - "translation": { - "type": "dict", - "options": { - "address": { - "type": "str", + "inbound_interface": { + "type": "list", + "elements": "str", + }, + "log": { + "type": "bool", + }, + "disable": { + "type": "bool", + }, + "translation": { + "type": "dict", + "options": { + "address": { + "type": "str", + }, }, }, }, }, }, }, }, }, }, "running_config": {"type": "str"}, "state": { "type": "str", "choices": [ "deleted", "merged", "overridden", "replaced", "gathered", "rendered", "parsed", ], "default": "merged", }, } # pylint: disable=C0301 diff --git a/plugins/module_utils/network/vyos/facts/nat/nat.py b/plugins/module_utils/network/vyos/facts/nat/nat.py index 2d196818..f7cfa86e 100644 --- a/plugins/module_utils/network/vyos/facts/nat/nat.py +++ b/plugins/module_utils/network/vyos/facts/nat/nat.py @@ -1,95 +1,77 @@ # -*- 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 ntp 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.nat.nat import ( NatArgs, ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.rm_templates.nat import ( NatTemplate, ) -# from ansible_collections.ansible.netcommon.plugins.module_utils.network.common import utils - - class NatFacts(object): """The vyos nat facts class""" def __init__(self, module, subspec="config", options="options"): self._module = module self.argument_spec = NatArgs.argument_spec def get_config(self, connection): return connection.get("show configuration commands | match 'nat'") def populate_facts(self, connection, ansible_facts, data=None): """Populate the facts for Ntp 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_config(connection) for resource in data.splitlines(): config_lines.append(re.sub("'", "", resource)) # parse native config using the Nat template nat_parser = NatTemplate(lines=config_lines, module=self._module) objs = nat_parser.parse() - self._module.fail_json(msg=objs) - # if objs: - # if "allow_clients" in objs: - # objs["allow_clients"] = sorted(list(objs["allow_clients"])) - - # if "listen_addresses" in objs: - # objs["listen_addresses"] = sorted(list(objs["listen_addresses"])) - - # """ if "options" in objs["servers"].values(): - # val = objs["servers"].values() - # val["options"] = sorted(val["options"]) """ - - # if "servers" in objs: - # objs["servers"] = list(objs["servers"].values()) - # objs["servers"] = sorted(objs["servers"], key=lambda k: k["server"]) - # for i in objs["servers"]: - # if "options" in i: - # i["options"] = sorted(list(i["options"])) - - # ansible_facts["ansible_network_resources"].pop("ntp_global", None) + ansible_facts["ansible_network_resources"].pop("nat", None) - # params = utils.remove_empties( - # ntp_parser.validate_config(self.argument_spec, {"config": objs}, redact=True), - # ) + # self._module.fail_json(msg=objs) + params = utils.remove_empties( + nat_parser.validate_config(self.argument_spec, {"config": objs}, redact=True), + ) - # if params.get("config"): - # facts["ntp_global"] = params["config"] - # ansible_facts["ansible_network_resources"].update(facts) + if params.get("config"): + facts["nat"] = params["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/nat.py b/plugins/module_utils/network/vyos/rm_templates/nat.py index 9671ad93..77c4817f 100644 --- a/plugins/module_utils/network/vyos/rm_templates/nat.py +++ b/plugins/module_utils/network/vyos/rm_templates/nat.py @@ -1,643 +1,687 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function __metaclass__ = type import re from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.rm_base.network_template import ( NetworkTemplate, ) class NatTemplate(NetworkTemplate): def __init__(self, lines=None, module=None): prefix = {"set": "set", "remove": "delete"} super(NatTemplate, self).__init__(lines=lines, tmplt=self, prefix=prefix, module=module) # fmt: off PARSERS = [ # # ------------------------- # CGNAT (keep explicit) # ------------------------- # { "name": "cgnat_log_allocation", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+log-allocation $""", re.VERBOSE, ), - "setval": "nat cgnat log-allocation", - "result": {"cgnat": {"log_allocation": True}}, + "setval": "{{ nat }} cgnat log-allocation", + "result": { + "{{ nat }}": { + "cgnat": { + "log_allocation": True, + }, + }, + }, }, { "name": "cgnat_pool_external_range", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+pool \s+external \s+(?P\S+) \s+range \s+(?P\S+)(?:\s+seq\s+(?P\d+))? $""", re.VERBOSE, ), - "setval": "nat cgnat pool external {{ name }} range {{ range }}{% if seq is defined %} seq {{ seq }}{% endif %}", + "setval": "{{ nat }} cgnat pool external {{ name }} range {{ range }}{% if seq is defined %} seq {{ seq }}{% endif %}", "result": { - "cgnat": { - "pool": { - "external": [ - { - "name": "{{ name }}", - "ranges": ["{{ range }}"], - "seq": "{{ seq }}", - }, - ], + "{{ nat }}": { + "cgnat": { + "pool": { + "external": [ + { + "name": "{{ name }}", + "ranges": ["{{ range }}"], + "seq": "{{ seq }}", + }, + ], + }, }, }, }, }, { "name": "cgnat_pool_external_port_range", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+pool \s+external \s+(?P\S+) \s+external-port-range \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat cgnat pool external {{ name }} external-port-range {{ range }}", + "setval": "{{ nat }} cgnat pool external {{ name }} external-port-range {{ range }}", "result": { - "cgnat": { - "pool": { - "external": [ - { - "name": "{{ name }}", - "external_port_range": "{{ range }}", - }, - ], + "{{ nat }}": { + "cgnat": { + "pool": { + "external": [ + { + "name": "{{ name }}", + "external_port_range": "{{ range }}", + }, + ], + }, }, }, }, }, { "name": "cgnat_pool_external_per_user", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+pool \s+external \s+(?P\S+) \s+per-user-limit \s+port \s+(?P\d+) $""", re.VERBOSE, ), - "setval": "nat cgnat pool external {{ name }} per-user-limit port {{ limit }}", + "setval": "{{ nat }} cgnat pool external {{ name }} per-user-limit port {{ limit }}", "result": { - "cgnat": { - "pool": { - "external": [ - { - "name": "{{ name }}", - "per_user_limit_port": "{{ limit }}", - }, - ], + "{{ nat }}": { + "cgnat": { + "pool": { + "external": [ + { + "name": "{{ name }}", + "per_user_limit_port": "{{ limit }}", + }, + ], + }, }, }, }, }, { "name": "cgnat_pool_internal_range", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+pool \s+internal \s+(?P\S+) \s+range \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat cgnat pool internal {{ name }} range {{ range }}", + "setval": "{{ nat }} cgnat pool internal {{ name }} range {{ range }}", "result": { - "cgnat": { - "pool": { - "internal": [ - { - "name": "{{ name }}", - "ranges": ["{{ range }}"], - }, - ], + "{{ nat }}": { + "cgnat": { + "pool": { + "internal": [ + { + "name": "{{ name }}", + "ranges": ["{{ range }}"], + }, + ], + }, }, }, }, }, { "name": "cgnat_rule_source_pool", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+rule \s+(?P\d+) \s+source \s+pool \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat cgnat rule {{ id }} source pool {{ pool }}", + "setval": "{{ nat }} cgnat rule {{ id }} source pool {{ pool }}", "result": { - "cgnat": { - "rule": [ - { - "id": "{{ id }}", - "source": {"pool": "{{ pool }}"}, - }, - ], + "{{ nat }}": { + "cgnat": { + "rule": [ + { + "id": "{{ id }}", + "source": {"pool": "{{ pool }}"}, + }, + ], + }, }, }, }, { "name": "cgnat_rule_translation_pool", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+cgnat \s+rule \s+(?P\d+) \s+translation \s+pool \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat cgnat rule {{ id }} translation pool {{ pool }}", + "setval": "{{ nat }} cgnat rule {{ id }} translation pool {{ pool }}", "result": { - "cgnat": { - "rule": [ - { - "id": "{{ id }}", - "translation": {"pool": "{{ pool }}"}, - }, - ], + "{{ nat }}": { + "cgnat": { + "rule": [ + { + "id": "{{ id }}", + "translation": {"pool": "{{ pool }}"}, + }, + ], + }, }, }, }, # # ------------------------- # GENERIC NAT (destination/source/static) # ------------------------- # # description { "name": "nat_type_description", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+description \s+(?P.+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} description {{ description }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} description {{ description }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": {"description": "{{ description }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": {"description": "{{ description }}"}, + }, }, }, }, }, # protocol { "name": "nat_type_protocol", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+protocol \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} protocol {{ protocol }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} protocol {{ protocol }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": {"protocol": "{{ protocol }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": {"protocol": "{{ protocol }}"}, + }, }, }, }, }, # flags { "name": "nat_type_disable", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+disable $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} disable", - "result": {"{{ type }}": {"rule": {"{{ rule }}": {"disable": True}}}}, + "setval": "{{ nat }} {{ type }} rule {{ rule }} disable", + "result": {"{{ nat }}": {"{{ type }}": {"rule": {"{{ rule }}": {"disable": True}}}}}, }, { "name": "nat_type_exclude", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+exclude $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} exclude", - "result": {"{{ type }}": {"rule": {"{{ rule }}": {"exclude": True}}}}, + "setval": "{{ nat }} {{ type }} rule {{ rule }} exclude", + "result": {"{{ nat }}": {"{{ type }}": {"rule": {"{{ rule }}": {"exclude": True}}}}}, }, { "name": "nat_type_log", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+log $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} log", - "result": {"{{ type }}": {"rule": {"{{ rule }}": {"log": True}}}}, + "setval": "{{ nat }} {{ type }} rule {{ rule }} log", + "result": {"{{ nat }}": {"{{ type }}": {"rule": {"{{ rule }}": {"log": True}}}}}, }, # address (destination/source) { "name": "nat_type_address", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+(?Pdestination|source) \s+address \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} {{ atype }} address {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} {{ atype }} address {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "{{ atype }}": {"address": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "{{ atype }}": {"address": "{{ value }}"}, + }, }, }, }, }, }, # fqdn { "name": "nat_type_fqdn", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+(?Pdestination|source) \s+fqdn \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} {{ atype }} fqdn {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} {{ atype }} fqdn {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "{{ atype }}": {"fqdn": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "{{ atype }}": {"fqdn": "{{ value }}"}, + }, }, }, }, }, }, # port { "name": "nat_type_port", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+(?Pdestination|source) \s+port \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} {{ atype }} port {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} {{ atype }} port {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "{{ atype }}": {"port": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "{{ atype }}": {"port": "{{ value }}"}, + }, }, }, }, }, }, # translation address { "name": "nat_type_translation_address", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+translation \s+address \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} translation address {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} translation address {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "translation": {"address": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "translation": {"address": "{{ value }}"}, + }, }, }, }, }, }, # translation port { "name": "nat_type_translation_port", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+translation \s+port \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} translation port {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} translation port {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "translation": {"port": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "translation": {"port": "{{ value }}"}, + }, }, }, }, }, }, # inbound interface { "name": "nat_type_inbound_interface", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+inbound-interface \s+(?Pgroup|name) \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} inbound-interface {{ mode }} {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} inbound-interface {{ mode }} {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "inbound_interface": { - "{{ mode }}": "{{ value }}", + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "inbound_interface": { + "{{ mode }}": "{{ value }}", + }, }, }, }, }, }, }, # packet type { "name": "nat_type_packet_type", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+packet-type \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} packet-type {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} packet-type {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": {"packet_type": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": {"packet_type": "{{ value }}"}, + }, }, }, }, }, # load balance backend { "name": "nat_type_lb_backend", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+load-balance \s+backend \s+(?P\S+) \s+weight \s+(?P\d+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} load-balance backend {{ ip }} weight {{ weight }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} load-balance backend {{ ip }} weight {{ weight }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "load_balance": { - "backend": { - "ip": "{{ ip }}", - "weight": "{{ weight }}", + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "load_balance": { + "backend": { + "ip": "{{ ip }}", + "weight": "{{ weight }}", + }, }, }, }, }, }, }, }, # load balance hash { "name": "nat_type_lb_hash", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+load-balance \s+hash \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} load-balance hash {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} load-balance hash {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "load_balance": {"hash": "{{ value }}"}, + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "load_balance": {"hash": "{{ value }}"}, + }, }, }, }, }, }, # translation options { "name": "nat_type_translation_options", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+translation \s+options \s+(?Paddress-mapping|port-mapping) \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} translation options {{ opt }} {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} translation options {{ opt }} {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "translation": { - "options": { - "{{ opt }}": "{{ value }}", + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "translation": { + "options": { + "{{ opt }}": "{{ value }}", + }, }, }, }, }, }, }, }, # redirect port { "name": "nat_type_translation_redirect", "getval": re.compile( r""" ^set - \s+nat + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+translation \s+redirect \s+port \s+(?P\S+) $""", re.VERBOSE, ), - "setval": "nat {{ type }} rule {{ rule }} translation redirect port {{ value }}", + "setval": "{{ nat }} {{ type }} rule {{ rule }} translation redirect port {{ value }}", "result": { - "{{ type }}": { - "rule": { - "{{ rule }}": { - "translation": { - "redirect_port": "{{ value }}", + "{{ nat }}": { + "{{ type }}": { + "rule": { + "{{ rule }}": { + "translation": { + "redirect_port": "{{ value }}", + }, }, }, }, }, }, }, ] # fmt: on diff --git a/plugins/modules/vyos_nat.py b/plugins/modules/vyos_nat.py index fec94c7a..c2dec5ef 100644 --- a/plugins/modules/vyos_nat.py +++ b/plugins/modules/vyos_nat.py @@ -1,414 +1,418 @@ #!/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_nat """ from __future__ import absolute_import, division, print_function __metaclass__ = type DOCUMENTATION = """ module: vyos_nat version_added: 1.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.3.8, 1.4.2, the upcoming 1.5, and the rolling release of spring 2025 - 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: - cgnat: + nat: type: dict - description: Configuration for Carrier Grade NAT (CGNAT). + description: Configuration for NAT rules. suboptions: - log_allocation: - type: bool - description: Whether to 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: int - description: Maximum number of ports allocated per user. - range: - type: list - elements: str - description: List of external IP addresses or prefixes in the pool. - 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 configuration for CGNAT translation. - suboptions: - pool: - type: str - description: Source pool to use for CGNAT translation. - translation: - type: dict - description: Translation configuration for CGNAT. - suboptions: - pool: - type: str - description: Translation pool 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. - destination: - type: dict - description: Match criteria for destination NAT. - suboptions: - address: - type: str - description: IP address, subnet, or range to match for destination NAT. - fqdn: - type: str - description: Fully qualified domain name to match for destination NAT. - group: - type: dict - description: Address/network/port group to match for destination NAT. - suboptions: - 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. - port: - type: str - description: Port number or range for destination NAT. - protocol: - type: str - description: Protocol to match (TCP, UDP, ICMP, etc.). - exclude: - type: bool - description: Exclude packets matching this rule from NAT. - log: - type: bool - description: Log packets hitting this destination NAT rule. - disable: - type: bool - description: Disable this destination NAT rule. - 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. - destination: - type: dict - description: Match criteria for source NAT. - suboptions: - address: - type: str - description: IP address, subnet, or range to match for source NAT. - fqdn: - type: str - description: Fully qualified domain name to match for source NAT. - group: - type: dict - description: Address/network/port group to match for source NAT. - suboptions: - 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. - port: - type: str - description: Port number or range for source NAT. - protocol: - type: str - description: Protocol to match (TCP, UDP, ICMP, etc.). - exclude: - type: bool - description: Exclude packets matching this rule from NAT. - log: - type: bool - description: Log packets hitting this source NAT rule. - disable: - type: bool - description: Disable this source NAT rule. - static: - type: dict - description: Configuration for static 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 (one-to-one). - destination: - type: dict - description: Match criteria for static NAT. - suboptions: - address: - type: str - description: IP address, subnet, or range to match for static NAT. - log: - type: bool - description: Log packets hitting this static NAT rule. - disable: - type: bool - description: Disable this static NAT rule. - description: - type: str - description: User-friendly description of the static NAT rule. - inbound_interface: - type: list - elements: str - description: List of inbound interfaces that this static NAT rule applies to. - translation: - type: dict - description: Translation configuration for static NAT. - suboptions: - address: - type: str - description: IP address or prefix to translate to. + cgnat: + type: dict + description: Configuration for Carrier Grade NAT (CGNAT). + suboptions: + log_allocation: + type: bool + description: Whether to 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: int + description: Maximum number of ports allocated per user. + range: + type: list + elements: str + description: List of external IP addresses or prefixes in the pool. + 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 configuration for CGNAT translation. + suboptions: + pool: + type: str + description: Source pool to use for CGNAT translation. + translation: + type: dict + description: Translation configuration for CGNAT. + suboptions: + pool: + type: str + description: Translation pool 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. + destination: + type: dict + description: Match criteria for destination NAT. + suboptions: + address: + type: str + description: IP address, subnet, or range to match for destination NAT. + fqdn: + type: str + description: Fully qualified domain name to match for destination NAT. + group: + type: dict + description: Address/network/port group to match for destination NAT. + suboptions: + 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. + port: + type: str + description: Port number or range for destination NAT. + protocol: + type: str + description: Protocol to match (TCP, UDP, ICMP, etc.). + exclude: + type: bool + description: Exclude packets matching this rule from NAT. + log: + type: bool + description: Log packets hitting this destination NAT rule. + disable: + type: bool + description: Disable this destination NAT rule. + 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. + destination: + type: dict + description: Match criteria for source NAT. + suboptions: + address: + type: str + description: IP address, subnet, or range to match for source NAT. + fqdn: + type: str + description: Fully qualified domain name to match for source NAT. + group: + type: dict + description: Address/network/port group to match for source NAT. + suboptions: + 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. + port: + type: str + description: Port number or range for source NAT. + protocol: + type: str + description: Protocol to match (TCP, UDP, ICMP, etc.). + exclude: + type: bool + description: Exclude packets matching this rule from NAT. + log: + type: bool + description: Log packets hitting this source NAT rule. + disable: + type: bool + description: Disable this source NAT rule. + static: + type: dict + description: Configuration for static 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 (one-to-one). + destination: + type: dict + description: Match criteria for static NAT. + suboptions: + address: + type: str + description: IP address, subnet, or range to match for static NAT. + log: + type: bool + description: Log packets hitting this static NAT rule. + disable: + type: bool + description: Disable this static NAT rule. + description: + type: str + description: User-friendly description of the static NAT rule. + inbound_interface: + type: list + elements: str + description: List of inbound interfaces that this static NAT rule applies to. + translation: + type: dict + description: Translation configuration for static NAT. + suboptions: + address: + type: str + description: IP address or prefix to translate 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 | grep nat). - The states I(replaced) and I(overridden) have identical behaviour for this module. - The state I(parsed) reads the configuration from C(show configuration commands | grep nat) 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 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 - name: Merge NAT source rule vyos.vyos.vyos_nat: config: source: rule: - id: 100 description: "Outbound masquerade" state: merged # Using gathered - name: Gather NAT config vyos.vyos.vyos_nat: state: gathered # Using deleted - name: Delete NAT config vyos.vyos.vyos_nat: state: deleted # Using replaced - name: Replace NAT config vyos.vyos.vyos_nat: config: source: rule: - id: 100 description: "Replaced rule" state: replaced # Using parsed - name: Parse NAT config vyos.vyos.vyos_nat: running_config: "{{ lookup('file', './nat_config.cfg') }}" state: parsed # Using rendered - name: Render NAT config offline vyos.vyos.vyos_nat: config: source: rule: - id: 100 description: "Rendered rule" state: rendered """ 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 nat source rule 100 description 'Outbound masquerade' 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 source rule 100 description 'Rendered rule' 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()