From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id A82091FF165 for ; Thu, 22 May 2025 18:23:13 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id C066BB254; Thu, 22 May 2025 18:18:34 +0200 (CEST) From: Stefan Hanreich To: pve-devel@lists.proxmox.com Date: Thu, 22 May 2025 18:17:03 +0200 Message-Id: <20250522161731.537011-48-s.hanreich@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250522161731.537011-1-s.hanreich@proxmox.com> References: <20250522161731.537011-1-s.hanreich@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.374 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods POISEN_SPAM_PILL 0.1 Meta: its spam POISEN_SPAM_PILL_1 0.1 random spam to be learned in bayes POISEN_SPAM_PILL_3 0.1 random spam to be learned in bayes RDNS_NONE 0.793 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Subject: [pve-devel] [PATCH pve-network v3 14/21] api: fabrics: add root-level module X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" There is one endpoint (/all) at the top-level that fetches both types of fabric entities (fabrics & nodes) and lists them separately. This is used for the main view, in order to avoid having to do two API calls. It works analogous to the existing root-level SDN API calls with the running / pending parameters. Also, since the interfaces key is used in the node sections, we need to add it to the function encoding the values so they are compared and returned from the API properly, when the pending parameter is set. Co-authored-by: Gabriel Goller Signed-off-by: Stefan Hanreich --- src/PVE/API2/Network/SDN.pm | 7 ++ src/PVE/API2/Network/SDN/Fabrics.pm | 165 ++++++++++++++++++++++++++++ src/PVE/API2/Network/SDN/Makefile | 3 +- src/PVE/Network/SDN.pm | 2 +- 4 files changed, 175 insertions(+), 2 deletions(-) create mode 100644 src/PVE/API2/Network/SDN/Fabrics.pm diff --git a/src/PVE/API2/Network/SDN.pm b/src/PVE/API2/Network/SDN.pm index 910f89a..877d46d 100644 --- a/src/PVE/API2/Network/SDN.pm +++ b/src/PVE/API2/Network/SDN.pm @@ -17,6 +17,7 @@ use PVE::API2::Network::SDN::Vnets; use PVE::API2::Network::SDN::Zones; use PVE::API2::Network::SDN::Ipams; use PVE::API2::Network::SDN::Dns; +use PVE::API2::Network::SDN::Fabrics; use base qw(PVE::RESTHandler); @@ -45,6 +46,11 @@ __PACKAGE__->register_method ({ path => 'dns', }); +__PACKAGE__->register_method ({ + subclass => "PVE::API2::Network::SDN::Fabrics", + path => 'fabrics', +}); + __PACKAGE__->register_method({ name => 'index', path => '', @@ -76,6 +82,7 @@ __PACKAGE__->register_method({ { id => 'controllers' }, { id => 'ipams' }, { id => 'dns' }, + { id => 'fabrics' }, ]; return $res; diff --git a/src/PVE/API2/Network/SDN/Fabrics.pm b/src/PVE/API2/Network/SDN/Fabrics.pm new file mode 100644 index 0000000..9333700 --- /dev/null +++ b/src/PVE/API2/Network/SDN/Fabrics.pm @@ -0,0 +1,165 @@ +package PVE::API2::Network::SDN::Fabrics; + +use strict; +use warnings; + +use PVE::Tools qw(extract_param); + +use PVE::Network::SDN; +use PVE::Network::SDN::Fabrics; + +use PVE::RESTHandler; +use base qw(PVE::RESTHandler); + +__PACKAGE__->register_method ({ + name => 'index', + path => '', + method => 'GET', + permissions => { + check => ['perm', '/sdn/fabrics', [ 'SDN.Audit' ]], + }, + description => "SDN Fabrics Index", + parameters => { + properties => {}, + }, + returns => { + type => 'array', + items => { + type => "object", + properties => { + subdir => { type => 'string' }, + }, + }, + links => [ { rel => 'child', href => "{subdir}" } ], + }, + code => sub { + my ($param) = @_; + + my $res = [ + { subdir => 'all' }, + ]; + + return $res; + }}); + +__PACKAGE__->register_method ({ + name => 'list_all', + path => 'all', + method => 'GET', + permissions => { + description => "Only list fabrics where you have 'SDN.Audit' or 'SDN.Allocate' permissions on\n" . + "'/sdn/fabrics/', only list nodes where you have 'Sys.Audit' or 'Sys.Modify' on /nodes/", + user => 'all' + }, + description => "SDN Fabrics Index", + parameters => { + properties => { + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, + }, + }, + returns => { + type => 'object', + properties => { + fabrics => { + type => 'array', + items => { + type => "object", + properties => PVE::Network::SDN::Fabrics::fabric_properties(0), + }, + }, + nodes => { + type => 'array', + items => { + type => "object", + properties => PVE::Network::SDN::Fabrics::node_properties(0), + }, + } + } + }, + code => sub { + my ($param) = @_; + + my $pending = extract_param($param, 'pending'); + my $running = extract_param($param, 'running'); + + my $digest; + my $fabrics; + my $nodes; + + if ($pending) { + my $current_config = PVE::Network::SDN::Fabrics::config(); + my $running_config = PVE::Network::SDN::Fabrics::config(1); + + my ($running_fabrics, $running_nodes) = $running_config + ->list_all(); + + my ($current_fabrics, $current_nodes) = $current_config + ->list_all(); + + my $pending_fabrics = PVE::Network::SDN::pending_config( + { fabrics => { ids => $running_fabrics }}, + { ids => $current_fabrics }, + 'fabrics' + ); + + my $pending_nodes = PVE::Network::SDN::pending_config( + { nodes => { ids => $running_nodes }}, + { ids => $current_nodes }, + 'nodes' + ); + + $digest = $current_config->digest(); + $fabrics = $pending_fabrics->{ids}; + $nodes = $pending_nodes->{ids}; + } elsif ($running) { + ($fabrics, $nodes) = PVE::Network::SDN::Fabrics::config(1) + ->list_all(); + } else { + my $current_config = PVE::Network::SDN::Fabrics::config(); + + ($fabrics, $nodes) = $current_config->list_all(); + $digest = $current_config->digest(); + } + + my $rpcenv = PVE::RPCEnvironment::get(); + my $authuser = $rpcenv->get_user(); + my $fabric_privs = ['SDN.Audit', 'SDN.Allocate']; + my $node_privs = ['Sys.Audit', 'Sys.Modify']; + + my @res_fabrics; + for my $id (keys %$fabrics) { + next if !$rpcenv->check_any($authuser, "/sdn/fabrics/$id", $fabric_privs, 1); + + $fabrics->{$id}->{digest} = $digest if $digest; + push @res_fabrics, $fabrics->{$id}; + } + + my @res_nodes; + for my $node_id (keys %$nodes) { + my $node = $nodes->{$node_id}; + my $fabric_id = $node->{fabric_id} // $node->{pending}->{fabric_id}; + + next if !$rpcenv->check_any($authuser, "/sdn/fabrics/$fabric_id", $fabric_privs, 1); + next if !$rpcenv->check_any($authuser, "/nodes/$node_id", $node_privs, 1); + + $node->{digest} = $digest if $digest; + + push @res_nodes, $node; + } + + return { + fabrics => \@res_fabrics, + nodes => \@res_nodes, + }; + }}); + +1; diff --git a/src/PVE/API2/Network/SDN/Makefile b/src/PVE/API2/Network/SDN/Makefile index abd1bfa..08bec75 100644 --- a/src/PVE/API2/Network/SDN/Makefile +++ b/src/PVE/API2/Network/SDN/Makefile @@ -1,4 +1,4 @@ -SOURCES=Vnets.pm Zones.pm Controllers.pm Subnets.pm Ipams.pm Dns.pm Ips.pm +SOURCES=Vnets.pm Zones.pm Controllers.pm Subnets.pm Ipams.pm Dns.pm Ips.pm Fabrics.pm PERL5DIR=${DESTDIR}/usr/share/perl5 @@ -7,4 +7,5 @@ PERL5DIR=${DESTDIR}/usr/share/perl5 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 diff --git a/src/PVE/Network/SDN.pm b/src/PVE/Network/SDN.pm index 79e19b1..1a340a5 100644 --- a/src/PVE/Network/SDN.pm +++ b/src/PVE/Network/SDN.pm @@ -362,7 +362,7 @@ sub generate_dhcp_config { sub encode_value { my ($type, $key, $value) = @_; - if ($key eq 'nodes' || $key eq 'exitnodes' || $key eq 'dhcp-range') { + if ($key eq 'nodes' || $key eq 'exitnodes' || $key eq 'dhcp-range' || $key eq 'interfaces') { if (ref($value) eq 'HASH') { return join(',', sort keys(%$value)); } elsif (ref($value) eq 'ARRAY') { -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel