From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH pve-network v2 13/27] sdn: dry-run: surface pending microseg changes
Date: Thu, 9 Jul 2026 11:18:38 +0200 [thread overview]
Message-ID: <20260709091852.538885-14-h.laimer@proxmox.com> (raw)
In-Reply-To: <20260709091852.538885-1-h.laimer@proxmox.com>
Microseg has no per-node generated file to diff, so the dry-run renders
a summary of the state (allocated identities, per-NIC memberships,
policies) for both the current and the pending config and returns their
diff. This is where changes with no .cfg edit behind them, like
assignment shifts caused by guest changes, become visible before an
apply.
Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
src/PVE/API2/Network/SDN.pm | 19 +++++++++++
src/PVE/Network/SDN/Microseg.pm | 60 +++++++++++++++++++++++++++++++++
2 files changed, 79 insertions(+)
diff --git a/src/PVE/API2/Network/SDN.pm b/src/PVE/API2/Network/SDN.pm
index 5a31e6f..5cee5a1 100644
--- a/src/PVE/API2/Network/SDN.pm
+++ b/src/PVE/API2/Network/SDN.pm
@@ -420,6 +420,13 @@ __PACKAGE__->register_method({
description =>
'The difference between the current and pending /etc/network/interfaces.d/sdn configuration.',
},
+ "microseg-diff" => {
+ type => 'string',
+ optional => 1,
+ description =>
+ 'The difference between the current and pending microsegmentation state'
+ . ' (allocated identities and realized per-NIC group membership).',
+ },
},
},
code => sub {
@@ -450,8 +457,20 @@ __PACKAGE__->register_method({
$return_value->{"interfaces-diff"} =
get_diff('/etc/network/interfaces.d/sdn', $interfaces_tmp_filename);
+ my $current_cfg = PVE::Network::SDN::running_config();
+ my $microseg_old = PVE::Network::SDN::Microseg::summary($current_cfg->{microseg});
+ my $microseg_new = PVE::Network::SDN::Microseg::summary($running_cfg->{microseg});
+ my ($microseg_old_filename, $microseg_old_fh) =
+ PVE::File::tempfile_contents($microseg_old, 700);
+ my ($microseg_new_filename, $microseg_new_fh) =
+ PVE::File::tempfile_contents($microseg_new, 700);
+ $return_value->{"microseg-diff"} =
+ get_diff($microseg_old_filename, $microseg_new_filename);
+
close($frr_tmp_fh);
close($interfaces_tmp_fh);
+ close($microseg_old_fh);
+ close($microseg_new_fh);
return $return_value;
},
});
diff --git a/src/PVE/Network/SDN/Microseg.pm b/src/PVE/Network/SDN/Microseg.pm
index 4f7398a..82ee52d 100644
--- a/src/PVE/Network/SDN/Microseg.pm
+++ b/src/PVE/Network/SDN/Microseg.pm
@@ -232,6 +232,66 @@ sub guest_inventory {
return $inventory;
}
+# A stable, human-readable summary of a rendered microseg block ({ ids, identities, realized }), for
+# the SDN dry-run diff.
+sub summary {
+ my ($mseg) = @_;
+
+ $mseg //= {};
+ my $ids = $mseg->{ids} // {};
+ my $identities = $mseg->{identities} // {};
+ my $realized = $mseg->{realized} // [];
+
+ my %mark2name;
+ for my $name (keys %$ids) {
+ my $object = $ids->{$name};
+ next if !$object || ($object->{type} // '') ne 'group';
+ $mark2name{ $object->{mark} } = $name if defined $object->{mark};
+ }
+ my $group_names = sub {
+ my ($marks) = @_;
+ return join(',', sort map { $mark2name{$_} // "mark$_" } @{ $marks // [] });
+ };
+
+ my @lines = ('identities:');
+ my $classes = $identities->{classes} // {};
+ for my $cid (sort { $a <=> $b } keys %$classes) {
+ push @lines, sprintf(' %s -> %s', $cid, $group_names->($classes->{$cid}));
+ }
+
+ push @lines, 'assignments:';
+ my @sorted = sort {
+ ($a->{vmid} // 0) <=> ($b->{vmid} // 0) || ($a->{iface} // 0) <=> ($b->{iface} // 0)
+ } @$realized;
+ for my $assignment (@sorted) {
+ push @lines,
+ sprintf(
+ ' vm%s net%s -> %s',
+ $assignment->{vmid} // '?',
+ $assignment->{iface} // '?',
+ join(',', sort @{ $assignment->{groups} // [] }),
+ );
+ }
+
+ push @lines, 'policies:';
+ my @rule_ids = sort grep { ($ids->{$_}->{type} // '') eq 'rule' } keys %$ids;
+ for my $rule_id (@rule_ids) {
+ my $rule = $ids->{$rule_id};
+ push @lines,
+ sprintf(
+ ' %s {%s} -> %s {%s}: %s prio %s',
+ $rule->{src_match} // 'any',
+ join(',', sort @{ $rule->{src} // [] }),
+ $rule->{dst_match} // 'any',
+ join(',', sort @{ $rule->{dst} // [] }),
+ ($rule->{allow} ? 'allow' : 'deny'),
+ $rule->{prio} // 0,
+ );
+ }
+
+ return join("\n", @lines) . "\n";
+}
+
# Shared CRUD helpers for the per-type API endpoints. Each takes the object's type, a single type
# string, or an arrayref of acceptable types for an endpoint that fronts a family of stored types
# (the assignment matcher kinds). The per-type modules only declare their schema and delegate here.
--
2.47.3
next prev parent reply other threads:[~2026-07-09 9:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-09 9:18 SPAM: [RFC cluster/docs/ifupdown2/manager/network/proxmox{-ve-rs,-ebpf,-perl-rs} v2 00/27] sdn: add microsegmentation support Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ve-rs v2 01/27] ve-config: sdn: add microseg signature-identity engine Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ve-rs v2 02/27] ve-config: sdn: add microseg config types Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ve-rs v2 03/27] ve-config: sdn: microseg: add tag matcher Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ve-rs v2 04/27] ve-config: sdn: microseg: add name regex matcher Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ve-rs v2 05/27] ve-config: sdn: microseg: add carrier bridge section Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ebpf v2 06/27] agent: add userspace coordinator and stateless policy subsystem Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ebpf v2 07/27] bpf: add bridge subsystem Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-ebpf v2 08/27] debian: add packaging and boot-time oneshot unit Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-cluster v2 09/27] cfs: add 'sdn/microseg.cfg' to observed files Hannes Laimer
2026-07-09 9:18 ` [PATCH proxmox-perl-rs v2 10/27] pve-rs: sdn: add microseg config binding Hannes Laimer
2026-07-09 9:18 ` [PATCH ifupdown2 v2 11/27] d/patches: add support for VXLAN-GBP flag Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-network v2 12/27] sdn: microseg: add config, API and guest inventory Hannes Laimer
2026-07-09 9:18 ` Hannes Laimer [this message]
2026-07-09 9:18 ` [PATCH pve-network v2 14/27] sdn: zones: trigger microseg apply on tap_plug Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-network v2 15/27] sdn: zones: add vxlan-gbp option to vxlan and evpn zones Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-network v2 16/27] evpn: disable vxlan-learning on create if GBP is enabled Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-network v2 17/27] sdn: microseg: add tag matcher Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-network v2 18/27] sdn: microseg: add name regex matcher Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-network v2 19/27] sdn: microseg: add carrier bridge API Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-manager v2 20/27] ui: sdn: add microsegmentation panel Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-manager v2 21/27] ui: sdn: dry-run: show pending microseg diff Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-manager v2 22/27] network: apply microseg state on reload Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-manager v2 23/27] ui: sdn: zones: add vxlan-gbp checkbox to vxlan and evpn Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-manager v2 24/27] ui: sdn: microseg: add tag matcher Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-manager v2 25/27] ui: sdn: microseg: add name regex matcher Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-docs v2 26/27] sdn: add microsegmentation section Hannes Laimer
2026-07-09 9:18 ` [PATCH pve-docs v2 27/27] sdn: add VXLAN-GBP flag to evpn/vxlan zone sections Hannes Laimer
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=20260709091852.538885-14-h.laimer@proxmox.com \
--to=h.laimer@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.