Skip to content

T8220: Firewall Zone Policy support#447

Open
omnom62 wants to merge 24 commits intovyos:mainfrom
omnom62:t8220_fzp
Open

T8220: Firewall Zone Policy support#447
omnom62 wants to merge 24 commits intovyos:mainfrom
omnom62:t8220_fzp

Conversation

@omnom62
Copy link
Copy Markdown
Contributor

@omnom62 omnom62 commented Feb 10, 2026

Change Summary

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Code style update (formatting, renaming)
  • Refactoring (no functional changes)
  • Migration from an old Vyatta component to vyos-1x, please link to related PR inside obsoleted component
  • Other (please describe):

Related Task(s)

https://vyos.dev/T8220

Related PR(s)

Component(s) name

vyos_firewall_global

Proposed changes

VyOS Ansible module that implements Firewall Zone Policy.

Provide new functionality in the VyOS Ansible module that VyOS doesn't currently support. Our module distinguishes between group name and zone name, but does not set the latter.

How to test

Test results

Unit tests are successful:
`============================= test session starts ==============================
platform linux -- Python 3.13.0, pytest-8.3.3, pluggy-1.5.0 -- /usr/bin/python3.13
rootdir: /root/ansible_collections/vyos/vyos
configfile: ../../../ansible/test/lib/ansible_test/_data/pytest/config/default.ini
plugins: xdist-3.6.1, mock-3.14.0
created: 8/8 workers
8 workers [6 items]

scheduling tests via LoadScheduling

tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_deleted
tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_merged
tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_replaced_idem
tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_replaced
tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_02_replaced
tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_merged_idem
[gw2] [ 16%] PASSED tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_merged_idem
[gw0] [ 33%] PASSED tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_deleted
[gw3] [ 50%] PASSED tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_replaced
[gw1] [ 66%] PASSED tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_merged
[gw5] [ 83%] PASSED tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_02_replaced
[gw4] [100%] PASSED tests/unit/modules/network/vyos/test_vyos_firewall_global.py::TestVyosFirewallGlobalModule::test_vyos_firewall_global_set_01_replaced_idem

  • generated xml file: /root/ansible_collections/vyos/vyos/tests/output/junit/python3.13-controller-units.xml -
    ============================== 6 passed in 2.36s ===============================
    `
  • Sanity tests passed
  • Unit tests passed

Tested against VyOS versions:

  • 1.5q2

Checklist:

  • I have read the CONTRIBUTING document
  • I have linked this PR to one or more Phabricator Task(s)
  • I have run the ansible sanity and unit tests
  • My commit headlines contain a valid Task id
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have added unit tests to cover my changes
  • I have added a file to changelogs/fragments to describe the changes

@omnom62 omnom62 requested a review from a team as a code owner February 10, 2026 12:40
@omnom62 omnom62 marked this pull request as draft February 10, 2026 12:41
@omnom62 omnom62 changed the title WIP T8220 Firewall Zone Policy support T8220 Firewall Zone Policy support Feb 24, 2026
@omnom62 omnom62 marked this pull request as ready for review February 24, 2026 11:59
@sever-sever sever-sever changed the title T8220 Firewall Zone Policy support T8220: Firewall Zone Policy support Feb 25, 2026
@gaige
Copy link
Copy Markdown
Contributor

gaige commented Mar 8, 2026

The PR here is pretty devoid of information, can you fix that?

@omnom62
Copy link
Copy Markdown
Contributor Author

omnom62 commented Mar 9, 2026

The PR here is pretty devoid of information, can you fix that?

The PR here is pretty devoid of information, can you fix that?

@gaige - I tried and added more information - please check

Copy link
Copy Markdown
Contributor

@gaige gaige left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. A couple of small changes (removal of commented out code).

:rtype: dictionary
:returns: The generated config
"""
# conf = "\n".join(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ready for removal?

set firewall global-options state-policy established action 'accept'
set firewall global-options state-policy established log 'enable'
set firewall global-options state-policy invalid action 'reject'
# set firewall global-options state-policy invalid acti. .on 'reject'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we delete this?

Copilot AI review requested due to automatic review settings April 17, 2026 12:02
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Firewall Zone Policy (“zone” / zone-based firewall) support to the vyos_firewall_global resource module, including parsing facts, rendering CLI commands, and extending unit/integration fixtures and documentation.

Changes:

  • Extend module argspec + documentation to accept config.zone definitions (interfaces, default action/log, intra-zone filtering, sources).
  • Add config rendering and facts parsing support for set firewall zone ... statements.
  • Update unit/integration tests + changelog fragment to cover the new behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
plugins/modules/vyos_firewall_global.py Exposes zone option in module DOCUMENTATION.
plugins/module_utils/network/vyos/argspec/firewall_global/firewall_global.py Adds zone structure to the argspec.
plugins/module_utils/network/vyos/config/firewall_global/firewall_global.py Renders CLI commands for zone configuration (set/delete/replace paths).
plugins/module_utils/network/vyos/facts/firewall_global/firewall_global.py Parses set firewall zone ... lines into facts.
tests/unit/modules/network/vyos/test_vyos_firewall_global14.py Adds/updates unit expectations for zone-related commands.
tests/integration/targets/vyos_firewall_global/vars/main.yaml Adds zone config to integration test input data.
tests/integration/targets/vyos_firewall_global/vars/v1_4.yaml Updates expected command lists for v1.4 integration runs.
tests/integration/targets/vyos_firewall_global/tests/cli/_parsed_config_1_4.cfg Updates parsed-config fixture with zone commands (currently contains invalid lines).
docs/vyos.vyos.vyos_firewall_global_module.rst Updates published module docs to include zone options.
changelogs/fragments/t882-fpz.yaml Adds changelog fragment announcing firewall zone support.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

want,
"name",
):
commands.append(cmd + " D-" + want["name"] + " " + key)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the delete/render phase (opr=False), this branch builds a command with a literal D- prefix and uses the raw key name (e.g. default_action) instead of the CLI token (default-action). This will generate invalid VyOS CLI (e.g. delete firewall zone D-<name> default_action). Please generate proper delete commands using the zone name + mapped CLI attribute (hyphenated), without the D- prefix, and ensure booleans vs valued attributes are handled correctly.

Suggested change
commands.append(cmd + " D-" + want["name"] + " " + key)
cli_attr = key.replace("_", "-")
if isinstance(val, bool):
commands.append(
cmd + " " + want["name"] + " " + cli_attr,
)
else:
commands.append(
cmd + " " + want["name"] + " " + cli_attr,
)

Copilot uses AI. Check for mistakes.
)
elif not opr and not have:
commands.append(
cmd + " " + name + " intra-zone-filtering " + attr,
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When deleting intra_zone_filtering (e.g. in state=replaced where the target zone removes this block), the not opr and not have branch appends ... intra-zone-filtering intra_zone_filtering, which is not a valid path. This should delete the intra-zone-filtering node (or the specific leaf keys) using the correct CLI syntax, not the Python attribute name.

Suggested change
cmd + " " + name + " intra-zone-filtering " + attr,
cmd + " " + name + " intra-zone-filtering",

Copilot uses AI. Check for mistakes.
Comment on lines +1072 to +1116
for item1 in want:
zone = item1["zone"]

if zone in have_index:
item2 = have_index[zone]

wfw = item1.get("firewall", {})
hfw = item2.get("firewall", {})
if wfw:
if opr:
sources = self._dict_diff(wfw, hfw)
for source in sources:
commands.append(
cmd
+ " "
+ name
+ " from "
+ zone
+ " firewall "
+ source[0].replace("_", "-")
+ " "
+ source[1],
)
elif not opr and hfw:
sources = self._dict_diff(wfw, hfw)
for source in sources:
commands.append(
cmd
+ " "
+ name
+ " from "
+ zone
+ " firewall "
+ source[0].replace("_", "-")
+ " "
+ source[1],
)
elif not opr and not have:
sources = self._dict_diff(wfw, hfw)
for source in sources:
commands.append(
cmd + " " + name + " from " + zone,
)
elif opr:
wfw = item1.get("firewall", {})
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_render_sources() never generates delete commands for sources that exist in want but are absent from have when opr=False (e.g. removing a from <zone> entry during state=replaced). The elif opr: guard means removed sources are silently left behind. Add an elif not opr: path for zone not in have_index to delete the entire from <zone> subtree (or relevant leaves) so replace/delete operations are correct.

Copilot uses AI. Check for mistakes.
Comment on lines +80 to 94
# conf = "\n".join(
# filter(
# lambda x: ("firewall ipv6-name" and "firewall name" not in x),
# conf,
# ),
# )

conf = "\n".join(
filter(
lambda x: ("firewall ipv6-name" and "firewall name" not in x),
lambda x: not (
x.startswith("set firewall ipv6 name") or x.startswith("set firewall ipv6 name")
),
conf,
),
)
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This filter predicate looks incorrect: it checks the same prefix twice and the prefix itself (set firewall ipv6 name) doesn’t match typical VyOS firewall commands. As written it effectively does nothing and leaves commented-out dead code above. Please either remove this filtering entirely (preferred if no longer needed) or fix it to match the actual lines that must be excluded, with a test that demonstrates the need.

Copilot uses AI. Check for mistakes.
Comment on lines +229 to +242
"sources": {
"elements": "dict",
"type": "list",
"options": {
"zone": {"type": "str"},
"firewall": {
"type": "dict",
"options": {
"name": {"type": "str"},
"ipv6_name": {"type": "str"},
},
},
},
},
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sources entries are assumed to always include a zone key (e.g. _render_sources() indexes item["zone"]). In the argspec it’s currently optional, which can lead to runtime KeyError rather than a validation error. Mark sources.options.zone as required: true (and consider doing the same for any other required subkeys used with direct indexing).

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +19
# set firewall global-options state-policy invalid acti. .on 'reject'
set firewall global-options syn-cookies 'enable'
set firewall global-options twa-hazards-protection 'enable'
set firewall global-options twa-hazards-protection 'enable'
Copy link

Copilot AI Apr 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parsed-config fixture now comments out the state-policy invalid action 'reject' line and introduces a typo (acti. .on), which will break parsing/round-trip expectations. It also duplicates the twa-hazards-protection command. Please restore the correct set firewall global-options state-policy invalid action 'reject' line (uncommented) and remove unintended duplicates so the fixture reflects valid device output.

Suggested change
# set firewall global-options state-policy invalid acti. .on 'reject'
set firewall global-options syn-cookies 'enable'
set firewall global-options twa-hazards-protection 'enable'
set firewall global-options twa-hazards-protection 'enable'
set firewall global-options state-policy invalid action 'reject'
set firewall global-options syn-cookies 'enable'
set firewall global-options twa-hazards-protection 'enable'

Copilot uses AI. Check for mistakes.
Comment thread changelogs/fragments/t882-fpz.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants