From: Stefan Hanreich <s.hanreich@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: Re: [PATCH pve-firewall 1/5] Add helpers for updating alias and ipset references
Date: Thu, 16 Jul 2026 15:17:09 +0200 [thread overview]
Message-ID: <c161fc57-1d8e-4340-9d2c-6621d1c39af8@proxmox.com> (raw)
In-Reply-To: <20260407073658.90818-2-a.bied-charreton@proxmox.com>
On 4/7/26 9:36 AM, Arthur Bied-Charreton wrote:
> Both ipsets and aliases require similar logic, where we need to
> be able to iterate over all firewall configs in the cluster (cluster,
> nodes and guests) to find and update all references to a given object.
>
> Add filter_map() and foreach_conf_in_env() as shared helpers that take
> closures, allowing the ipset and alias handlers to reuse some of the
> traversal logic.
>
> Signed-off-by: Arthur Bied-Charreton <a.bied-charreton@proxmox.com>
> ---
> src/PVE/API2/Firewall/Helpers.pm | 66 ++++++++++++++++++++++++++++++++
> 1 file changed, 66 insertions(+)
>
> diff --git a/src/PVE/API2/Firewall/Helpers.pm b/src/PVE/API2/Firewall/Helpers.pm
> index 0fb71f7..8a8759a 100644
> --- a/src/PVE/API2/Firewall/Helpers.pm
> +++ b/src/PVE/API2/Firewall/Helpers.pm
> @@ -4,8 +4,74 @@ use strict;
> use warnings;
>
> use PVE::Cluster;
> +use PVE::Firewall;
> use PVE::Network::SDN::Vnets;
> use PVE::RPCEnvironment;
> +use base 'Exporter';
> +our @EXPORT_OK = qw(filter_map foreach_conf_in_env);
> +
> +# Apply $action to each item in $items for which $matches->($item) is true. Remove item
> +# if $matches->($item) is true and $action->($item) returns undef.
> +#
> +# Returns the updated items arrayref and a boolean indicating whether any item was matched.
I've started to introduce the POD format for comments (e.g. in
src/PVE/Firewall/Helpers.pm) for new functions in the Firewall, so we
could utilize that here as well?
> +sub filter_map {
The name is imo a bit misleading, since the result still includes
everything that *doesn't* match, so there's not really any filtering
included. I, personally, would think from the name of this function that
it filters everything according to matches, and then maps it via
$action. I'd think of this more like a simple map operation rather, that
returns the item as-is if it doesn't fit a given criteria, otherwise
transforms it.
> + my ($items, $action, $matches) = @_;
> + my @result;
> + my $modified = 0;
> + for my $item (@{ $items // [] }) {
> + if ($matches->($item)) {
> + $modified = 1;
> + my $new = $action->($item);
> + push @result, $new if defined $new;
> + } else {
> + push @result, $item;
> + }
> + }
> + return (\@result, $modified);
> +}
> +
> +# Apply $rewrite to the main firewall config and, if $rule_env is 'cluster', to all guest
> +# and host firewall configs across the cluster. Configs where $rewrite returns true are saved.
> +# The caller is responsible for locking and saving the cluster config. Guest and host
> +# configs are locked by this function.
> +sub foreach_conf_in_env {
> + my ($conf, $rule_env, $rewrite) = @_;
> +
> + $rewrite->($conf, $rule_env, 0);
> +
> + return if $rule_env ne 'cluster';
> +
> + my $vmlist = PVE::Cluster::get_vmlist();
> + for my $vmid (keys %{ ($vmlist // {})->{ids} // {} }) {
> + PVE::Firewall::lock_vmfw_conf(
> + $vmid,
> + 10,
> + sub {
> + my $type = $vmlist->{ids}->{$vmid}->{type};
> + my $env = $type eq 'lxc' ? 'ct' : 'vm';
> + my $guest_conf = PVE::Firewall::load_vmfw_conf($conf, $env, $vmid);
> + if ($rewrite->($guest_conf, 'cluster', 1)) {
> + PVE::Firewall::save_vmfw_conf($vmid, $guest_conf);
> + }
> + },
> + );
> + }
> +
> + for my $node (@{ PVE::Cluster::get_nodelist() }) {
> + my $host_conf_path = "/etc/pve/nodes/$node/host.fw";
> + PVE::Firewall::lock_hostfw_conf(
> + $node,
> + 10,
> + sub {
> + my $host_conf = PVE::Firewall::load_hostfw_conf($conf, $host_conf_path);
> + return if !defined($host_conf);
> + if ($rewrite->($host_conf, 'cluster', 0)) {
> + PVE::Firewall::save_hostfw_conf($host_conf, $host_conf_path);
> + }
> + },
> + );
> + }
> +}
This is missing the VNet firewall configurations entirely, they do not
get updated as a consequence.
next prev parent reply other threads:[~2026-07-16 13:17 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-07 7:36 [PATCH firewall/manager 0/5] Allow updating references to firewall objects when editing them Arthur Bied-Charreton
2026-04-07 7:36 ` [PATCH pve-firewall 1/5] Add helpers for updating alias and ipset references Arthur Bied-Charreton
2026-07-16 13:17 ` Stefan Hanreich [this message]
2026-04-07 7:36 ` [PATCH pve-firewall 2/5] ipset: Add option to update references on rename/delete Arthur Bied-Charreton
2026-07-16 13:17 ` Stefan Hanreich
2026-04-07 7:36 ` [PATCH pve-firewall 3/5] aliases: " Arthur Bied-Charreton
2026-07-16 13:17 ` Stefan Hanreich
2026-04-07 7:36 ` [PATCH pve-manager 4/5] ipset: " Arthur Bied-Charreton
2026-04-07 7:36 ` [PATCH pve-manager 5/5] aliases: " Arthur Bied-Charreton
2026-07-16 13:17 ` [PATCH firewall/manager 0/5] Allow updating references to firewall objects when editing them Stefan Hanreich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c161fc57-1d8e-4340-9d2c-6621d1c39af8@proxmox.com \
--to=s.hanreich@proxmox.com \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.