From 6f5f42e4435a4ec171f4634d3480208c271b39d5 Mon Sep 17 00:00:00 2001 From: Alexandre Derumier Date: Mon, 5 Oct 2020 17:09:04 +0200 Subject: [PATCH] api: add running/pending zones/vnets/subnets/controllers Signed-off-by: Alexandre Derumier --- PVE/API2/Network/SDN/Controllers.pm | 53 ++++++++++++++++++++++--- PVE/API2/Network/SDN/Subnets.pm | 49 +++++++++++++++++++++-- PVE/API2/Network/SDN/Vnets.pm | 60 +++++++++++++++++++++++++++-- PVE/API2/Network/SDN/Zones.pm | 54 ++++++++++++++++++++++++-- PVE/Network/SDN.pm | 45 ++++++++++++++++++++++ 5 files changed, 245 insertions(+), 16 deletions(-) diff --git a/PVE/API2/Network/SDN/Controllers.pm b/PVE/API2/Network/SDN/Controllers.pm index 919d343..75beb6b 100644 --- a/PVE/API2/Network/SDN/Controllers.pm +++ b/PVE/API2/Network/SDN/Controllers.pm @@ -51,15 +51,27 @@ __PACKAGE__->register_method ({ enum => $sdn_controllers_type_enum, optional => 1, }, + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, }, }, returns => { type => 'array', items => { type => "object", - properties => { controller => { type => 'string'}, - type => { type => 'string'}, - }, + properties => { controller => { type => 'string' }, + type => { type => 'string' }, + state => { type => 'string', optional => 1 }, + pending => { optional => 1}, + }, }, links => [ { rel => 'child', href => "{controller}" } ], }, @@ -69,8 +81,17 @@ __PACKAGE__->register_method ({ my $rpcenv = PVE::RPCEnvironment::get(); my $authuser = $rpcenv->get_user(); - - my $cfg = PVE::Network::SDN::Controllers::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Controllers::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'controllers'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{controllers}; + } else { + $cfg = PVE::Network::SDN::Controllers::config(); + } my @sids = PVE::Network::SDN::Controllers::sdn_controllers_ids($cfg); my $res = []; @@ -102,13 +123,33 @@ __PACKAGE__->register_method ({ additionalProperties => 0, properties => { controller => get_standard_option('pve-sdn-controller-id'), + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, }, }, returns => { type => 'object' }, code => sub { my ($param) = @_; - my $cfg = PVE::Network::SDN::Controllers::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Controllers::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'controllers'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{controllers}; + } else { + $cfg = PVE::Network::SDN::Controllers::config(); + } return &$api_sdn_controllers_config($cfg, $param->{controller}); }}); diff --git a/PVE/API2/Network/SDN/Subnets.pm b/PVE/API2/Network/SDN/Subnets.pm index e122ffd..82635f6 100644 --- a/PVE/API2/Network/SDN/Subnets.pm +++ b/PVE/API2/Network/SDN/Subnets.pm @@ -46,7 +46,17 @@ __PACKAGE__->register_method ({ additionalProperties => 0, properties => { vnet => get_standard_option('pve-sdn-vnet-id'), - }, + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, + }, }, returns => { type => 'array', @@ -64,7 +74,17 @@ __PACKAGE__->register_method ({ my $vnetid = $param->{vnet}; - my $cfg = PVE::Network::SDN::Subnets::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Subnets::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'subnets'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{subnets}; + } else { + $cfg = PVE::Network::SDN::Subnets::config(); + } my @sids = PVE::Network::SDN::Subnets::sdn_subnets_ids($cfg); my $res = []; @@ -96,13 +116,34 @@ __PACKAGE__->register_method ({ subnet => get_standard_option('pve-sdn-subnet-id', { completion => \&PVE::Network::SDN::Subnets::complete_sdn_subnets, }), - }, + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, + }, }, returns => { type => 'object' }, code => sub { my ($param) = @_; - my $cfg = PVE::Network::SDN::Subnets::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Subnets::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'subnets'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{subnets}; + } else { + $cfg = PVE::Network::SDN::Subnets::config(); + } + my $scfg = &$api_sdn_subnets_config($cfg, $param->{subnet}); raise_param_exc({ vnet => "wrong vnet"}) if $param->{vnet} ne $scfg->{vnet}; diff --git a/PVE/API2/Network/SDN/Vnets.pm b/PVE/API2/Network/SDN/Vnets.pm index 0fbb747..5fe524b 100644 --- a/PVE/API2/Network/SDN/Vnets.pm +++ b/PVE/API2/Network/SDN/Vnets.pm @@ -33,10 +33,22 @@ my $api_sdn_vnets_config = sub { my $scfg = dclone(PVE::Network::SDN::Vnets::sdn_vnets_config($cfg, $id)); $scfg->{vnet} = $id; $scfg->{digest} = $cfg->{digest}; - + return $scfg; }; +my $api_sdn_vnets_deleted_config = sub { + my ($cfg, $running_cfg, $id) = @_; + + if (!$cfg->{ids}->{$id}) { + + my $vnet_cfg = dclone(PVE::Network::SDN::Vnets::sdn_vnets_config($running_cfg->{vnets}, $id)); + $vnet_cfg->{state} = "deleted"; + $vnet_cfg->{vnet} = $id; + return $vnet_cfg; + } +}; + __PACKAGE__->register_method ({ name => 'index', path => '', @@ -49,6 +61,18 @@ __PACKAGE__->register_method ({ }, parameters => { additionalProperties => 0, + properties => { + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, + }, }, returns => { type => 'array', @@ -64,7 +88,17 @@ __PACKAGE__->register_method ({ my $rpcenv = PVE::RPCEnvironment::get(); my $authuser = $rpcenv->get_user(); - my $cfg = PVE::Network::SDN::Vnets::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Vnets::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'vnets'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{vnets}; + } else { + $cfg = PVE::Network::SDN::Vnets::config(); + } my @sids = PVE::Network::SDN::Vnets::sdn_vnets_ids($cfg); my $res = []; @@ -93,13 +127,33 @@ __PACKAGE__->register_method ({ vnet => get_standard_option('pve-sdn-vnet-id', { completion => \&PVE::Network::SDN::Vnets::complete_sdn_vnets, }), + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, }, }, returns => { type => 'object' }, code => sub { my ($param) = @_; - my $cfg = PVE::Network::SDN::Vnets::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Vnets::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'vnets'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{vnets}; + } else { + $cfg = PVE::Network::SDN::Vnets::config(); + } return $api_sdn_vnets_config->($cfg, $param->{vnet}); }}); diff --git a/PVE/API2/Network/SDN/Zones.pm b/PVE/API2/Network/SDN/Zones.pm index a37df3d..512945c 100644 --- a/PVE/API2/Network/SDN/Zones.pm +++ b/PVE/API2/Network/SDN/Zones.pm @@ -38,6 +38,11 @@ my $api_sdn_zones_config = sub { $scfg->{nodes} = PVE::Network::SDN::Zones::Plugin->encode_value($scfg->{type}, 'nodes', $scfg->{nodes}); } + my $pending = $scfg->{pending}; + if ($pending->{nodes}) { + $pending->{nodes} = PVE::Network::SDN::Zones::Plugin->encode_value($scfg->{type}, 'nodes', $pending->{nodes}); + } + return $scfg; }; @@ -59,6 +64,16 @@ __PACKAGE__->register_method ({ enum => $sdn_zones_type_enum, optional => 1, }, + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + }, }, }, returns => { @@ -67,6 +82,10 @@ __PACKAGE__->register_method ({ type => "object", properties => { zone => { type => 'string'}, type => { type => 'string'}, + mtu => { type => 'integer', optional => 1 }, + pending => { optional => 1}, + state => { type => 'string', optional => 1}, + nodes => { type => 'string', optional => 1}, }, }, links => [ { rel => 'child', href => "{zone}" } ], @@ -77,8 +96,17 @@ __PACKAGE__->register_method ({ my $rpcenv = PVE::RPCEnvironment::get(); my $authuser = $rpcenv->get_user(); - - my $cfg = PVE::Network::SDN::Zones::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Zones::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'zones'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{zones}; + } else { + $cfg = PVE::Network::SDN::Zones::config(); + } my @sids = PVE::Network::SDN::Zones::sdn_zones_ids($cfg); my $res = []; @@ -110,13 +138,33 @@ __PACKAGE__->register_method ({ additionalProperties => 0, properties => { zone => get_standard_option('pve-sdn-zone-id'), + running => { + type => 'boolean', + optional => 1, + description => "Display running config.", + }, + pending => { + type => 'boolean', + optional => 1, + description => "Display pending config.", + } }, }, returns => { type => 'object' }, code => sub { my ($param) = @_; - my $cfg = PVE::Network::SDN::Zones::config(); + my $cfg = {}; + if($param->{pending}) { + my $running_cfg = PVE::Network::SDN::config(); + my $config = PVE::Network::SDN::Zones::config(); + $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'zones'); + } elsif ($param->{running}) { + my $running_cfg = PVE::Network::SDN::config(); + $cfg = $running_cfg->{zones}; + } else { + $cfg = PVE::Network::SDN::Zones::config(); + } return &$api_sdn_zones_config($cfg, $param->{zone}); }}); diff --git a/PVE/Network/SDN.pm b/PVE/Network/SDN.pm index f21de15..3cd73ff 100644 --- a/PVE/Network/SDN.pm +++ b/PVE/Network/SDN.pm @@ -81,6 +81,51 @@ sub config { return cfs_read_file($running_cfg); } +sub pending_config { + my ($running_cfg, $cfg, $type) = @_; + + my $pending = {}; + + my $running_objects = $running_cfg->{$type}->{ids}; + my $config_objects = $cfg->{ids}; + + foreach my $id (sort keys %{$running_objects}) { + my $running_object = $running_objects->{$id}; + my $config_object = $config_objects->{$id}; + foreach my $key (sort keys %{$running_object}) { + $pending->{$id}->{$key} = $running_object->{$key}; + if(!keys %{$config_object}) { + $pending->{$id}->{state} = "deleted"; + } elsif ($running_object->{$key} ne $config_object->{$key}) { + $pending->{$id}->{state} = "changed"; + } + } + } + + foreach my $id (sort keys %{$config_objects}) { + my $running_object = $running_objects->{$id}; + my $config_object = $config_objects->{$id}; + + foreach my $key (sort keys %{$config_object}) { + my $config_value = $config_object->{$key} if $config_object->{$key}; + my $running_value = $running_object->{$key} if $running_object->{$key}; + if($key eq 'type' || $key eq 'vnet') { + $pending->{$id}->{$key} = $config_value; + } else { + $pending->{$id}->{"pending"}->{$key} = $config_value if !defined($running_value) || ($config_value ne $running_value); + } + if(!keys %{$running_object}) { + $pending->{$id}->{state} = "new"; + } elsif (!defined($running_value) && defined($config_value)) { + $pending->{$id}->{state} = "changed"; + } + } + } + + return {ids => $pending}; + +} + sub commit_config { my $cfg = cfs_read_file($running_cfg); -- 2.39.2