summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/PVE/API2/Network/SDN.pm7
-rw-r--r--src/PVE/API2/Network/SDN/Fabrics.pm165
-rw-r--r--src/PVE/API2/Network/SDN/Makefile3
-rw-r--r--src/PVE/Network/SDN.pm2
4 files changed, 175 insertions, 2 deletions
diff --git a/src/PVE/API2/Network/SDN.pm b/src/PVE/API2/Network/SDN.pm
index 0824410..6645f28 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);
@@ -46,6 +47,11 @@ __PACKAGE__->register_method({
});
__PACKAGE__->register_method({
+ subclass => "PVE::API2::Network::SDN::Fabrics",
+ path => 'fabrics',
+});
+
+__PACKAGE__->register_method({
name => 'index',
path => '',
method => 'GET',
@@ -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..a4a972d
--- /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/<fabric>', only list nodes where you have 'Sys.Audit' or 'Sys.Modify' on /nodes/<node_id>",
+ 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 8c584f6..66665a4 100644
--- a/src/PVE/Network/SDN.pm
+++ b/src/PVE/Network/SDN.pm
@@ -376,7 +376,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') {