summaryrefslogtreecommitdiff
path: root/plugins/modules/vyos_firewall_rules.py.preview
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/modules/vyos_firewall_rules.py.preview')
-rw-r--r--plugins/modules/vyos_firewall_rules.py.preview492
1 files changed, 0 insertions, 492 deletions
diff --git a/plugins/modules/vyos_firewall_rules.py.preview b/plugins/modules/vyos_firewall_rules.py.preview
deleted file mode 100644
index f535f3a..0000000
--- a/plugins/modules/vyos_firewall_rules.py.preview
+++ /dev/null
@@ -1,492 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# 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
-
-DOCUMENTATION = r"""
----
-module: vyos_firewall_rules
-short_description: Manage firewall rules on VyOS via the REST API.
-description:
- - Manages VyOS firewall rule sets and individual rules using the HTTPS REST API.
- - Mirrors C(vyos.vyos.vyos_firewall_rules) but uses the HTTP API.
-version_added: "1.0.0"
-author:
- - VyOS Community (@vyos)
-options:
- config:
- description: List of firewall rule set configurations.
- type: list
- elements: dict
- suboptions:
- afi:
- description: Address family.
- type: str
- choices: [ipv4, ipv6]
- required: true
- rule_sets:
- description: List of named rule sets.
- type: list
- elements: dict
- suboptions:
- name:
- description: Rule set name.
- type: str
- required: true
- default_action:
- description: Default action for unmatched traffic.
- type: str
- choices: [drop, reject, accept]
- default: drop
- description:
- description: Rule set description.
- type: str
- rules:
- description: List of firewall rules.
- type: list
- elements: dict
- suboptions:
- number:
- description: Rule number (1-999999).
- type: int
- required: true
- action:
- description: Rule action.
- type: str
- choices: [drop, reject, accept, inspect]
- description:
- description: Rule description.
- type: str
- protocol:
- description: Protocol (e.g. C(tcp), C(udp), C(icmp), C(all)).
- type: str
- source:
- description: Source match criteria.
- type: dict
- suboptions:
- address:
- description: Source IP address or network.
- type: str
- port:
- description: Source port or port range.
- type: str
- group:
- description: Address or network group.
- type: dict
- suboptions:
- address_group:
- type: str
- network_group:
- type: str
- destination:
- description: Destination match criteria.
- type: dict
- suboptions:
- address:
- description: Destination IP address or network.
- type: str
- port:
- description: Destination port or port range.
- type: str
- group:
- description: Address or network group.
- type: dict
- suboptions:
- address_group:
- type: str
- network_group:
- type: str
- state:
- description: Connection state matching.
- type: dict
- suboptions:
- established:
- type: bool
- new:
- type: bool
- related:
- type: bool
- invalid:
- type: bool
- enabled:
- description: Whether the rule is active.
- type: bool
- default: true
- state:
- description:
- - C(merged): Add/update listed rule sets and rules.
- - C(replaced): Replace listed rule sets entirely.
- - C(overridden): Replace the entire firewall rule config.
- - C(deleted): Remove listed (or all) rule sets.
- - C(gathered): Read firewall rule config from device.
- type: str
- choices: [merged, replaced, overridden, deleted, gathered]
- default: merged
- hostname:
- description: IP address or FQDN of the VyOS device.
- type: str
- required: true
- port:
- description: HTTPS port for the REST API.
- type: int
- default: 443
- api_key:
- description: API key configured on the device.
- type: str
- required: true
- no_log: true
- timeout:
- description: Request timeout in seconds.
- type: int
- default: 30
- verify_ssl:
- description: Validate the device's TLS certificate.
- type: bool
- default: false
-requirements:
- - VyOS 1.3+
-seealso:
- - module: vyos.vyos.vyos_firewall_rules
-examples: |
- - name: Create an IPv4 firewall rule set
- vyos.rest.vyos_firewall_rules:
- hostname: 192.168.1.1
- api_key: MY-KEY
- config:
- - afi: ipv4
- rule_sets:
- - name: OUTSIDE-IN
- default_action: drop
- rules:
- - number: 10
- action: accept
- protocol: tcp
- destination:
- port: "80,443"
- state:
- established: true
- related: true
- state: merged
-
- - name: Delete all firewall rules
- vyos.rest.vyos_firewall_rules:
- hostname: 192.168.1.1
- api_key: MY-KEY
- state: deleted
-"""
-
-RETURN = r"""
-before:
- description: Firewall rule config before the module ran.
- returned: always
- type: list
-after:
- description: Firewall rule config after the module ran.
- returned: when changed
- type: list
-gathered:
- description: Firewall config read from device (state=gathered).
- returned: when state is gathered
- type: list
-commands:
- description: set/delete commands issued.
- returned: always
- type: list
-"""
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible_collections.vyos.rest.plugins.module_utils.vyos_rest import (
- VYOS_REST_CONNECTION_ARGSPEC,
- VyOSRestClient,
- VyOSRestError,
-)
-
-
-_FW_PATH = {
- "ipv4": ["firewall", "name"],
- "ipv6": ["firewall", "ipv6-name"],
-}
-
-
-def _get_fw_rules(client):
- try:
- result = client.retrieve_show_config(["firewall"])
- data = result.get("data") or {}
- out = []
- for afi, key in [("ipv4", "name"), ("ipv6", "ipv6-name")]:
- sets_data = data.get(key, {})
- if not isinstance(sets_data, dict):
- continue
- rule_sets = []
- for rs_name, rs_data in sets_data.items():
- if not isinstance(rs_data, dict):
- continue
- rs = {
- "name": rs_name,
- "default_action": rs_data.get("default-action", "drop"),
- }
- if "description" in rs_data:
- rs["description"] = rs_data["description"]
- rules = []
- for rnum, rdata in (rs_data.get("rule") or {}).items():
- if not isinstance(rdata, dict):
- continue
- rule = {"number": int(rnum)}
- if "action" in rdata:
- rule["action"] = rdata["action"]
- if "description" in rdata:
- rule["description"] = rdata["description"]
- if "protocol" in rdata:
- rule["protocol"] = rdata["protocol"]
- rule["enabled"] = "disable" not in rdata
- rules.append(rule)
- if rules:
- rs["rules"] = sorted(rules, key=lambda r: r["number"])
- rule_sets.append(rs)
- if rule_sets:
- out.append({"afi": afi, "rule_sets": rule_sets})
- return out
- except VyOSRestError:
- return []
-
-
-def _apply_rule_set(client, afi, rs, commands):
- base = _FW_PATH[afi] + [rs["name"]]
- client.configure_set(base)
- commands.append("set {p}".format(p=" ".join(base)))
-
- if rs.get("default_action"):
- client.configure_set(base + ["default-action"], rs["default_action"])
- commands.append(
- "set {p} default-action {a}".format(
- p=" ".join(base),
- a=rs["default_action"],
- ),
- )
- if rs.get("description"):
- client.configure_set(base + ["description"], rs["description"])
- commands.append(
- "set {p} description '{d}'".format(
- p=" ".join(base),
- d=rs["description"],
- ),
- )
-
- for rule in rs.get("rules") or []:
- rbase = base + ["rule", str(rule["number"])]
- client.configure_set(rbase)
- commands.append("set {p}".format(p=" ".join(rbase)))
-
- if rule.get("action"):
- client.configure_set(rbase + ["action"], rule["action"])
- commands.append(
- "set {p} action {a}".format(p=" ".join(rbase), a=rule["action"]),
- )
- if rule.get("description"):
- client.configure_set(rbase + ["description"], rule["description"])
- if rule.get("protocol"):
- client.configure_set(rbase + ["protocol"], rule["protocol"])
- commands.append(
- "set {p} protocol {pr}".format(
- p=" ".join(rbase),
- pr=rule["protocol"],
- ),
- )
- for direction in ("source", "destination"):
- match = rule.get(direction)
- if not match:
- continue
- mbase = rbase + [direction]
- if match.get("address"):
- client.configure_set(mbase + ["address"], match["address"])
- commands.append(
- "set {p} address '{a}'".format(
- p=" ".join(mbase),
- a=match["address"],
- ),
- )
- if match.get("port"):
- client.configure_set(mbase + ["port"], match["port"])
- commands.append(
- "set {p} port {pt}".format(
- p=" ".join(mbase),
- pt=match["port"],
- ),
- )
-
- state_match = rule.get("state")
- if state_match:
- sbase = rbase + ["state"]
- for st_name in ("established", "new", "related", "invalid"):
- if state_match.get(st_name):
- client.configure_set(sbase + [st_name], "enable")
- commands.append(
- "set {p} {s} enable".format(
- p=" ".join(sbase),
- s=st_name,
- ),
- )
-
- if "enabled" in rule and not rule["enabled"]:
- client.configure_set(rbase + ["disable"])
- commands.append("set {p} disable".format(p=" ".join(rbase)))
-
-
-def main():
- rule_spec = dict(
- number=dict(type="int", required=True),
- action=dict(type="str", choices=["drop", "reject", "accept", "inspect"]),
- description=dict(type="str"),
- protocol=dict(type="str"),
- source=dict(
- type="dict",
- options=dict(
- address=dict(type="str"),
- port=dict(type="str"),
- group=dict(
- type="dict",
- options=dict(
- address_group=dict(type="str"),
- network_group=dict(type="str"),
- ),
- ),
- ),
- ),
- destination=dict(
- type="dict",
- options=dict(
- address=dict(type="str"),
- port=dict(type="str"),
- group=dict(
- type="dict",
- options=dict(
- address_group=dict(type="str"),
- network_group=dict(type="str"),
- ),
- ),
- ),
- ),
- state=dict(
- type="dict",
- options=dict(
- established=dict(type="bool"),
- new=dict(type="bool"),
- related=dict(type="bool"),
- invalid=dict(type="bool"),
- ),
- ),
- enabled=dict(type="bool", default=True),
- )
-
- argument_spec = dict(
- config=dict(
- type="list",
- elements="dict",
- options=dict(
- afi=dict(type="str", required=True, choices=["ipv4", "ipv6"]),
- rule_sets=dict(
- type="list",
- elements="dict",
- options=dict(
- name=dict(type="str", required=True),
- default_action=dict(
- type="str",
- choices=["drop", "reject", "accept"],
- default="drop",
- ),
- description=dict(type="str"),
- rules=dict(type="list", elements="dict", options=rule_spec),
- ),
- ),
- ),
- ),
- state=dict(
- type="str",
- default="merged",
- choices=["merged", "replaced", "overridden", "deleted", "gathered"],
- ),
- )
- argument_spec.update(VYOS_REST_CONNECTION_ARGSPEC)
-
- module = AnsibleModule(
- argument_spec=argument_spec,
- supports_check_mode=True,
- )
-
- client = VyOSRestClient(module)
- state = module.params["state"]
- config = module.params.get("config") or []
- commands = []
- changed = False
-
- before = _get_fw_rules(client)
-
- if state == "gathered":
- module.exit_json(changed=False, gathered=before, before=before, commands=[])
-
- if module.check_mode:
- module.exit_json(changed=True, before=before, commands=["(check mode)"])
-
- try:
- if state in ("deleted", "overridden") and not config:
- for afi_key in ("name", "ipv6-name"):
- try:
- client.configure_delete(["firewall", afi_key])
- commands.append(
- "delete firewall {k}".format(k=afi_key),
- )
- except VyOSRestError:
- pass
- changed = True
-
- elif state == "deleted" and config:
- for entry in config:
- afi = entry["afi"]
- base_path = _FW_PATH[afi]
- for rs in entry.get("rule_sets") or []:
- try:
- client.configure_delete(base_path + [rs["name"]])
- commands.append(
- "delete {p} {n}".format(
- p=" ".join(base_path),
- n=rs["name"],
- ),
- )
- changed = True
- except VyOSRestError:
- pass
-
- elif state in ("merged", "replaced", "overridden"):
- if state == "replaced":
- for entry in config:
- afi = entry["afi"]
- base_path = _FW_PATH[afi]
- for rs in entry.get("rule_sets") or []:
- try:
- client.configure_delete(base_path + [rs["name"]])
- commands.append(
- "delete {p} {n}".format(
- p=" ".join(base_path),
- n=rs["name"],
- ),
- )
- except VyOSRestError:
- pass
- for entry in config:
- afi = entry["afi"]
- for rs in entry.get("rule_sets") or []:
- _apply_rule_set(client, afi, rs, commands)
- changed = True
- except VyOSRestError as exc:
- module.fail_json(msg=str(exc))
-
- after = _get_fw_rules(client) if changed else before
- module.exit_json(changed=changed, before=before, after=after, commands=commands)
-
-
-if __name__ == "__main__":
- main()