[pve-devel] [PATCH pve-network 1/9] refactor: rework api module structure for the /nodes/{node}/sdn subdir

Stefan Hanreich s.hanreich at proxmox.com
Thu Oct 30 16:48:26 CET 2025


Previously, the endpoints for the SDN browser were contained in the
PVE::API2::Network::SDN::Zones module, which was registered in
PVE::API2::Nodes (located in pve-manager) directly with the sub-path
'sdn/{zone}'.

Instead of importing the zones module in pve-manager directly, create
a top-level Nodes module in pve-network, that is then imported in
pve-manager under the path 'sdn'. By importing just the root-level
module, changes can be made to the pve-network API without having to
update pve-manager. This allows for a better module structure on
pve-network side, because different entities can then be managed in
pve-network directly in the new top-level module. This is mainly in
preparation for adding new Vnets and Fabrics modules.

Also, the zones' content endpoint was contained in its own module. In
order to make it easier to add new endpoints to the 'sdn/zones/{zone}'
directory, move the contents endpoint into a new module that is
imported directly under 'sdn/zones/{zone}'. This allows easily adding
endpoints under the 'sdn/zones/{zone}' sub directory, without having
to create a separate module for each endpoint and registering it in
the Status module.

No functional changes intended, every endpoint should be the same as
before (URL + returned information).

Signed-off-by: Stefan Hanreich <s.hanreich at proxmox.com>
---
 src/PVE/API2/Network/SDN/Makefile             |  2 +-
 .../Network/SDN/{Zones => Nodes}/Makefile     |  8 ++-
 src/PVE/API2/Network/SDN/Nodes/Status.pm      | 49 +++++++++++++++
 .../SDN/{Zones/Content.pm => Nodes/Zone.pm}   | 59 +++++++++++++++----
 .../SDN/{Zones/Status.pm => Nodes/Zones.pm}   | 56 +++---------------
 5 files changed, 111 insertions(+), 63 deletions(-)
 rename src/PVE/API2/Network/SDN/{Zones => Nodes}/Makefile (62%)
 create mode 100644 src/PVE/API2/Network/SDN/Nodes/Status.pm
 rename src/PVE/API2/Network/SDN/{Zones/Content.pm => Nodes/Zone.pm} (60%)
 rename src/PVE/API2/Network/SDN/{Zones/Status.pm => Nodes/Zones.pm} (59%)

diff --git a/src/PVE/API2/Network/SDN/Makefile b/src/PVE/API2/Network/SDN/Makefile
index 08bec75..2624d9a 100644
--- a/src/PVE/API2/Network/SDN/Makefile
+++ b/src/PVE/API2/Network/SDN/Makefile
@@ -6,6 +6,6 @@ PERL5DIR=${DESTDIR}/usr/share/perl5
 .PHONY: install
 install:
 	for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/$$i; done
-	make -C Zones install
 	make -C Fabrics install
+	make -C Nodes install
 
diff --git a/src/PVE/API2/Network/SDN/Zones/Makefile b/src/PVE/API2/Network/SDN/Nodes/Makefile
similarity index 62%
rename from src/PVE/API2/Network/SDN/Zones/Makefile
rename to src/PVE/API2/Network/SDN/Nodes/Makefile
index 9b0a42b..edf0225 100644
--- a/src/PVE/API2/Network/SDN/Zones/Makefile
+++ b/src/PVE/API2/Network/SDN/Nodes/Makefile
@@ -1,8 +1,10 @@
-SOURCES=Status.pm Content.pm
-
+SOURCES=\
+	Status.pm\
+	Zone.pm\
+	Zones.pm
 
 PERL5DIR=${DESTDIR}/usr/share/perl5
 
 .PHONY: install
 install:
-	for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/Zones/$$i; done
+	for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/Nodes/$$i; done
diff --git a/src/PVE/API2/Network/SDN/Nodes/Status.pm b/src/PVE/API2/Network/SDN/Nodes/Status.pm
new file mode 100644
index 0000000..e862d4a
--- /dev/null
+++ b/src/PVE/API2/Network/SDN/Nodes/Status.pm
@@ -0,0 +1,49 @@
+package PVE::API2::Network::SDN::Nodes::Status;
+
+use strict;
+use warnings;
+
+use PVE::API2::Network::SDN::Nodes::Zones;
+
+use PVE::JSONSchema qw(get_standard_option);
+
+use PVE::RESTHandler;
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method({
+    subclass => "PVE::API2::Network::SDN::Nodes::Zones",
+    path => 'zones',
+});
+
+__PACKAGE__->register_method({
+    name => 'sdnindex',
+    path => '',
+    method => 'GET',
+    permissions => { user => 'all' },
+    description => "SDN index.",
+    proxyto => 'node',
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            node => get_standard_option('pve-node'),
+        },
+    },
+    returns => {
+        type => 'array',
+        items => {
+            type => "object",
+            properties => {},
+        },
+        links => [{ rel => 'child', href => "{name}" }],
+    },
+    code => sub {
+        my ($param) = @_;
+
+        my $result = [
+            { name => 'zones' },
+        ];
+        return $result;
+    },
+});
+
+1;
diff --git a/src/PVE/API2/Network/SDN/Zones/Content.pm b/src/PVE/API2/Network/SDN/Nodes/Zone.pm
similarity index 60%
rename from src/PVE/API2/Network/SDN/Zones/Content.pm
rename to src/PVE/API2/Network/SDN/Nodes/Zone.pm
index 7666321..1e963fc 100644
--- a/src/PVE/API2/Network/SDN/Zones/Content.pm
+++ b/src/PVE/API2/Network/SDN/Nodes/Zone.pm
@@ -1,26 +1,65 @@
-package PVE::API2::Network::SDN::Zones::Content;
+package PVE::API2::Network::SDN::Nodes::Zone;
 
 use strict;
 use warnings;
 
-use PVE::SafeSyslog;
-use PVE::Cluster;
-use PVE::INotify;
+use JSON qw(decode_json);
+
 use PVE::Exception qw(raise_param_exc);
-use PVE::RPCEnvironment;
-use PVE::RESTHandler;
+use PVE::INotify;
+use PVE::IPRoute2;
 use PVE::JSONSchema qw(get_standard_option);
-use PVE::Network::SDN;
+use PVE::Network;
+use PVE::Network::SDN::Vnets;
+use PVE::Network::SDN::Zones;
+use PVE::RS::SDN::Fabrics;
+use PVE::Tools qw(extract_param run_command);
 
+use PVE::RESTHandler;
 use base qw(PVE::RESTHandler);
 
 __PACKAGE__->register_method({
-    name => 'index',
+    name => 'diridx',
     path => '',
     method => 'GET',
+    description => "Directory index for SDN zone status.",
+    permissions => {
+        check => ['perm', '/sdn/zones/{zone}', ['SDN.Audit']],
+    },
+    parameters => {
+        additionalProperties => 0,
+        properties => {
+            node => get_standard_option('pve-node'),
+            zone => get_standard_option('pve-sdn-zone-id'),
+        },
+    },
+    returns => {
+        type => 'array',
+        items => {
+            type => "object",
+            properties => {
+                subdir => { type => 'string' },
+            },
+        },
+        links => [{ rel => 'child', href => "{subdir}" }],
+    },
+    code => sub {
+        my ($param) = @_;
+        my $res = [
+            { subdir => 'content' }, { subdir => 'bridges' }, { subdir => 'ip-vrf' },
+        ];
+
+        return $res;
+    },
+});
+
+__PACKAGE__->register_method({
+    path => 'content',
+    name => 'index',
+    method => 'GET',
     description => "List zone content.",
     permissions => {
-        check => ['perm', '/sdn/zones/{zone}', ['SDN.Audit'], any => 1],
+        check => ['perm', '/sdn/zones/{zone}', ['SDN.Audit']],
     },
     protected => 1,
     proxyto => 'node',
@@ -70,7 +109,7 @@ __PACKAGE__->register_method({
 
         my $res = [];
 
-        my ($zone_status, $vnet_status) = PVE::Network::SDN::status();
+        my ($zone_status, $vnet_status) = PVE::Network::SDN::Zones::status();
 
         foreach my $id (keys %{$vnet_status}) {
             if ($vnet_status->{$id}->{zone} eq $zoneid) {
diff --git a/src/PVE/API2/Network/SDN/Zones/Status.pm b/src/PVE/API2/Network/SDN/Nodes/Zones.pm
similarity index 59%
rename from src/PVE/API2/Network/SDN/Zones/Status.pm
rename to src/PVE/API2/Network/SDN/Nodes/Zones.pm
index 4957567..54c444f 100644
--- a/src/PVE/API2/Network/SDN/Zones/Status.pm
+++ b/src/PVE/API2/Network/SDN/Nodes/Zones.pm
@@ -1,24 +1,17 @@
-package PVE::API2::Network::SDN::Zones::Status;
+package PVE::API2::Network::SDN::Nodes::Zones;
 
-use strict;
-use warnings;
-
-use File::Path;
-use File::Basename;
-use PVE::Tools;
+use PVE::API2::Network::SDN::Nodes::Zone;
 use PVE::INotify;
-use PVE::Cluster;
-use PVE::API2::Network::SDN::Zones::Content;
-use PVE::RESTHandler;
-use PVE::RPCEnvironment;
 use PVE::JSONSchema qw(get_standard_option);
-use PVE::Exception qw(raise_param_exc);
+use PVE::Network::SDN;
+use PVE::RPCEnvironment;
 
+use PVE::RESTHandler;
 use base qw(PVE::RESTHandler);
 
 __PACKAGE__->register_method({
-    subclass => "PVE::API2::Network::SDN::Zones::Content",
-    path => '{zone}/content',
+    subclass => "PVE::API2::Network::SDN::Nodes::Zone",
+    path => '{zone}',
 });
 
 __PACKAGE__->register_method({
@@ -75,39 +68,4 @@ __PACKAGE__->register_method({
     },
 });
 
-__PACKAGE__->register_method({
-    name => 'diridx',
-    path => '{zone}',
-    method => 'GET',
-    description => "",
-    permissions => {
-        check => ['perm', '/sdn/zones/{zone}', ['SDN.Audit'], any => 1],
-    },
-    parameters => {
-        additionalProperties => 0,
-        properties => {
-            node => get_standard_option('pve-node'),
-            zone => get_standard_option('pve-sdn-zone-id'),
-        },
-    },
-    returns => {
-        type => 'array',
-        items => {
-            type => "object",
-            properties => {
-                subdir => { type => 'string' },
-            },
-        },
-        links => [{ rel => 'child', href => "{subdir}" }],
-    },
-    code => sub {
-        my ($param) = @_;
-        my $res = [
-            { subdir => 'content' },
-        ];
-
-        return $res;
-    },
-});
-
 1;
-- 
2.47.3




More information about the pve-devel mailing list