mirror of
git://git.proxmox.com/git/pve-network.git
synced 2025-01-07 21:18:01 +03:00
add network transport api
This commit is contained in:
parent
0ec8cb8742
commit
eec580bf18
5
PVE/API2/Makefile
Normal file
5
PVE/API2/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
make -C Network install
|
8
PVE/API2/Network/Makefile
Normal file
8
PVE/API2/Network/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
SOURCES=Transport.pm
|
||||
|
||||
|
||||
PERL5DIR=${DESTDIR}/usr/share/perl5
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
for i in ${SOURCES}; do install -D -m 0644 $$i ${PERL5DIR}/PVE/API2/Network/$$i; done
|
235
PVE/API2/Network/Transport.pm
Normal file
235
PVE/API2/Network/Transport.pm
Normal file
@ -0,0 +1,235 @@
|
||||
package PVE::API2::Network::Transport;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use PVE::SafeSyslog;
|
||||
use PVE::Tools qw(extract_param);
|
||||
use PVE::Cluster qw(cfs_read_file cfs_write_file);
|
||||
use PVE::Network::Transport;
|
||||
use PVE::Network::Plugin;
|
||||
use PVE::Network::VlanPlugin;
|
||||
use PVE::Network::VxlanMulticastPlugin;
|
||||
use Storable qw(dclone);
|
||||
use PVE::JSONSchema qw(get_standard_option);
|
||||
use PVE::RPCEnvironment;
|
||||
|
||||
use PVE::RESTHandler;
|
||||
|
||||
use base qw(PVE::RESTHandler);
|
||||
|
||||
my $transport_type_enum = PVE::Network::Plugin->lookup_types();
|
||||
|
||||
my $api_transport_config = sub {
|
||||
my ($cfg, $transportid) = @_;
|
||||
|
||||
my $scfg = dclone(PVE::Network::Transport::transport_config($cfg, $transportid));
|
||||
$scfg->{transport} = $transportid;
|
||||
$scfg->{digest} = $cfg->{digest};
|
||||
|
||||
return $scfg;
|
||||
};
|
||||
|
||||
__PACKAGE__->register_method ({
|
||||
name => 'index',
|
||||
path => '',
|
||||
method => 'GET',
|
||||
description => "Transport index.",
|
||||
permissions => {
|
||||
description => "Only list entries where you have 'NetworkTransport.Audit' or 'NetworkTransport.Allocate' permissions on '/networktransports/<transport>'",
|
||||
user => 'all',
|
||||
},
|
||||
parameters => {
|
||||
additionalProperties => 0,
|
||||
properties => {
|
||||
type => {
|
||||
description => "Only list transport of specific type",
|
||||
type => 'string',
|
||||
enum => $transport_type_enum,
|
||||
optional => 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
returns => {
|
||||
type => 'array',
|
||||
items => {
|
||||
type => "object",
|
||||
properties => { transport => { type => 'string'} },
|
||||
},
|
||||
links => [ { rel => 'child', href => "{transport}" } ],
|
||||
},
|
||||
code => sub {
|
||||
my ($param) = @_;
|
||||
|
||||
my $rpcenv = PVE::RPCEnvironment::get();
|
||||
my $authuser = $rpcenv->get_user();
|
||||
|
||||
|
||||
my $cfg = PVE::Network::Transport::config();
|
||||
|
||||
my @sids = PVE::Network::Transport::transports_ids($cfg);
|
||||
my $res = [];
|
||||
foreach my $transportid (@sids) {
|
||||
# my $privs = [ 'NetworkTransport.Audit', 'NetworkTransport.Allocate' ];
|
||||
# next if !$rpcenv->check_any($authuser, "/network/transports/$transportid", $privs, 1);
|
||||
|
||||
my $scfg = &$api_transport_config($cfg, $transportid);
|
||||
next if $param->{type} && $param->{type} ne $scfg->{type};
|
||||
push @$res, $scfg;
|
||||
}
|
||||
|
||||
return $res;
|
||||
}});
|
||||
|
||||
__PACKAGE__->register_method ({
|
||||
name => 'read',
|
||||
path => '{transport}',
|
||||
method => 'GET',
|
||||
description => "Read transport configuration.",
|
||||
# permissions => {
|
||||
# check => ['perm', '/network/transports/{transport}', ['NetworkTransport.Allocate']],
|
||||
# },
|
||||
|
||||
parameters => {
|
||||
additionalProperties => 0,
|
||||
properties => {
|
||||
transport => get_standard_option('pve-transport-id'),
|
||||
},
|
||||
},
|
||||
returns => { type => 'object' },
|
||||
code => sub {
|
||||
my ($param) = @_;
|
||||
|
||||
my $cfg = PVE::Network::Transport::config();
|
||||
|
||||
return &$api_transport_config($cfg, $param->{transport});
|
||||
}});
|
||||
|
||||
__PACKAGE__->register_method ({
|
||||
name => 'create',
|
||||
protected => 1,
|
||||
path => '',
|
||||
method => 'POST',
|
||||
description => "Create a new network transport.",
|
||||
# permissions => {
|
||||
# check => ['perm', '/network/transports', ['NetworkTransport.Allocate']],
|
||||
# },
|
||||
parameters => PVE::Network::Plugin->createSchema(),
|
||||
returns => { type => 'null' },
|
||||
code => sub {
|
||||
my ($param) = @_;
|
||||
|
||||
my $type = extract_param($param, 'type');
|
||||
my $transportid = extract_param($param, 'transport');
|
||||
|
||||
my $plugin = PVE::Network::Plugin->lookup($type);
|
||||
my $opts = $plugin->check_config($transportid, $param, 1, 1);
|
||||
|
||||
PVE::Network::Transport::lock_transport_config(
|
||||
sub {
|
||||
|
||||
my $cfg = PVE::Network::Transport::config();
|
||||
|
||||
if (my $scfg = PVE::Network::Transport::transport_config($cfg, $transportid, 1)) {
|
||||
die "network transport ID '$transportid' already defined\n";
|
||||
}
|
||||
|
||||
$cfg->{ids}->{$transportid} = $opts;
|
||||
|
||||
#improveme:
|
||||
#check local configuration of all nodes for conflict
|
||||
|
||||
PVE::Network::Transport::write_config($cfg);
|
||||
|
||||
}, "create network transport failed");
|
||||
|
||||
return undef;
|
||||
}});
|
||||
|
||||
__PACKAGE__->register_method ({
|
||||
name => 'update',
|
||||
protected => 1,
|
||||
path => '{transport}',
|
||||
method => 'PUT',
|
||||
description => "Update network transport configuration.",
|
||||
# permissions => {
|
||||
# check => ['perm', '/network/transports', ['NetworkTransport.Allocate']],
|
||||
# },
|
||||
parameters => PVE::Network::Plugin->updateSchema(),
|
||||
returns => { type => 'null' },
|
||||
code => sub {
|
||||
my ($param) = @_;
|
||||
|
||||
my $transportid = extract_param($param, 'transport');
|
||||
my $digest = extract_param($param, 'digest');
|
||||
|
||||
PVE::Network::Transport::lock_transport_config(
|
||||
sub {
|
||||
|
||||
my $cfg = PVE::Network::Transport::config();
|
||||
|
||||
PVE::SectionConfig::assert_if_modified($cfg, $digest);
|
||||
|
||||
my $scfg = PVE::Network::Transport::transport_config($cfg, $transportid);
|
||||
|
||||
my $plugin = PVE::Network::Plugin->lookup($scfg->{type});
|
||||
my $opts = $plugin->check_config($transportid, $param, 0, 1);
|
||||
|
||||
foreach my $k (%$opts) {
|
||||
$scfg->{$k} = $opts->{$k};
|
||||
}
|
||||
#improveme:
|
||||
#add vlan/vxlan check on existingvnets
|
||||
#check local configuration of all nodes for conflict
|
||||
PVE::Network::Transport::write_config($cfg);
|
||||
|
||||
}, "update network transport failed");
|
||||
|
||||
return undef;
|
||||
}});
|
||||
|
||||
__PACKAGE__->register_method ({
|
||||
name => 'delete',
|
||||
protected => 1,
|
||||
path => '{transport}', # /network/transports/{transport}
|
||||
method => 'DELETE',
|
||||
description => "Delete network transport configuration.",
|
||||
# permissions => {
|
||||
# check => ['perm', '/network/transports', ['NetworkTransport.Allocate']],
|
||||
# },
|
||||
parameters => {
|
||||
additionalProperties => 0,
|
||||
properties => {
|
||||
transport => get_standard_option('pve-transport-id', {
|
||||
completion => \&PVE::Network::Transport::complete_transport,
|
||||
}),
|
||||
},
|
||||
},
|
||||
returns => { type => 'null' },
|
||||
code => sub {
|
||||
my ($param) = @_;
|
||||
|
||||
my $transportid = extract_param($param, 'transport');
|
||||
|
||||
PVE::Network::Transport::lock_transport_config(
|
||||
sub {
|
||||
|
||||
my $cfg = PVE::Network::Transport::config();
|
||||
|
||||
my $scfg = PVE::Network::Transport::transport_config($cfg, $transportid);
|
||||
|
||||
# my $plugin = PVE::Network::Plugin->lookup($scfg->{type});
|
||||
# $plugin->on_delete_hook($transportid, $scfg);
|
||||
|
||||
delete $cfg->{ids}->{$transportid};
|
||||
#improveme:
|
||||
#check that vnet don't use this transport
|
||||
PVE::Network::Transport::write_config($cfg);
|
||||
|
||||
}, "delete network transport failed");
|
||||
|
||||
|
||||
return undef;
|
||||
}});
|
||||
|
||||
1;
|
@ -1,3 +1,4 @@
|
||||
.PHONY: install
|
||||
install:
|
||||
make -C Network install
|
||||
make -C API2 install
|
||||
|
@ -8,7 +8,7 @@ use PVE::JSONSchema;
|
||||
use PVE::Cluster;
|
||||
|
||||
use Data::Dumper;
|
||||
|
||||
use PVE::JSONSchema qw(get_standard_option);
|
||||
use base qw(PVE::SectionConfig);
|
||||
|
||||
PVE::Cluster::cfs_register_file('network/transports.cfg',
|
||||
@ -23,11 +23,8 @@ my $defaultData = {
|
||||
type => 'string', format => 'pve-configid',
|
||||
type => 'string',
|
||||
},
|
||||
'uplink-id' => {
|
||||
type => 'integer',
|
||||
minimum => 1, maximum => 4096,
|
||||
description => 'Uplink interface',
|
||||
},
|
||||
transport => get_standard_option('pve-transport-id',
|
||||
{ completion => \&PVE::Network::Transport::complete_transport }),
|
||||
},
|
||||
};
|
||||
|
||||
|
62
PVE/Network/Transport.pm
Normal file
62
PVE/Network/Transport.pm
Normal file
@ -0,0 +1,62 @@
|
||||
package PVE::Network::Transport;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
|
||||
use PVE::Network::Plugin;
|
||||
use PVE::Network::VlanPlugin;
|
||||
use PVE::Network::VxlanMulticastPlugin;
|
||||
|
||||
PVE::Network::VlanPlugin->register();
|
||||
PVE::Network::VxlanMulticastPlugin->register();
|
||||
PVE::Network::Plugin->init();
|
||||
|
||||
|
||||
sub transport_config {
|
||||
my ($cfg, $transportid, $noerr) = @_;
|
||||
|
||||
die "no transport ID specified\n" if !$transportid;
|
||||
|
||||
my $scfg = $cfg->{ids}->{$transportid};
|
||||
die "transport '$transportid' does not exists\n" if (!$noerr && !$scfg);
|
||||
|
||||
return $scfg;
|
||||
}
|
||||
|
||||
sub config {
|
||||
|
||||
return cfs_read_file("network/transports.cfg");
|
||||
}
|
||||
|
||||
sub write_config {
|
||||
my ($cfg) = @_;
|
||||
|
||||
cfs_write_file("network/transports.cfg", $cfg);
|
||||
}
|
||||
|
||||
sub lock_transport_config {
|
||||
my ($code, $errmsg) = @_;
|
||||
|
||||
cfs_lock_file("network/transports.cfg", undef, $code);
|
||||
my $err = $@;
|
||||
if ($err) {
|
||||
$errmsg ? die "$errmsg: $err" : die $err;
|
||||
}
|
||||
}
|
||||
|
||||
sub transports_ids {
|
||||
my ($cfg) = @_;
|
||||
|
||||
return keys %{$cfg->{ids}};
|
||||
}
|
||||
|
||||
sub complete_transport {
|
||||
my ($cmdname, $pname, $cvalue) = @_;
|
||||
|
||||
my $cfg = PVE::Network::Transport::config();
|
||||
|
||||
return $cmdname eq 'add' ? [] : [ PVE::Network::Transport::transports_ids($cfg) ];
|
||||
}
|
||||
|
||||
1;
|
@ -21,6 +21,11 @@ sub pve_verify_network_vlanrange {
|
||||
|
||||
sub properties {
|
||||
return {
|
||||
'uplink-id' => {
|
||||
type => 'integer',
|
||||
minimum => 1, maximum => 4096,
|
||||
description => 'Uplink interface',
|
||||
},
|
||||
'vlan-allowed' => {
|
||||
type => 'string', format => 'pve-network-vlanrange',
|
||||
description => "Allowed vlan range",
|
||||
@ -42,7 +47,7 @@ sub properties {
|
||||
sub options {
|
||||
|
||||
return {
|
||||
'uplink-id' => { fixed => 1 },
|
||||
'uplink-id' => { optional => 1 },
|
||||
'vlan-allowed' => { optional => 1 },
|
||||
'vlan-protocol' => { optional => 1 },
|
||||
'vlan-aware' => { optional => 1 },
|
||||
|
@ -36,7 +36,7 @@ sub properties {
|
||||
sub options {
|
||||
|
||||
return {
|
||||
'uplink-id' => { fixed => 1 },
|
||||
'uplink-id' => { optional => 1 },
|
||||
'multicast-address' => { fixed => 1 },
|
||||
'vxlan-allowed' => { optional => 1 },
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user