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