diff options
author | maxime <37832743+mlk-89@users.noreply.github.com> | 2024-11-18 20:37:36 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-18 21:37:36 +0200 |
commit | 67cda0147ab54136ef0604427c5a01a7f4b21986 (patch) | |
tree | 4d78ab585fcf90f2dfd6315294969199aef9ed33 | |
parent | 37ba454f746ab6c4b05fef520ced523e2ad032cb (diff) | |
download | vyos.vyos-67cda0147ab54136ef0604427c5a01a7f4b21986.tar.gz vyos.vyos-67cda0147ab54136ef0604427c5a01a7f4b21986.zip |
Add feature for bonding/vlan interface in the firewall_interfaces (#246)
* - Add feature for bonding interface in the firewall_interfaces
- Add feature for vlan interface in the firewall_interfaces
* fix a bug when invoking replaced in the module firewall_rules.
* - Add feature for bonding interface in the firewall_interfaces
- Add feature for vlan interface in the firewall_interfaces
* test: add tests
* fix: support for interface types
* docs: fixed for 1.4 deprecation
---------
Co-authored-by: Maxime.L <maxime@nfrance.com>
Co-authored-by: Gaige B. Paulsen <gaige@cluetrust.com>
Co-authored-by: Gaige B Paulsen <gaige@cluetrust.net>
8 files changed, 483 insertions, 483 deletions
@@ -54,7 +54,7 @@ Name | Description [vyos.vyos.vyos_config](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_config_module.rst)|Manage VyOS configuration on remote device [vyos.vyos.vyos_facts](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_facts_module.rst)|Get facts about vyos devices. [vyos.vyos.vyos_firewall_global](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_global_module.rst)|FIREWALL global resource module -[vyos.vyos.vyos_firewall_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_interfaces_module.rst)|FIREWALL interfaces resource module +[vyos.vyos.vyos_firewall_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_interfaces_module.rst)|Manage firewall rules attributes of interfaces on VyOS devices [vyos.vyos.vyos_firewall_rules](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_firewall_rules_module.rst)|FIREWALL rules resource module [vyos.vyos.vyos_hostname](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_hostname_module.rst)|Manages hostname resource module [vyos.vyos.vyos_interfaces](https://github.com/ansible-collections/vyos.vyos/blob/main/docs/vyos.vyos.vyos_interfaces_module.rst)|Interfaces resource module diff --git a/changelogs/fragments/firewall_interface_types.yml b/changelogs/fragments/firewall_interface_types.yml new file mode 100644 index 0000000..29451e8 --- /dev/null +++ b/changelogs/fragments/firewall_interface_types.yml @@ -0,0 +1,4 @@ +--- +minor_changes: + - added support for VIF interfaces + - expanded firewall interface types to match existing types diff --git a/docs/vyos.vyos.vyos_firewall_interfaces_module.rst b/docs/vyos.vyos.vyos_firewall_interfaces_module.rst index 8510812..386d52b 100644 --- a/docs/vyos.vyos.vyos_firewall_interfaces_module.rst +++ b/docs/vyos.vyos.vyos_firewall_interfaces_module.rst @@ -5,10 +5,10 @@ vyos.vyos.vyos_firewall_interfaces ********************************** -**FIREWALL interfaces resource module** +**Manage firewall rules attributes of interfaces on VyOS devices** -Version added: 1.0.0 +Version added: 2.10.0 .. contents:: :local: @@ -17,7 +17,7 @@ Version added: 1.0.0 Synopsis -------- -- Manage firewall rules of interfaces on VyOS network devices. +- Manage firewall rules of interfaces on VyOS network devices. (1.3-) @@ -211,6 +211,12 @@ Parameters <br/> +Notes +----- + +.. note:: + - Deprecated in VyOS 1.4+, firewalls are no longer connected directly to interfaces. See the Firewall Configuration documentation for how to establish a connection betwen the firewall rulesets and the flow, interface, or zone. + Examples @@ -383,206 +389,121 @@ Examples # Using merged - # + # Before state: # ------------- - # - # vyos@vyos:~$ show configuration commands| grep firewall - # set firewall ipv6-name 'V6-LOCAL' - # set firewall name 'INBOUND' - # set firewall name 'LOCAL' - # set firewall name 'OUTBOUND' - # set interfaces ethernet eth1 firewall in name 'INBOUND' - # set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' - # set interfaces ethernet eth1 firewall local name 'LOCAL' - # set interfaces ethernet eth1 firewall out name 'OUTBOUND' - # set interfaces ethernet eth3 firewall in name 'INBOUND' - # set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' - # set interfaces ethernet eth3 firewall local name 'LOCAL' - # set interfaces ethernet eth3 firewall out name 'OUTBOUND' - # - - name: Merge the provided configuration with the existing running configuration - vyos.vyos.vyos_firewall_interfaces: + # vyos@vyos:~$ show configuration commands | grep interfaces + # set interfaces bonding 'bond0' + # set interfaces bonding 'bond1' + # set interfaces bonding bond2 'ip' + # set interfaces bonding bond2 'ipv6' + # set interfaces ethernet eth0 address 'dhcp' + # set interfaces ethernet eth0 duplex 'auto' + # set interfaces ethernet eth0 'ip' + # set interfaces ethernet eth0 'ipv6' + # set interfaces ethernet eth0 smp_affinity 'auto' + # set interfaces ethernet eth0 speed 'auto' + # set interfaces ethernet 'eth1' + # set interfaces ethernet 'eth2' + + - name: Merge provided configuration with device configuration + vyos.vyos.vyos_interfaces: config: - - access_rules: - - afi: ipv4 - rules: - - name: OUTBOUND - direction: in - - name: INBOUND - direction: out - name: eth1 + - name: eth2 + description: Configured by Ansible + enabled: true + vifs: + - vlan_id: 200 + description: VIF 200 - ETH2 + - name: eth3 + description: Configured by Ansible + mtu: 1500 + - name: bond1 + description: Bond - 1 + mtu: 1200 + - name: vti2 + description: VTI - 2 + enabled: false state: merged - # - # - # ------------------------- - # Module Execution Result - # ------------------------- - # - # "before": [ - # { - # "name": "eth0" - # }, - # { - # "access_rules": [ - # { - # "afi": "ipv4", - # "rules": [ - # { - # "direction": "in", - # "name": "INBOUND" - # }, - # { - # "direction": "local", - # "name": "LOCAL" - # }, - # { - # "direction": "out", - # "name": "OUTBOUND" - # } - # ] - # }, - # { - # "afi": "ipv6", - # "rules": [ - # { - # "direction": "local", - # "name": "V6-LOCAL" - # } - # ] - # } - # ], - # "name": "eth1" - # }, - # { - # "name": "eth2" - # }, - # { - # "access_rules": [ - # { - # "afi": "ipv4", - # "rules": [ - # { - # "direction": "in", - # "name": "INBOUND" - # }, - # { - # "direction": "local", - # "name": "LOCAL" - # }, - # { - # "direction": "out", - # "name": "OUTBOUND" - # } - # ] - # }, - # { - # "afi": "ipv6", - # "rules": [ - # { - # "direction": "local", - # "name": "V6-LOCAL" - # } - # ] - # } - # ], - # "name": "eth3" - # } - # ] - # - # "commands": [ - # "set interfaces ethernet eth1 firewall in name 'OUTBOUND'", - # "set interfaces ethernet eth1 firewall out name 'INBOUND'" - # ] - # - # "after": [ - # { - # "name": "eth0" - # }, - # { - # "access_rules": [ - # { - # "afi": "ipv4", - # "rules": [ - # { - # "direction": "in", - # "name": "OUTBOUND" - # }, - # { - # "direction": "local", - # "name": "LOCAL" - # }, - # { - # "direction": "out", - # "name": "INBOUND" - # } - # ] - # }, - # { - # "afi": "ipv6", - # "rules": [ - # { - # "direction": "local", - # "name": "V6-LOCAL" - # } - # ] - # } - # ], - # "name": "eth1" - # }, - # { - # "name": "eth2" - # }, - # { - # "access_rules": [ - # { - # "afi": "ipv4", - # "rules": [ - # { - # "direction": "in", - # "name": "INBOUND" - # }, - # { - # "direction": "local", - # "name": "LOCAL" - # }, - # { - # "direction": "out", - # "name": "OUTBOUND" - # } - # ] - # }, - # { - # "afi": "ipv6", - # "rules": [ - # { - # "direction": "local", - # "name": "V6-LOCAL" - # } - # ] - # } - # ], - # "name": "eth3" - # } - # ] - # + # Task Output + # ----------- + # before: + # - enabled: true + # name: lo + # - enabled: true + # name: eth3 + # - enabled: true + # name: eth2 + # - enabled: true + # name: eth1 + # - duplex: auto + # enabled: true + # name: eth0 + # speed: auto + # commands: + # - set interfaces ethernet eth2 description 'Configured by Ansible' + # - set interfaces ethernet eth2 vif 200 + # - set interfaces ethernet eth2 vif 200 description 'VIF 200 - ETH2' + # - set interfaces ethernet eth3 description 'Configured by Ansible' + # - set interfaces ethernet eth3 mtu '1500' + # - set interfaces bonding bond1 + # - set interfaces bonding bond1 description 'Bond - 1' + # - set interfaces bonding bond1 mtu '1200' + # - set interfaces vti vti2 + # - set interfaces vti vti2 description 'VTI - 2' + # - set interfaces vti vti2 disable + # after: + # - description: Bond - 1 + # enabled: true + # mtu: 1200 + # name: bond1 + # - enabled: true + # name: lo + # - description: VTI - 2 + # enabled: false + # name: vti2 + # - description: Configured by Ansible + # enabled: true + # mtu: 1500 + # name: eth3 + # - description: Configured by Ansible + # enabled: true + # name: eth2 + # vifs: + # - description: VIF 200 - ETH2 + # enabled: true + # vlan_id: '200' + # - enabled: true + # name: eth1 + # - duplex: auto + # enabled: true + # name: eth0 + # speed: auto + # After state: - # ------------- - # - # vyos@vyos:~$ show configuration commands| grep firewall - # set firewall ipv6-name 'V6-LOCAL' - # set firewall name 'INBOUND' - # set firewall name 'LOCAL' - # set firewall name 'OUTBOUND' - # set interfaces ethernet eth1 firewall in name 'OUTBOUND' - # set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' - # set interfaces ethernet eth1 firewall local name 'LOCAL' - # set interfaces ethernet eth1 firewall out name 'INBOUND' - # set interfaces ethernet eth3 firewall in name 'INBOUND' - # set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' - # set interfaces ethernet eth3 firewall local name 'LOCAL' - # set interfaces ethernet eth3 firewall out name 'OUTBOUND' + # ------------ + # vyos@vyos:~$ show configuration commands | grep interfaces + # set interfaces bonding bond1 description 'Bond - 1' + # set interfaces bonding bond1 mtu '1200' + # set interfaces ethernet eth0 address 'dhcp' + # set interfaces ethernet eth0 address 'dhcpv6' + # set interfaces ethernet eth0 duplex 'auto' + # set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' + # set interfaces ethernet eth0 smp-affinity 'auto' + # set interfaces ethernet eth0 speed 'auto' + # set interfaces ethernet eth1 hw-id '08:00:27:ea:0f:b9' + # set interfaces ethernet eth1 smp-affinity 'auto' + # set interfaces ethernet eth2 description 'Configured by Ansible' + # set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' + # set interfaces ethernet eth2 smp-affinity 'auto' + # set interfaces ethernet eth2 vif 200 description 'VIF 200 - ETH2' + # set interfaces ethernet eth3 description 'Configured by Ansible' + # set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' + # set interfaces ethernet eth3 mtu '1500' + # set interfaces loopback lo + # set interfaces vti vti2 description 'VTI - 2' + # set interfaces vti vti2 disable # Using replaced @@ -626,7 +547,6 @@ Examples - name: INBOUND direction: in state: replaced - # # # ------------------------- @@ -857,7 +777,7 @@ Examples # "delete interfaces ethernet eth1 firewall", # "delete interfaces ethernet eth3 firewall in name", # "set interfaces ethernet eth3 firewall out name 'INBOUND'" - # + # ] # # "after": [ # { @@ -1005,20 +925,7 @@ Examples # "delete interfaces ethernet eth3 firewall" # ] # - # "after": [ - # { - # "name": "eth0" - # }, - # { - # "name": "eth1" - # }, - # { - # "name": "eth2" - # }, - # { - # "name": "eth3" - # } - # ] + # "after" : [] # After state # ------------ # vyos@vyos# run show configuration commands | grep firewall @@ -1076,6 +983,7 @@ Examples # set firewall name 'LOCAL' # set firewall name 'OUTBOUND' + # Using deleted without config # # Before state @@ -1098,6 +1006,13 @@ Examples - name: Delete firewall interfaces config when empty config provided. vyos.vyos.vyos_firewall_interfaces: state: deleted + # After state + # ------------ + # vyos@vyos# run show configuration commands | grep firewall + # set firewall ipv6-name 'V6-LOCAL' + # set firewall name 'INBOUND' + # set firewall name 'LOCAL' + # set firewall name 'OUTBOUND' # # # ------------------------ @@ -1109,17 +1024,11 @@ Examples # "delete interfaces ethernet eth1 firewall" # ] # - # After state - # ------------ - # vyos@vyos# run show configuration commands | grep firewall - # set firewall ipv6-name 'V6-LOCAL' - # set firewall name 'INBOUND' - # set firewall name 'LOCAL' - # set firewall name 'OUTBOUND' # Using parsed # + # - name: Parse the provided configuration vyos.vyos.vyos_firewall_interfaces: running_config: @@ -1310,14 +1219,13 @@ Examples access_rules: - afi: ipv4 rules: - - direction: in - name: INGRESS - - direction: out - name: OUTGRESS - - direction: local - name: DROP + - name: INGRESS + direction: in + - name: OUTGRESS + direction: out + - name: DROP + direction: local state: rendered - # # # ------------------------- @@ -1352,16 +1260,15 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late <b>after</b> <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a> <div style="font-size: small"> - <span style="color: purple">list</span> + <span style="color: purple">dictionary</span> </div> </td> <td>when changed</td> <td> - <div>The resulting configuration model invocation.</div> + <div>The resulting configuration after module execution.</div> <br/> <div style="font-size: smaller"><b>Sample:</b></div> - <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">The configuration returned will always be in the same format - of the parameters above.</div> + <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div> </td> </tr> <tr> @@ -1370,16 +1277,15 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late <b>before</b> <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a> <div style="font-size: small"> - <span style="color: purple">list</span> + <span style="color: purple">dictionary</span> </div> </td> - <td>always</td> + <td>when <em>state</em> is <code>merged</code>, <code>replaced</code>, <code>overridden</code>, <code>deleted</code> or <code>purged</code></td> <td> - <div>The configuration prior to the model invocation.</div> + <div>The configuration prior to the module execution.</div> <br/> <div style="font-size: smaller"><b>Sample:</b></div> - <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">The configuration returned will always be in the same format - of the parameters above.</div> + <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div> </td> </tr> <tr> @@ -1399,6 +1305,57 @@ Common return values are documented `here <https://docs.ansible.com/ansible/late <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">["set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'", "set interfaces ethernet eth3 firewall in name 'INBOUND'"]</div> </td> </tr> + <tr> + <td colspan="1"> + <div class="ansibleOptionAnchor" id="return-"></div> + <b>gathered</b> + <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a> + <div style="font-size: small"> + <span style="color: purple">list</span> + </div> + </td> + <td>when <em>state</em> is <code>gathered</code></td> + <td> + <div>Facts about the network resource gathered from the remote device as structured data.</div> + <br/> + <div style="font-size: smaller"><b>Sample:</b></div> + <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div> + </td> + </tr> + <tr> + <td colspan="1"> + <div class="ansibleOptionAnchor" id="return-"></div> + <b>parsed</b> + <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a> + <div style="font-size: small"> + <span style="color: purple">list</span> + </div> + </td> + <td>when <em>state</em> is <code>parsed</code></td> + <td> + <div>The device native config provided in <em>running_config</em> option parsed into structured data as per module argspec.</div> + <br/> + <div style="font-size: smaller"><b>Sample:</b></div> + <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">This output will always be in the same format as the module argspec.</div> + </td> + </tr> + <tr> + <td colspan="1"> + <div class="ansibleOptionAnchor" id="return-"></div> + <b>rendered</b> + <a class="ansibleOptionLink" href="#return-" title="Permalink to this return value"></a> + <div style="font-size: small"> + <span style="color: purple">list</span> + </div> + </td> + <td>when <em>state</em> is <code>rendered</code></td> + <td> + <div>The provided configuration in the task rendered in device-native format (offline).</div> + <br/> + <div style="font-size: smaller"><b>Sample:</b></div> + <div style="font-size: smaller; color: blue; word-wrap: break-word; word-break: break-all;">["set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'", "set interfaces ethernet eth3 firewall in name 'INBOUND'"]</div> + </td> + </tr> </table> <br/><br/> diff --git a/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py b/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py index a613ccd..93c898e 100644 --- a/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py +++ b/plugins/module_utils/network/vyos/argspec/firewall_interfaces/firewall_interfaces.py @@ -25,6 +25,7 @@ The arg spec for the vyos_firewall_interfaces module """ + from __future__ import absolute_import, division, print_function @@ -45,7 +46,10 @@ class Firewall_interfacesArgs(object): # pylint: disable=R0903 "elements": "dict", "options": { "afi": { - "choices": ["ipv4", "ipv6"], + "choices": [ + "ipv4", + "ipv6", + ], "required": True, "type": "str", }, @@ -53,7 +57,11 @@ class Firewall_interfacesArgs(object): # pylint: disable=R0903 "elements": "dict", "options": { "direction": { - "choices": ["in", "local", "out"], + "choices": [ + "in", + "local", + "out", + ], "required": True, "type": "str", }, diff --git a/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py b/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py index 5c4db73..85a8042 100644 --- a/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py +++ b/plugins/module_utils/network/vyos/config/firewall_interfaces/firewall_interfaces.py @@ -27,6 +27,9 @@ from ansible_collections.ansible.netcommon.plugins.module_utils.network.common.u ) from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.facts.facts import Facts +from ansible_collections.vyos.vyos.plugins.module_utils.network.vyos.utils.utils import ( + get_interface_type, +) class Firewall_interfaces(ConfigBase): @@ -393,10 +396,24 @@ class Firewall_interfaces(ConfigBase): :param opr: operation flag. :return: generated command. """ + + # Append vif if interface contains a dot + vlan = None + interface_real = name + if "." in name: + interface_real, vlan = name.split(".") + + if vlan is not None: + interface_real = interface_real + " vif " + vlan + + # if interface name is bondX, then it's a bonding interface. Everything else is an ethernet + iftype = get_interface_type(interface_real) + if not opr: - cmd = "delete interfaces ethernet" + " " + name + " firewall" + cmd = "delete interfaces " + iftype + " " + interface_real + " firewall" else: - cmd = "set interfaces ethernet" + " " + name + " firewall" + cmd = "set interfaces " + iftype + " " + interface_real + " firewall" + if attrib: cmd += " " + attrib if afi: diff --git a/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py b/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py index b980469..bac3192 100644 --- a/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py +++ b/plugins/module_utils/network/vyos/facts/firewall_interfaces/firewall_interfaces.py @@ -58,7 +58,10 @@ class Firewall_interfacesFacts(object): # using mock data instead data = self.get_device_data(connection) objs = [] - interfaces = findall(r"^set interfaces ethernet (?:\'*)(\S+)(?:\'*)", data, M) + # Search all set from configuration with set interface, including ethernet and bonding + interfaces_raw = findall(r"^set interfaces \S+ (\S+) firewall (?:\'*)", data, M) + interfaces_vif = findall(r"^set interfaces \S+ (\S+) vif (\d+)* firewall (?:\'*)", data, M) + interfaces = interfaces_raw + interfaces_vif if interfaces: objs = self.get_names(data, interfaces) ansible_facts["ansible_network_resources"].pop("firewall_interfaces", None) @@ -83,10 +86,22 @@ class Firewall_interfacesFacts(object): """ names = [] for r in set(interfaces): - int_regex = r" %s .+$" % r.strip("'") - cfg = findall(int_regex, data, M) - fi = self.render_config(cfg) - fi["name"] = r.strip("'") + myvif = None + if isinstance(r, tuple): + myinterface, myvif = r + else: + myinterface = r + # Parse interfaces that contains string or tuple when the interface is in a vlan + if myvif is not None: + int_regex = r" %s vif \d+ firewall .+$" % myinterface + cfg = findall(int_regex, data, M) + fi = self.render_config(cfg) + fi["name"] = myinterface + "." + myvif + else: + int_regex = r" %s firewall .+$" % myinterface + cfg = findall(int_regex, data, M) + fi = self.render_config(cfg) + fi["name"] = myinterface names.append(fi) if names: names = sorted(names, key=lambda i: i["name"]) diff --git a/plugins/modules/vyos_firewall_interfaces.py b/plugins/modules/vyos_firewall_interfaces.py index 11f3e52..2feabe4 100644 --- a/plugins/modules/vyos_firewall_interfaces.py +++ b/plugins/modules/vyos_firewall_interfaces.py @@ -31,14 +31,24 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type +ANSIBLE_METADATA = { + "metadata_version": "1.1", + "status": ["preview"], + "supported_by": "network", +} DOCUMENTATION = """ +--- module: vyos_firewall_interfaces -short_description: FIREWALL interfaces resource module -description: Manage firewall rules of interfaces on VyOS network devices. -version_added: 1.0.0 +version_added: '2.10.0' +short_description: Manage firewall rules attributes of interfaces on VyOS devices +description: Manage firewall rules of interfaces on VyOS network devices. (1.3-) author: - Rohit Thakur (@rohitthakur2590) +notes: +- Deprecated in VyOS 1.4+, firewalls are no longer connected directly to interfaces. + See the Firewall Configuration documentation for how to establish a + connection betwen the firewall rulesets and the flow, interface, or zone. options: config: description: A list of firewall rules options for interfaces. @@ -107,7 +117,6 @@ options: - rendered - gathered default: merged - """ EXAMPLES = """ # Using merged @@ -275,206 +284,121 @@ EXAMPLES = """ # Using merged -# + # Before state: # ------------- -# -# vyos@vyos:~$ show configuration commands| grep firewall -# set firewall ipv6-name 'V6-LOCAL' -# set firewall name 'INBOUND' -# set firewall name 'LOCAL' -# set firewall name 'OUTBOUND' -# set interfaces ethernet eth1 firewall in name 'INBOUND' -# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' -# set interfaces ethernet eth1 firewall local name 'LOCAL' -# set interfaces ethernet eth1 firewall out name 'OUTBOUND' -# set interfaces ethernet eth3 firewall in name 'INBOUND' -# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' -# set interfaces ethernet eth3 firewall local name 'LOCAL' -# set interfaces ethernet eth3 firewall out name 'OUTBOUND' -# -- name: Merge the provided configuration with the existing running configuration - vyos.vyos.vyos_firewall_interfaces: +# vyos@vyos:~$ show configuration commands | grep interfaces +# set interfaces bonding 'bond0' +# set interfaces bonding 'bond1' +# set interfaces bonding bond2 'ip' +# set interfaces bonding bond2 'ipv6' +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 'ip' +# set interfaces ethernet eth0 'ipv6' +# set interfaces ethernet eth0 smp_affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet 'eth1' +# set interfaces ethernet 'eth2' + +- name: Merge provided configuration with device configuration + vyos.vyos.vyos_interfaces: config: - - access_rules: - - afi: ipv4 - rules: - - name: OUTBOUND - direction: in - - name: INBOUND - direction: out - name: eth1 + - name: eth2 + description: Configured by Ansible + enabled: true + vifs: + - vlan_id: 200 + description: VIF 200 - ETH2 + - name: eth3 + description: Configured by Ansible + mtu: 1500 + - name: bond1 + description: Bond - 1 + mtu: 1200 + - name: vti2 + description: VTI - 2 + enabled: false state: merged -# -# -# ------------------------- -# Module Execution Result -# ------------------------- -# -# "before": [ -# { -# "name": "eth0" -# }, -# { -# "access_rules": [ -# { -# "afi": "ipv4", -# "rules": [ -# { -# "direction": "in", -# "name": "INBOUND" -# }, -# { -# "direction": "local", -# "name": "LOCAL" -# }, -# { -# "direction": "out", -# "name": "OUTBOUND" -# } -# ] -# }, -# { -# "afi": "ipv6", -# "rules": [ -# { -# "direction": "local", -# "name": "V6-LOCAL" -# } -# ] -# } -# ], -# "name": "eth1" -# }, -# { -# "name": "eth2" -# }, -# { -# "access_rules": [ -# { -# "afi": "ipv4", -# "rules": [ -# { -# "direction": "in", -# "name": "INBOUND" -# }, -# { -# "direction": "local", -# "name": "LOCAL" -# }, -# { -# "direction": "out", -# "name": "OUTBOUND" -# } -# ] -# }, -# { -# "afi": "ipv6", -# "rules": [ -# { -# "direction": "local", -# "name": "V6-LOCAL" -# } -# ] -# } -# ], -# "name": "eth3" -# } -# ] -# -# "commands": [ -# "set interfaces ethernet eth1 firewall in name 'OUTBOUND'", -# "set interfaces ethernet eth1 firewall out name 'INBOUND'" -# ] -# -# "after": [ -# { -# "name": "eth0" -# }, -# { -# "access_rules": [ -# { -# "afi": "ipv4", -# "rules": [ -# { -# "direction": "in", -# "name": "OUTBOUND" -# }, -# { -# "direction": "local", -# "name": "LOCAL" -# }, -# { -# "direction": "out", -# "name": "INBOUND" -# } -# ] -# }, -# { -# "afi": "ipv6", -# "rules": [ -# { -# "direction": "local", -# "name": "V6-LOCAL" -# } -# ] -# } -# ], -# "name": "eth1" -# }, -# { -# "name": "eth2" -# }, -# { -# "access_rules": [ -# { -# "afi": "ipv4", -# "rules": [ -# { -# "direction": "in", -# "name": "INBOUND" -# }, -# { -# "direction": "local", -# "name": "LOCAL" -# }, -# { -# "direction": "out", -# "name": "OUTBOUND" -# } -# ] -# }, -# { -# "afi": "ipv6", -# "rules": [ -# { -# "direction": "local", -# "name": "V6-LOCAL" -# } -# ] -# } -# ], -# "name": "eth3" -# } -# ] -# +# Task Output +# ----------- +# before: +# - enabled: true +# name: lo +# - enabled: true +# name: eth3 +# - enabled: true +# name: eth2 +# - enabled: true +# name: eth1 +# - duplex: auto +# enabled: true +# name: eth0 +# speed: auto +# commands: +# - set interfaces ethernet eth2 description 'Configured by Ansible' +# - set interfaces ethernet eth2 vif 200 +# - set interfaces ethernet eth2 vif 200 description 'VIF 200 - ETH2' +# - set interfaces ethernet eth3 description 'Configured by Ansible' +# - set interfaces ethernet eth3 mtu '1500' +# - set interfaces bonding bond1 +# - set interfaces bonding bond1 description 'Bond - 1' +# - set interfaces bonding bond1 mtu '1200' +# - set interfaces vti vti2 +# - set interfaces vti vti2 description 'VTI - 2' +# - set interfaces vti vti2 disable +# after: +# - description: Bond - 1 +# enabled: true +# mtu: 1200 +# name: bond1 +# - enabled: true +# name: lo +# - description: VTI - 2 +# enabled: false +# name: vti2 +# - description: Configured by Ansible +# enabled: true +# mtu: 1500 +# name: eth3 +# - description: Configured by Ansible +# enabled: true +# name: eth2 +# vifs: +# - description: VIF 200 - ETH2 +# enabled: true +# vlan_id: '200' +# - enabled: true +# name: eth1 +# - duplex: auto +# enabled: true +# name: eth0 +# speed: auto + # After state: -# ------------- -# -# vyos@vyos:~$ show configuration commands| grep firewall -# set firewall ipv6-name 'V6-LOCAL' -# set firewall name 'INBOUND' -# set firewall name 'LOCAL' -# set firewall name 'OUTBOUND' -# set interfaces ethernet eth1 firewall in name 'OUTBOUND' -# set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL' -# set interfaces ethernet eth1 firewall local name 'LOCAL' -# set interfaces ethernet eth1 firewall out name 'INBOUND' -# set interfaces ethernet eth3 firewall in name 'INBOUND' -# set interfaces ethernet eth3 firewall local ipv6-name 'V6-LOCAL' -# set interfaces ethernet eth3 firewall local name 'LOCAL' -# set interfaces ethernet eth3 firewall out name 'OUTBOUND' +# ------------ +# vyos@vyos:~$ show configuration commands | grep interfaces +# set interfaces bonding bond1 description 'Bond - 1' +# set interfaces bonding bond1 mtu '1200' +# set interfaces ethernet eth0 address 'dhcp' +# set interfaces ethernet eth0 address 'dhcpv6' +# set interfaces ethernet eth0 duplex 'auto' +# set interfaces ethernet eth0 hw-id '08:00:27:30:f0:22' +# set interfaces ethernet eth0 smp-affinity 'auto' +# set interfaces ethernet eth0 speed 'auto' +# set interfaces ethernet eth1 hw-id '08:00:27:ea:0f:b9' +# set interfaces ethernet eth1 smp-affinity 'auto' +# set interfaces ethernet eth2 description 'Configured by Ansible' +# set interfaces ethernet eth2 hw-id '08:00:27:c2:98:23' +# set interfaces ethernet eth2 smp-affinity 'auto' +# set interfaces ethernet eth2 vif 200 description 'VIF 200 - ETH2' +# set interfaces ethernet eth3 description 'Configured by Ansible' +# set interfaces ethernet eth3 hw-id '08:00:27:43:70:8c' +# set interfaces ethernet eth3 mtu '1500' +# set interfaces loopback lo +# set interfaces vti vti2 description 'VTI - 2' +# set interfaces vti vti2 disable # Using replaced @@ -518,7 +442,6 @@ EXAMPLES = """ - name: INBOUND direction: in state: replaced - # # # ------------------------- @@ -749,7 +672,7 @@ EXAMPLES = """ # "delete interfaces ethernet eth1 firewall", # "delete interfaces ethernet eth3 firewall in name", # "set interfaces ethernet eth3 firewall out name 'INBOUND'" -# +# ] # # "after": [ # { @@ -897,20 +820,7 @@ EXAMPLES = """ # "delete interfaces ethernet eth3 firewall" # ] # -# "after": [ -# { -# "name": "eth0" -# }, -# { -# "name": "eth1" -# }, -# { -# "name": "eth2" -# }, -# { -# "name": "eth3" -# } -# ] +# "after" : [] # After state # ------------ # vyos@vyos# run show configuration commands | grep firewall @@ -968,6 +878,7 @@ EXAMPLES = """ # set firewall name 'LOCAL' # set firewall name 'OUTBOUND' + # Using deleted without config # # Before state @@ -990,6 +901,13 @@ EXAMPLES = """ - name: Delete firewall interfaces config when empty config provided. vyos.vyos.vyos_firewall_interfaces: state: deleted +# After state +# ------------ +# vyos@vyos# run show configuration commands | grep firewall +# set firewall ipv6-name 'V6-LOCAL' +# set firewall name 'INBOUND' +# set firewall name 'LOCAL' +# set firewall name 'OUTBOUND' # # # ------------------------ @@ -1001,17 +919,11 @@ EXAMPLES = """ # "delete interfaces ethernet eth1 firewall" # ] # -# After state -# ------------ -# vyos@vyos# run show configuration commands | grep firewall -# set firewall ipv6-name 'V6-LOCAL' -# set firewall name 'INBOUND' -# set firewall name 'LOCAL' -# set firewall name 'OUTBOUND' # Using parsed # +# - name: Parse the provided configuration vyos.vyos.vyos_firewall_interfaces: running_config: @@ -1202,14 +1114,13 @@ EXAMPLES = """ access_rules: - afi: ipv4 rules: - - direction: in - name: INGRESS - - direction: out - name: OUTGRESS - - direction: local - name: DROP + - name: INGRESS + direction: in + - name: OUTGRESS + direction: out + - name: DROP + direction: local state: rendered - # # # ------------------------- @@ -1226,19 +1137,19 @@ EXAMPLES = """ """ RETURN = """ before: - description: The configuration prior to the model invocation. - returned: always - type: list + 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: > - The configuration returned will always be in the same format - of the parameters above. + This output will always be in the same format as the + module argspec. after: - description: The resulting configuration model invocation. + description: The resulting configuration after module execution. returned: when changed - type: list + type: dict sample: > - The configuration returned will always be in the same format - of the parameters above. + 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: always @@ -1246,6 +1157,28 @@ commands: sample: - "set interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'" - "set interfaces ethernet eth3 firewall in name 'INBOUND'" +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 interfaces ethernet eth1 firewall local ipv6-name 'V6-LOCAL'" + - "set interfaces ethernet eth3 firewall in name 'INBOUND'" +gathered: + description: Facts about the network resource gathered from the remote device as structured data. + returned: when I(state) is C(gathered) + type: list + sample: > + This output will always be in the same format as the + module argspec. +parsed: + description: The device native config provided in I(running_config) option parsed into structured data as per module argspec. + returned: when I(state) is C(parsed) + type: list + sample: > + This output will always be in the same format as the + module argspec. + """ @@ -1268,6 +1201,7 @@ def main(): required_if = [ ("state", "merged", ("config",)), ("state", "replaced", ("config",)), + ("state", "rendered", ("config",)), ("state", "overridden", ("config",)), ("state", "parsed", ("running_config",)), ] diff --git a/tests/unit/modules/network/vyos/test_vyos_firewall_interfaces.py b/tests/unit/modules/network/vyos/test_vyos_firewall_interfaces.py index 3034d58..f921c50 100644 --- a/tests/unit/modules/network/vyos/test_vyos_firewall_interfaces.py +++ b/tests/unit/modules/network/vyos/test_vyos_firewall_interfaces.py @@ -388,3 +388,68 @@ class TestVyosFirewallInterfacesModule(TestVyosModule): ), ) self.execute_module(changed=False, commands=[]) + + def test_vyos_firewall_rule_set_02_replaced(self): + set_module_args( + dict( + config=[ + dict( + name="eth0.100", + access_rules=[ + dict( + afi="ipv4", + rules=[dict(name="INBOUND", direction="in")], + ), + dict( + afi="ipv6", + rules=[dict(name="V6-LOCAL", direction="local")], + ), + ], + ), + dict( + name="bond2", + access_rules=[ + dict( + afi="ipv4", + rules=[dict(name="LOCAL", direction="local")], + ), + dict( + afi="ipv6", + rules=[dict(name="V6-LOCAL", direction="local")], + ), + ], + ), + dict( + name="wg4", + access_rules=[ + dict( + afi="ipv4", + rules=[dict(name="LOCAL", direction="local")], + ), + dict( + afi="ipv6", + rules=[dict(name="V6-LOCAL", direction="local")], + ), + ], + ), + ], + state="replaced", + ), + ) + commands = [ + 'delete interfaces ethernet eth0 firewall in name', + 'delete interfaces ethernet eth0 firewall local name', + 'delete interfaces ethernet eth0 firewall out name', + 'delete interfaces ethernet eth0 firewall local ipv6-name', + 'delete interfaces ethernet eth2 firewall in name', + 'delete interfaces ethernet eth2 firewall local name', + 'delete interfaces ethernet eth2 firewall out name', + 'delete interfaces ethernet eth2 firewall local ipv6-name', + "set interfaces ethernet eth0 vif 100 firewall in name 'INBOUND'", + "set interfaces ethernet eth0 vif 100 firewall local ipv6-name 'V6-LOCAL'", + "set interfaces bonding bond2 firewall local name 'LOCAL'", + "set interfaces bonding bond2 firewall local ipv6-name 'V6-LOCAL'", + "set interfaces wireguard wg4 firewall local name 'LOCAL'", + "set interfaces wireguard wg4 firewall local ipv6-name 'V6-LOCAL'" + ] + self.execute_module(changed=True, commands=commands) |