From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 497821FF168 for <inbox@lore.proxmox.com>; Tue, 4 Mar 2025 10:51:46 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id B78051A1A4; Tue, 4 Mar 2025 10:51:40 +0100 (CET) Message-ID: <65997975-98d6-4561-b8c7-a35fdf824cb6@proxmox.com> Date: Tue, 4 Mar 2025 10:51:02 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>, Gabriel Goller <g.goller@proxmox.com> References: <20250214133951.344500-1-g.goller@proxmox.com> <20250214133951.344500-9-g.goller@proxmox.com> Content-Language: en-US From: Stefan Hanreich <s.hanreich@proxmox.com> In-Reply-To: <20250214133951.344500-9-g.goller@proxmox.com> X-SPAM-LEVEL: Spam detection results: 0 AWL 0.670 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 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [sdn.pm, common.pm, vnets.pm, dns.pm, subnets.pm, zones.pm, ipams.pm, fabrics.pm, openfabric.pm, ips.pm, controllers.pm, ospf.pm] Subject: Re: [pve-devel] [PATCH pve-network 08/11] add api endpoints for fabrics X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> please add descriptions to the properties, it serves as the documentation and we also cannot autogenerate the Rust types for the API methods. Some methods only have type => 'object' as return type. It would be good to properly document the properties of those as well for the same reasons as above. It might make sense to define some standard options so we can reuse them among multiple API methods. On 2/14/25 14:39, Gabriel Goller wrote: > Add api endpoints for CRUD of fabrics, nodes, and interfaces. > > Signed-off-by: Gabriel Goller <g.goller@proxmox.com> > --- > src/PVE/API2/Network/SDN.pm | 7 + > src/PVE/API2/Network/SDN/Fabrics.pm | 57 +++ > src/PVE/API2/Network/SDN/Fabrics/Common.pm | 111 +++++ > src/PVE/API2/Network/SDN/Fabrics/Makefile | 9 + > .../API2/Network/SDN/Fabrics/OpenFabric.pm | 460 ++++++++++++++++++ > src/PVE/API2/Network/SDN/Fabrics/Ospf.pm | 433 +++++++++++++++++ > src/PVE/API2/Network/SDN/Makefile | 3 +- > 7 files changed, 1079 insertions(+), 1 deletion(-) > create mode 100644 src/PVE/API2/Network/SDN/Fabrics.pm > create mode 100644 src/PVE/API2/Network/SDN/Fabrics/Common.pm > create mode 100644 src/PVE/API2/Network/SDN/Fabrics/Makefile > create mode 100644 src/PVE/API2/Network/SDN/Fabrics/OpenFabric.pm > create mode 100644 src/PVE/API2/Network/SDN/Fabrics/Ospf.pm > > diff --git a/src/PVE/API2/Network/SDN.pm b/src/PVE/API2/Network/SDN.pm > index d216e4878b61..ccbf0777e3d4 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 000000000000..8eb88efca102 > --- /dev/null > +++ b/src/PVE/API2/Network/SDN/Fabrics.pm > @@ -0,0 +1,57 @@ > +package PVE::API2::Network::SDN::Fabrics; > + > +use strict; > +use warnings; > + > +use Storable qw(dclone); > + > +use PVE::RPCEnvironment; > +use PVE::Tools qw(extract_param); > + > +use PVE::API2::Network::SDN::Fabrics::OpenFabric; > +use PVE::API2::Network::SDN::Fabrics::Ospf; > + > +use PVE::Network::SDN::Fabrics; > + > +use PVE::RESTHandler; > +use base qw(PVE::RESTHandler); > + > + > +__PACKAGE__->register_method ({ > + subclass => "PVE::API2::Network::SDN::Fabrics::OpenFabric", > + path => 'openfabric', > +}); > +__PACKAGE__->register_method ({ > + subclass => "PVE::API2::Network::SDN::Fabrics::Ospf", > + path => 'ospf', > +}); > + > +__PACKAGE__->register_method({ > + name => 'index', > + path => '', > + method => 'GET', > + description => 'Index of SDN Fabrics', > + permissions => { > + description => "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/fabrics/<fabric>'", > + user => 'all', > + }, > + parameters => { > + additionalProperties => 0, > + }, > + returns => { > + type => 'array', > + items => { > + oneOf => [ > + > + ], something missing here? > + }, > + }, > + code => sub { > + my ($param) = @_; > + > + my $config = PVE::Network::SDN::Fabrics::get_all_configs(); > + return $config; > + }, > +}); > + > +1; > diff --git a/src/PVE/API2/Network/SDN/Fabrics/Common.pm b/src/PVE/API2/Network/SDN/Fabrics/Common.pm > new file mode 100644 > index 000000000000..f3042a18090d > --- /dev/null > +++ b/src/PVE/API2/Network/SDN/Fabrics/Common.pm > @@ -0,0 +1,111 @@ > +package PVE::API2::Network::SDN::Fabrics::Common; > + > +use strict; > +use warnings; > + > +use PVE::Network::SDN::Fabrics; > + > +sub delete_fabric { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->delete_fabric($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + return $fabrics->get_inner(); > +} > + > +sub delete_node { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->delete_node($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + return $fabrics->get_inner(); > +} > + > +sub delete_interface { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->delete_interface($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + return $fabrics->get_inner(); > +} > + > +sub add_node { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->add_node($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + > + return $fabrics->get_inner(); > +} > + > +sub add_fabric { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->add_fabric($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + > + return $fabrics->get_inner(); > +} > + > +sub get_fabric { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + my $return_value = $fabrics->get_fabric($param->{fabric}); > + # Add the fabric id to the return value. The rust return value doesn't contain > + # the fabric name (as it's in the key of the section config hashmap, so we add it here). > + $return_value->{fabric}->{name} = $param->{fabric}; > + return $return_value; > +} > + > +sub get_node { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + my $return_value = $fabrics->get_node($param->{fabric}, $param->{node}); > + # Add the node id to the return value. The rust return value doesn't contain > + # the nodename (as it's in the key of the section config hashmap, so we add it here). > + $return_value->{node}->{node} = $param->{node}; > + return $return_value; > +} > + > +sub get_interface { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + return $fabrics->get_interface($param->{fabric}, $param->{node}, $param->{name}); > +} > + > +sub edit_fabric { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->edit_fabric($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + return $fabrics->get_inner(); > +} > + > +sub edit_node { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->edit_node($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + return $fabrics->get_inner(); > +} > + > +sub edit_interface { > + my ($type, $param) = @_; > + > + my $fabrics = PVE::Network::SDN::Fabrics::get_config($type); > + $fabrics->edit_interface($param); > + PVE::Network::SDN::Fabrics::write_config($fabrics); > + return $fabrics->get_inner(); > +} > + > +1; > diff --git a/src/PVE/API2/Network/SDN/Fabrics/Makefile b/src/PVE/API2/Network/SDN/Fabrics/Makefile > new file mode 100644 > index 000000000000..e433f2e7d0a6 > --- /dev/null > +++ b/src/PVE/API2/Network/SDN/Fabrics/Makefile > @@ -0,0 +1,9 @@ > +SOURCES=OpenFabric.pm Ospf.pm Common.pm > + > + > +PERL5DIR=${DESTDIR}/usr/share/perl5 > + > +.PHONY: install > +install: > + for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/SDN/Fabrics/$$i; done > + > diff --git a/src/PVE/API2/Network/SDN/Fabrics/OpenFabric.pm b/src/PVE/API2/Network/SDN/Fabrics/OpenFabric.pm > new file mode 100644 > index 000000000000..626893aa61b7 > --- /dev/null > +++ b/src/PVE/API2/Network/SDN/Fabrics/OpenFabric.pm > @@ -0,0 +1,460 @@ > +package PVE::API2::Network::SDN::Fabrics::OpenFabric; > + > +use strict; > +use warnings; > + > +use Storable qw(dclone); > + > +use PVE::RPCEnvironment; > +use PVE::Tools qw(extract_param); > + > +use PVE::Network::SDN::Fabrics; > +use PVE::API2::Network::SDN::Fabrics::Common; > + > +use PVE::RESTHandler; > +use base qw(PVE::RESTHandler); > + > +__PACKAGE__->register_method({ > + name => 'delete_fabric', > + path => '{fabric}', > + method => 'DELETE', > + description => 'Delete SDN Fabric', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::delete_fabric("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'delete_node', > + path => '{fabric}/node/{node}', > + method => 'DELETE', > + description => 'Delete SDN Fabric Node', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}/node/{node}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::delete_node("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'delete_interface', > + path => '{fabric}/node/{node}/interface/{name}', > + method => 'DELETE', > + description => 'Delete SDN Fabric Node Interface', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}/node/{node}/interface/{name}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + name => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::delete_interface("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'update_fabric', > + path => '{fabric}', > + method => 'PUT', > + description => 'Update SDN Fabric configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string' > + }, > + hello_interval => { > + type => 'integer', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::edit_fabric("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'update_node', > + path => '{fabric}/node/{node}', > + method => 'PUT', > + description => 'Update SDN Fabric Node configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}/node/{node}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + net => { > + type => 'string', > + }, > + interfaces => { > + type => 'array', > + items => { > + type => 'string', you can use the additional format parameter for documenting property strings > + }, > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::edit_node("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'update_interface', > + path => '{fabric}/node/{node}/interface/{name}', > + method => 'PUT', > + description => 'Update SDN Fabric Interface configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}/node/{node}/interface/{name}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + name => { > + type => 'string', > + }, > + passive => { > + type => 'boolean', > + }, > + hello_interval => { > + optional => 1, > + type => 'string', > + }, > + hello_multiplier => { > + optional => 1, > + type => 'string', > + }, > + csnp_interval => { > + optional => 1, > + type => 'string', > + }, should we turn those into numbers as well? in get_interface they're types as numbers afaict. > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::edit_interface("openfabric", $param); > + }, > +}); > + > + > +__PACKAGE__->register_method({ > + name => 'get_fabric', > + path => '{fabric}', > + method => 'GET', > + description => 'Get SDN Fabric configuration', > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => {} > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + properties => { > + fabric => { > + type => 'object', > + properties => { > + name => { > + type => 'string' > + } > + } > + } > + } > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::get_fabric("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'get_node', > + path => '{fabric}/node/{node}', > + method => 'GET', > + description => 'Get SDN Fabric Node configuration', > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => {} > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + properties => { > + node => { > + type => 'object', > + properties => { > + net => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + interface => { > + type => 'array', > + items => { > + type => 'string' > + } > + }, > + } > + } > + } > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::get_node("openfabric", $param); > + }, > +}); > + > + > +__PACKAGE__->register_method({ > + name => 'get_interface', > + path => '{fabric}/node/{node}/interface/{name}', > + method => 'GET', > + description => 'Get SDN Fabric Interface configuration', > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + properties => { > + name => { > + type => 'string', > + }, > + passive => { > + type => 'boolean', > + }, > + hello_interval => { > + optional => 1, > + type => 'number', > + }, > + hello_multiplier => { > + optional => 1, > + type => 'number', > + }, > + csnp_interval => { > + optional => 1, > + type => 'number', > + }, > + } > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::get_interface("openfabric", $param); > + }, > +}); > + > + > +__PACKAGE__->register_method({ > + name => 'add_fabric', > + path => '/', > + method => 'POST', > + description => 'Create SDN Fabric configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + "type" => { > + type => 'string', > + }, > + "name" => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::add_fabric("openfabric", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'add_node', > + path => '{fabric}/node/{node}', > + method => 'POST', > + description => 'Create SDN Fabric Node configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/openfabric/{fabric}/node/{node}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + net => { > + type => 'string', > + }, > + interfaces => { > + type => 'array', > + items => { > + type => 'string', > + }, > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::add_node("openfabric", $param); > + }, > +}); > + > +1; > diff --git a/src/PVE/API2/Network/SDN/Fabrics/Ospf.pm b/src/PVE/API2/Network/SDN/Fabrics/Ospf.pm > new file mode 100644 > index 000000000000..309d29788667 > --- /dev/null > +++ b/src/PVE/API2/Network/SDN/Fabrics/Ospf.pm > @@ -0,0 +1,433 @@ > +package PVE::API2::Network::SDN::Fabrics::Ospf; > + > +use strict; > +use warnings; > + > +use Storable qw(dclone); > + > +use PVE::RPCEnvironment; > +use PVE::Tools qw(extract_param); > + > +use PVE::Network::SDN::Fabrics; > +use PVE::API2::Network::SDN::Fabrics::Common; > + > +use PVE::RESTHandler; > +use base qw(PVE::RESTHandler); > + > +__PACKAGE__->register_method({ > + name => 'delete_fabric', > + path => '{fabric}', > + method => 'DELETE', > + description => 'Delete SDN Fabric', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::delete_fabric("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'delete_node', > + path => '{fabric}/node/{node}', > + method => 'DELETE', > + description => 'Delete SDN Fabric Node', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}/node/{node}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::delete_node("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'delete_interface', > + path => '{fabric}/node/{node}/interface/{name}', > + method => 'DELETE', > + description => 'Delete SDN Fabric Node Interface', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}/node/{node}/interface/{name}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + name => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'null', > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::delete_interface("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'update_fabric', > + path => '{fabric}', > + method => 'PUT', > + description => 'Update SDN Fabric configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string' > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::edit_fabric("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'update_node', > + path => '{fabric}/node/{node}', > + method => 'PUT', > + description => 'Update SDN Fabric Interface configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + router_id => { > + type => 'string', > + }, > + interfaces => { > + type => 'array', > + items => { > + type => 'string', > + }, > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::edit_node("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'update_interface', > + path => '{fabric}/node/{node}/interface/{name}', > + method => 'PUT', > + description => 'Update SDN Fabric Interface configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}/node/{node}/interface/{name}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + name => { > + type => 'string', > + }, > + passive => { > + type => 'boolean', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::edit_interface("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'get_fabric', > + path => '{fabric}', > + method => 'GET', > + description => 'Get SDN Fabric configuration', > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => {} > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + properties => { > + fabric => { > + type => 'object', > + properties => { > + name => { > + type => 'string' > + } > + } > + } > + } > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::get_fabric("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'get_node', > + path => '{fabric}/node/{node}', > + method => 'GET', > + description => 'Get SDN Fabric Node configuration', > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => {} > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + properties => { > + node => { > + type => 'object', > + properties => { > + router_id => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + interface => { > + type => 'array', > + items => { > + type => 'string' > + } > + }, > + } > + } > + } > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::get_node("ospf", $param); > + }, > +}); > + > + > +__PACKAGE__->register_method({ > + name => 'get_interface', > + path => '{fabric}/node/{node}/interface/{name}', > + method => 'GET', > + description => 'Get SDN Fabric Interface configuration', > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + properties => { > + name => { > + type => 'string', > + }, > + passive => { > + type => 'boolean', > + }, > + } > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::get_interface("ospf", $param); > + }, > +}); > + > + > +__PACKAGE__->register_method({ > + name => 'add_fabric', > + path => '/', > + method => 'POST', > + description => 'Create SDN Fabric configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + "type" => { > + type => 'string', > + }, > + "name" => { > + type => 'string', > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::add_fabric("ospf", $param); > + }, > +}); > + > +__PACKAGE__->register_method({ > + name => 'add_node', > + path => '{fabric}/node/{node}', > + method => 'POST', > + description => 'Create SDN Fabric Node configuration', > + protected => 1, > + permissions => { > + check => ['perm', '/sdn/fabrics/ospf/{fabric}/node/{node}', [ 'SDN.Allocate' ]], > + }, > + parameters => { > + additionalProperties => 1, > + properties => { > + fabric => { > + type => 'string', > + }, > + node => { > + type => 'string', > + }, > + router_id => { > + type => 'string', > + }, > + interfaces => { > + type => 'array', > + items => { > + type => 'string', > + }, > + }, > + }, > + }, > + returns => { > + type => 'object', > + properties => { > + data => { > + type => 'object', > + } > + } > + }, > + code => sub { > + my ($param) = @_; > + > + return PVE::API2::Network::SDN::Fabrics::Common::add_node("ospf", $param); > + }, > +}); > + > + > +1; > diff --git a/src/PVE/API2/Network/SDN/Makefile b/src/PVE/API2/Network/SDN/Makefile > index abd1bfae020e..08bec7535530 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 > _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel