diff --git a/plugins/module_utils/network/vyos/argspec/nat/nat.py b/plugins/module_utils/network/vyos/argspec/nat/nat.py index e6b7fe70..18e47985 100644 --- a/plugins/module_utils/network/vyos/argspec/nat/nat.py +++ b/plugins/module_utils/network/vyos/argspec/nat/nat.py @@ -1,554 +1,596 @@ # -*- 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 """ 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", "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": "str", }, }, }, "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", }, }, }, "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", }, "protocol": { "type": "str", }, + "packet_type": { + "type": "str", + }, "exclude": { "type": "bool", }, "log": { "type": "bool", }, "disable": { "type": "bool", }, "inbound_interface": { "type": "dict", "options": { "name": { "type": "str", }, "group": { "type": "str", }, }, }, "destination": { "type": "dict", "options": { "address": { "type": "str", }, "fqdn": { "type": "str", }, "port": { "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", - }, - }, + "address_group": { + "type": "str", + }, + "domain_group": { + "type": "str", + }, + "mac_group": { + "type": "str", + }, + "network_group": { + "type": "str", + }, + "port_group": { + "type": "str", }, }, }, "translation": { "type": "dict", "options": { "address": { "type": "str", }, "port": { "type": "str", }, "redirect_port": { "type": "str", }, "address_mapping": { "type": "str", "choices": [ "random", "persistent", ], }, "port_mapping": { "type": "str", "choices": [ "random", "none", ], }, }, }, }, }, }, }, "source": { "type": "dict", "options": { "rule": { "type": "list", "elements": "dict", "options": { "id": { "type": "int", "required": True, }, "description": { "type": "str", }, "protocol": { "type": "str", }, + "packet_type": { + "type": "str", + }, "exclude": { "type": "bool", }, "log": { "type": "bool", }, "disable": { "type": "bool", }, + "outbound_interface": { + "type": "dict", + "options": { + "name": { + "type": "str", + }, + "group": { + "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", - }, - }, + "address_group": { + "type": "str", + }, + "domain_group": { + "type": "str", + }, + "mac_group": { + "type": "str", + }, + "network_group": { + "type": "str", + }, + "port_group": { + "type": "str", }, "port": { "type": "str", }, }, }, + "source": { + "type": "dict", + "options": { + "address": {"type": "str"}, + "fqdn": {"type": "str"}, + "port": {"type": "str"}, + "address_group": {"type": "str"}, + "domain_group": {"type": "str"}, + "mac_group": {"type": "str"}, + "network_group": {"type": "str"}, + "port_group": {"type": "str"}, + }, + }, + "translation": { + "type": "dict", + "options": { + "address": { + "type": "str", + }, + "port": { + "type": "str", + }, + "address_mapping": { + "type": "str", + "choices": [ + "random", + "persistent", + ], + }, + "port_mapping": { + "type": "str", + "choices": [ + "random", + "none", + ], + }, + }, + }, }, }, }, }, "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": "str", }, "log": { "type": "bool", }, - "disable": { - "type": "bool", - }, "translation": { "type": "dict", "options": { "address": { "type": "str", }, }, }, }, }, }, }, }, }, "nat64": { "type": "dict", "options": { "source": { "type": "dict", "options": { "rule": { "type": "list", "elements": "dict", "options": { "id": { "type": "int", "required": True, }, "description": { "type": "str", }, "disable": { "type": "bool", }, "match": { "type": "dict", "options": { "mark": { - "type": "int", + "type": "str", }, }, }, "source": { "type": "dict", "options": { "prefix": { "type": "str", }, }, }, "translation": { "type": "dict", "options": { "pool": { "type": "list", "elements": "dict", "options": { "id": { "type": "int", "required": True, }, "address": { "type": "str", }, "description": { "type": "str", }, "disable": { "type": "bool", }, "port": { "type": "str", }, "protocol": { "type": "str", "choices": [ "icmp", "tcp", "udp", ], }, }, }, }, }, }, }, }, }, }, }, "nat66": { "type": "dict", "options": { "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", }, "port": { "type": "str", }, }, }, "disable": { "type": "bool", }, "exclude": { "type": "bool", }, "inbound_interface": { "type": "dict", "options": { "name": { "type": "str", }, }, }, "log": { "type": "bool", }, "protocol": { "type": "str", }, "source": { "type": "dict", "options": { "address": { "type": "str", }, "port": { "type": "str", }, }, }, "translation": { "type": "dict", "options": { "address": { "type": "str", }, "port": { "type": "str", }, }, }, }, }, }, }, "source": { "type": "dict", "options": { "rule": { "type": "list", "elements": "dict", "options": { "id": { "type": "int", "required": True, }, "description": { "type": "str", }, "destination": { "type": "dict", "options": { "port": { "type": "str", }, "prefix": { "type": "str", }, }, }, "disable": { "type": "bool", }, "exclude": { "type": "bool", }, "log": { "type": "bool", }, "outbound_interface": { "type": "dict", "options": { "name": { "type": "str", }, }, }, "protocol": { "type": "str", }, "source": { "type": "dict", "options": { "port": { "type": "str", }, "prefix": { "type": "str", }, }, }, "translation": { "type": "dict", "options": { "address": { "type": "str", }, "port": { "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/rm_templates/nat.py b/plugins/module_utils/network/vyos/rm_templates/nat.py index 305a6fa5..c6d6eedb 100644 --- a/plugins/module_utils/network/vyos/rm_templates/nat.py +++ b/plugins/module_utils/network/vyos/rm_templates/nat.py @@ -1,1139 +1,1229 @@ # -*- 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) # def parse(self): # data = super(NatTemplate, self).parse() # return self._normalize(data) # def _normalize(self, data): # def convert_rules(section): # if not section or "rule" not in section: # return section # rules = section["rule"] # if isinstance(rules, dict): # new_rules = [] # for rule_id, rule_data in rules.items(): # rule = rule_data.copy() # # normalize id # try: # rule["id"] = int(rule_id) # except (ValueError, TypeError): # rule["id"] = rule_id # new_rules.append(rule) # section["rule"] = sorted(new_rules, key=lambda x: x.get("id", 0)) # return section # if not data: # return data # for nat_type in ["nat", "nat64", "nat66"]: # if nat_type not in data: # continue # nat = data[nat_type] # for block in ["destination", "source", "static"]: # if block in nat: # nat[block] = convert_rules(nat[block]) # # CGNAT rules # if "cgnat" in nat and "rule" in nat["cgnat"]: # rules = nat["cgnat"]["rule"] # if isinstance(rules, list): # for r in rules: # if "id" in r: # r["id"] = int(r["id"]) # return data # def _normalize(self, data): # if not data: # return data # def normalize_rules(rules): # """Convert rules dict → sorted list with int IDs, or cast IDs in existing list.""" # if isinstance(rules, dict): # result = [] # for rule_id, rule_data in rules.items(): # rule = rule_data.copy() # try: # rule["id"] = int(rule_id) # except (ValueError, TypeError): # rule["id"] = rule_id # result.append(rule) # return sorted(result, key=lambda x: x.get("id", 0)) # if isinstance(rules, list): # for rule in rules: # if "id" in rule: # try: # rule["id"] = int(rule["id"]) # except (ValueError, TypeError): # pass # return rules # return rules # for nat_type in ["nat", "nat64", "nat66"]: # nat = data.get(nat_type) # if not nat: # continue # for block in ["destination", "source", "static", "cgnat"]: # section = nat.get(block) # if section and "rule" in section: # section["rule"] = normalize_rules(section["rule"]) # return data # fmt: off PARSERS = [ # # ------------------------- # CGNAT (keep explicit) # ------------------------- # { "name": "cgnat_log_allocation", "getval": re.compile( r""" ^set \s+nat \s+cgnat \s+log-allocation $""", re.VERBOSE, ), "setval": "nat cgnat log-allocation", "result": { "nat": { "cgnat": { "log_allocation": True, }, }, }, }, { "name": "cgnat_pool_external_range", "getval": re.compile( r""" ^set \s+nat \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 %}", "result": { "nat": { "cgnat": { "pool": { "external": [ { "name": "{{ name }}", "range": ["{{ range }}"], "seq": "{{ seq }}", }, ], }, }, }, }, }, { "name": "cgnat_pool_external_port_range", "getval": re.compile( r""" ^set \s+nat \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 }}", "result": { "nat": { "cgnat": { "pool": { "external": [ { "name": "{{ name }}", "external_port_range": "{{ range }}", }, ], }, }, }, }, }, { "name": "cgnat_pool_external_per_user", "getval": re.compile( r""" ^set \s+nat \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 }}", "result": { "nat": { "cgnat": { "pool": { "external": [ { "name": "{{ name }}", "per_user_limit": {"port": "{{ limit }}"}, }, ], }, }, }, }, }, { "name": "cgnat_pool_internal_range", "getval": re.compile( r""" ^set \s+nat \s+cgnat \s+pool \s+internal \s+(?P\S+) \s+range \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat cgnat pool internal {{ name }} range {{ range }}", "result": { "nat": { "cgnat": { "pool": { "internal": [ { "name": "{{ name }}", "range": ["{{ range }}"], }, ], }, }, }, }, }, { "name": "cgnat_rule_source_pool", "getval": re.compile( r""" ^set \s+nat \s+cgnat \s+rule \s+(?P\d+) \s+source \s+pool \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat cgnat rule {{ id }} source pool {{ pool }}", "result": { "nat": { "cgnat": { "rule": [ { "id": "{{ id }}", "source": {"pool": "{{ pool }}"}, }, ], }, }, }, }, { "name": "cgnat_rule_translation_pool", "getval": re.compile( r""" ^set \s+nat \s+cgnat \s+rule \s+(?P\d+) \s+translation \s+pool \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat cgnat rule {{ id }} translation pool {{ pool }}", "result": { "nat": { "cgnat": { "rule": [ { "id": "{{ id }}", "translation": {"pool": "{{ pool }}"}, }, ], }, }, }, }, # # ------------------------- # GENERIC NAT (destination/source/static) # ------------------------- # # description { "name": "nat_type_description", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+description \s+(?P.+) $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} description {{ description }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "description": "{{ description }}", }, ], }, }, }, }, # protocol { "name": "nat_type_protocol", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+protocol \s+(?P\S+) $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} protocol {{ protocol }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "protocol": "{{ protocol }}", }, ], }, }, }, }, # flags { "name": "nat_type_disable", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+disable $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} disable", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "disable": True, }, ], }, }, }, }, { "name": "nat_type_exclude", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+exclude $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} exclude", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "exclude": True, }, ], }, }, }, }, { "name": "nat_type_log", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+log $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} log", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "log": True, }, ], }, }, }, }, # address (destination/source) { "name": "nat_type_address", "getval": re.compile( r""" ^set \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 {{ id }} {{ atype }} address {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "{{ atype }}": {"address": "{{ value }}"}, }, ], }, }, }, }, # prefix (destination/source) { "name": "nat_type_prefix", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+(?Pdestination|source) \s+prefix \s+(?P\S+) $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} {{ atype }} prefix {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "{{ atype }}": {"prefix": "{{ value }}"}, }, ], }, }, }, }, # fqdn { "name": "nat_type_fqdn", "getval": re.compile( r""" ^set \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 {{ id }} {{ atype }} fqdn {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "{{ atype }}": {"fqdn": "{{ value }}"}, }, ], }, }, }, }, # port { "name": "nat_type_port", "getval": re.compile( r""" ^set \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 {{ id }} {{ atype }} port {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "{{ atype }}": {"port": "{{ value }}"}, }, ], }, }, }, }, # translation address { "name": "nat_type_translation_address", "getval": re.compile( r""" ^set \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 {{ id }} translation address {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "translation": {"address": "{{ value }}"}, }, ], }, }, }, }, # translation port { "name": "nat_type_translation_port", "getval": re.compile( r""" ^set \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 {{ id }} translation port {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "translation": {"port": "{{ value }}"}, }, ], }, }, }, }, { "name": "nat_inbound_interface_name", "getval": re.compile( r""" ^set \s+nat - \s+(?Pdestination|source|static) + \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+inbound-interface \s+name \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat {{ type }} rule {{ id }} inbound-interface name {{ value }}", "result": { "nat": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "inbound_interface": {"name": "{{ value }}"}, }, ], }, }, }, }, { "name": "nat_inbound_interface_group", "getval": re.compile( r""" ^set \s+nat - \s+(?Pdestination|source|static) + \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+inbound-interface \s+group \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat {{ type }} rule {{ id }} inbound-interface group {{ value }}", "result": { "nat": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "inbound_interface": {"group": "{{ value }}"}, }, ], }, }, }, }, + { + "name": "nat_static_inbound_interface", + "getval": re.compile( + r""" + ^set + \s+nat + \s+static + \s+rule + \s+(?P\S+) + \s+inbound-interface + \s+(?P\S+) + $""", + re.VERBOSE, + ), + "setval": "nat static rule {{ id }} inbound-interface {{ value }}", + "result": { + "nat": { + "static": { + "rule": [ + { + "id": "{{ id }}", + "inbound_interface": "{{ value }}", + }, + ], + }, + }, + }, + }, + # NAT6X inbound interface { "name": "nat6x_inbound_interface", "getval": re.compile( r""" ^set \s+(?Pnat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+inbound-interface \s+name \s+(?P\S+) $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} inbound-interface name {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "inbound_interface": "{{ value }}", }, ], }, }, }, }, + # outbound interface { "name": "nat_type_outbound_interface", "getval": re.compile( r""" ^set - \s+(?Pnat64|nat66) + \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source|static) \s+rule \s+(?P\S+) \s+outbound-interface \s+name \s+(?P\S+) $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} outbound-interface name {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", - "outbound_interface": "{{ value }}", + "outbound_interface": {"name": "{{ value }}"}, + }, + ], + }, + }, + }, + }, + { + "name": "nat_type_outbound_interface_group", + "getval": re.compile( + r""" + ^set + \s+(?Pnat|nat64|nat66) + \s+(?Pdestination|source|static) + \s+rule + \s+(?P\S+) + \s+outbound-interface + \s+group + \s+(?P\S+) + $""", + re.VERBOSE, + ), + "setval": "{{ nat }} {{ type }} rule {{ id }} outbound-interface group {{ value }}", + "result": { + "{{ nat }}": { + "{{ type }}": { + "rule": [ + { + "id": "{{ id }}", + "outbound_interface": {"group": "{{ value }}"}, + }, + ], + }, + }, + }, + }, + { + "name": "nat_type_address_group", + "getval": re.compile( + r""" + ^set + \s+(?Pnat|nat64|nat66) + \s+(?Pdestination|source) + \s+rule + \s+(?P\S+) + \s+(?Pdestination|source) + \s+group + \s+(?Paddress-group|domain-group|mac-group|network-group|port-group) + \s+(?P\S+) + $""", + re.VERBOSE, + ), + "setval": "{{ nat }} {{ type }} rule {{ id }} {{ atype }} group {{ gtype }} {{ value }}", + "result": { + "{{ nat }}": { + "{{ type }}": { + "rule": [ + { + "id": "{{ id }}", + "{{ atype }}": { + "{{ gtype | replace('-', '_') }}": "{{ value }}", + }, }, ], }, }, }, }, - # packet type { "name": "nat_type_packet_type", "getval": re.compile( r""" ^set \s+(?Pnat|nat64|nat66) \s+(?Pdestination|source) \s+rule \s+(?P\S+) \s+packet-type \s+(?P\S+) $""", re.VERBOSE, ), "setval": "{{ nat }} {{ type }} rule {{ id }} packet-type {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "packet_type": "{{ value }}", }, ], }, }, }, }, # load balance backend { "name": "nat_type_lb_backend", "getval": re.compile( r""" ^set \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 {{ id }} load-balance backend {{ ip }} weight {{ weight }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "load_balance": { "backend": { "ip": "{{ ip }}", "weight": "{{ weight }}", }, }, }, ], }, }, }, }, # load balance hash { "name": "nat_type_lb_hash", "getval": re.compile( r""" ^set \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 {{ id }} load-balance hash {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "load_balance": {"hash": "{{ value }}"}, }, ], }, }, }, }, # translation options { "name": "nat_type_translation_options", "getval": re.compile( r""" ^set \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 {{ id }} translation options {{ opt }} {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "translation": { "{{ opt | replace(\"-\", \"_\") }}": "{{ value }}", }, }, ], }, }, }, }, # redirect port { "name": "nat_type_translation_redirect", "getval": re.compile( r""" ^set \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 {{ id }} translation redirect port {{ value }}", "result": { "{{ nat }}": { "{{ type }}": { "rule": [ { "id": "{{ id }}", "translation": { "redirect_port": "{{ value }}", }, }, ], }, }, }, }, { "name": "nat64_match_mark", "getval": re.compile( r""" ^set \s+nat64 \s+source \s+rule \s+(?P\S+) \s+match \s+mark \s+(?P\d+) $""", re.VERBOSE, ), "setval": "nat64 source rule {{ id }} match mark {{ mark }}", "result": { "nat64": { "source": { "rule": [ { "id": "{{ id }}", "match": {"mark": "{{ mark }}"}, }, ], }, }, }, }, { "name": "nat64_translation_pool_address", "getval": re.compile( r""" ^set \s+nat64 \s+source \s+rule \s+(?P\S+) \s+translation \s+pool \s+(?P\d+) \s+address \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat64 source rule {{ id }} translation pool {{ pool_id }} address {{ value }}", "result": { "nat64": { "source": { "rule": [ { "id": "{{ id }}", "translation": { "pool": [{"id": "{{ pool_id }}", "address": "{{ value }}"}], }, }, ], }, }, }, }, { "name": "nat64_translation_pool_description", "getval": re.compile( r""" ^set \s+nat64 \s+source \s+rule \s+(?P\S+) \s+translation \s+pool \s+(?P\d+) \s+description \s+(?P.+) $""", re.VERBOSE, ), "setval": "nat64 source rule {{ id }} translation pool {{ pool_id }} description {{ value }}", "result": { "nat64": { "source": { "rule": [ { "id": "{{ id }}", "translation": { "pool": [{"id": "{{ pool_id }}", "description": "{{ value }}"}], }, }, ], }, }, }, }, { "name": "nat64_translation_pool_disable", "getval": re.compile( r""" ^set \s+nat64 \s+source \s+rule \s+(?P\S+) \s+translation \s+pool \s+(?P\d+) \s+disable $""", re.VERBOSE, ), "setval": "nat64 source rule {{ id }} translation pool {{ pool_id }} disable", "result": { "nat64": { "source": { "rule": [ { "id": "{{ id }}", "translation": { "pool": [{"id": "{{ pool_id }}", "disable": True}], }, }, ], }, }, }, }, { "name": "nat64_translation_pool_port", "getval": re.compile( r""" ^set \s+nat64 \s+source \s+rule \s+(?P\S+) \s+translation \s+pool \s+(?P\d+) \s+port \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat64 source rule {{ id }} translation pool {{ pool_id }} port {{ value }}", "result": { "nat64": { "source": { "rule": [ { "id": "{{ id }}", "translation": { "pool": [{"id": "{{ pool_id }}", "port": "{{ value }}"}], }, }, ], }, }, }, }, { "name": "nat64_translation_pool_protocol", "getval": re.compile( r""" ^set \s+nat64 \s+source \s+rule \s+(?P\S+) \s+translation \s+pool \s+(?P\d+) \s+protocol \s+(?P\S+) $""", re.VERBOSE, ), "setval": "nat64 source rule {{ id }} translation pool {{ pool_id }} protocol {{ value }}", "result": { "nat64": { "source": { "rule": [ { "id": "{{ id }}", "translation": { "pool": [{"id": "{{ pool_id }}", "protocol": "{{ value }}"}], }, }, ], }, }, }, }, ] # fmt: on