[pve-devel] [PATCH pve-network 36/38] zones: auto find controller
Alexandre Derumier
aderumier at odiso.com
Sun Nov 8 15:19:38 CET 2020
We can have only 1 controller of same type by node, avoid to define it in zone plugin.
This allow to define a global controller definition for all nodes,
and if needed, allow to redefine a controller for a specific node.
(for evpn with Ebgp, where we need to be able change peers/AS or other options by node)
---
PVE/Network/SDN/Controllers.pm | 33 +++++++++++++++--------
PVE/Network/SDN/Controllers/EvpnPlugin.pm | 10 ++++++-
PVE/Network/SDN/Controllers/Plugin.pm | 1 +
PVE/Network/SDN/Zones.pm | 6 ++++-
PVE/Network/SDN/Zones/EvpnPlugin.pm | 28 ++++++++++++-------
PVE/Network/SDN/Zones/Plugin.pm | 5 ++++
6 files changed, 61 insertions(+), 22 deletions(-)
diff --git a/PVE/Network/SDN/Controllers.pm b/PVE/Network/SDN/Controllers.pm
index f652d7f..be110b7 100644
--- a/PVE/Network/SDN/Controllers.pm
+++ b/PVE/Network/SDN/Controllers.pm
@@ -95,19 +95,25 @@ sub generate_controller_config {
#generate configuration
my $config = {};
- foreach my $id (keys %{$controller_cfg->{ids}}) {
- my $plugin_config = $controller_cfg->{ids}->{$id};
- my $plugin = PVE::Network::SDN::Controllers::Plugin->lookup($plugin_config->{type});
- $plugin->generate_controller_config($plugin_config, $plugin_config, $id, $uplinks, $config);
- }
+ my $nodename = PVE::INotify::nodename();
+ my $generated_controller_config = {};
foreach my $id (keys %{$zone_cfg->{ids}}) {
my $plugin_config = $zone_cfg->{ids}->{$id};
- my $controllerid = $plugin_config->{controller};
- next if !$controllerid;
- my $controller = $controller_cfg->{ids}->{$controllerid};
+ my $controller;
+ my $controllerid;
+ if ($controllerid = $plugin_config->{controller}) {
+ $controller = $controller_cfg->{ids}->{$controllerid};
+ } else {
+ my $zone_plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
+ $controllerid = $zone_plugin->find_controller($plugin_config, $nodename, $controller_cfg);
+ $controller = $controller_cfg->{ids}->{$controllerid} if $controllerid;
+ }
if ($controller) {
my $controller_plugin = PVE::Network::SDN::Controllers::Plugin->lookup($controller->{type});
+
+ $controller_plugin->generate_controller_config($controller, $controller, $controllerid, $uplinks, $config) if !$generated_controller_config->{$controllerid};
+ $generated_controller_config->{$controllerid} = 1;
$controller_plugin->generate_controller_zone_config($plugin_config, $controller, $id, $uplinks, $config);
}
}
@@ -118,9 +124,14 @@ sub generate_controller_config {
next if !$zoneid;
my $zone = $zone_cfg->{ids}->{$zoneid};
next if !$zone;
- my $controllerid = $zone->{controller};
- next if !$controllerid;
- my $controller = $controller_cfg->{ids}->{$controllerid};
+ my $controller;
+ if (my $controllerid = $plugin_config->{controller}) {
+ $controller = $controller_cfg->{ids}->{$controllerid};
+ } else {
+ my $zone_plugin = PVE::Network::SDN::Zones::Plugin->lookup($zone->{type});
+ my $controllerid = $zone_plugin->find_controller($zone, $nodename, $controller_cfg);
+ $controller = $controller_cfg->{ids}->{$controllerid} if $controllerid;
+ }
if ($controller) {
my $controller_plugin = PVE::Network::SDN::Controllers::Plugin->lookup($controller->{type});
$controller_plugin->generate_controller_vnet_config($plugin_config, $controller, $zoneid, $id, $config);
diff --git a/PVE/Network/SDN/Controllers/EvpnPlugin.pm b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
index d82de2a..ca7be5b 100644
--- a/PVE/Network/SDN/Controllers/EvpnPlugin.pm
+++ b/PVE/Network/SDN/Controllers/EvpnPlugin.pm
@@ -36,6 +36,7 @@ sub properties {
sub options {
return {
+ 'node' => { optional => 1 },
'asn' => { optional => 0 },
'peers' => { optional => 0 },
'gateway-nodes' => { optional => 1 },
@@ -165,10 +166,17 @@ sub on_update_hook {
# we can only have 1 evpn controller / 1 asn by server
+ my $current_controller = $controller_cfg->{ids}->{$controllerid};
+
foreach my $id (keys %{$controller_cfg->{ids}}) {
next if $id eq $controllerid;
my $controller = $controller_cfg->{ids}->{$id};
- die "only 1 evpn controller can be defined" if $controller->{type} eq "evpn";
+ next if $controller->{type} ne "evpn";
+ if(!$controller->{node} && !$current_controller->{node}) {
+ die "only 1 global evpn controller can be defined";
+ } else {
+ die "only 1 evpn controller can be defined for a specific node" if $controller->{node} eq $current_controller->{node};
+ }
}
}
diff --git a/PVE/Network/SDN/Controllers/Plugin.pm b/PVE/Network/SDN/Controllers/Plugin.pm
index 06cd576..acdfda0 100644
--- a/PVE/Network/SDN/Controllers/Plugin.pm
+++ b/PVE/Network/SDN/Controllers/Plugin.pm
@@ -40,6 +40,7 @@ my $defaultData = {
type => 'string', format => 'pve-configid',
type => 'string',
},
+ node => get_standard_option('pve-node', { optional => 1 }),
controller => get_standard_option('pve-sdn-controller-id',
{ completion => \&PVE::Network::SDN::complete_sdn_controller }),
},
diff --git a/PVE/Network/SDN/Zones.pm b/PVE/Network/SDN/Zones.pm
index 1f225dc..bff5cd7 100644
--- a/PVE/Network/SDN/Zones.pm
+++ b/PVE/Network/SDN/Zones.pm
@@ -124,12 +124,16 @@ sub generate_etc_network_config {
next if defined($plugin_config->{nodes}) && !$plugin_config->{nodes}->{$nodename};
+ my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
+
my $controller;
if (my $controllerid = $plugin_config->{controller}) {
$controller = $controller_cfg->{ids}->{$controllerid};
+ } else {
+ my $controllerid = $plugin->find_controller($plugin_config, $nodename, $controller_cfg);
+ $controller = $controller_cfg->{ids}->{$controllerid} if $controllerid;
}
- my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
eval {
$plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $controller, $subnet_cfg, $interfaces_config, $config);
};
diff --git a/PVE/Network/SDN/Zones/EvpnPlugin.pm b/PVE/Network/SDN/Zones/EvpnPlugin.pm
index 5338a1b..495d134 100644
--- a/PVE/Network/SDN/Zones/EvpnPlugin.pm
+++ b/PVE/Network/SDN/Zones/EvpnPlugin.pm
@@ -35,7 +35,6 @@ sub options {
return {
nodes => { optional => 1},
'vrf-vxlan' => { optional => 0 },
- 'controller' => { optional => 0 },
mtu => { optional => 1 },
dns => { optional => 1 },
reversedns => { optional => 1 },
@@ -156,17 +155,28 @@ sub generate_sdn_config {
return $config;
}
+sub find_controller {
+ my ($class, $plugin_config, $nodename, $controller_cfg) = @_;
+
+ #return global controller or more precise if node is defined
+ my $found_controller = undef;
+ foreach my $id (keys %{$controller_cfg->{ids}}) {
+ my $controller = $controller_cfg->{ids}->{$id};
+ next if $controller->{type} ne 'evpn';
+ if(!$controller->{node}) {
+ $found_controller = $id if !$found_controller;
+ } else {
+ next if $controller->{node} ne $nodename;
+ $found_controller = $id;
+ }
+ }
+ die "can't find any evpn controller" if !$found_controller;
+ return $found_controller;
+}
+
sub on_update_hook {
my ($class, $zoneid, $zone_cfg, $controller_cfg) = @_;
- # verify that controller exist
- my $controller = $zone_cfg->{ids}->{$zoneid}->{controller};
- if (!defined($controller_cfg->{ids}->{$controller})) {
- die "controller $controller don't exist";
- } else {
- die "$controller is not a evpn controller type" if $controller_cfg->{ids}->{$controller}->{type} ne 'evpn';
- }
-
#vrf-vxlan need to be defined
my $vrfvxlan = $zone_cfg->{ids}->{$zoneid}->{'vrf-vxlan'};
diff --git a/PVE/Network/SDN/Zones/Plugin.pm b/PVE/Network/SDN/Zones/Plugin.pm
index 6fc13eb..bd46e45 100644
--- a/PVE/Network/SDN/Zones/Plugin.pm
+++ b/PVE/Network/SDN/Zones/Plugin.pm
@@ -126,6 +126,11 @@ sub controller_reload {
die "please implement inside plugin";
}
+sub find_controller {
+ my ($class, $plugin_config, $nodename, $controller_cfg) = @_;
+ return undef;
+}
+
sub on_delete_hook {
my ($class, $zoneid, $vnet_cfg) = @_;
--
2.20.1
More information about the pve-devel
mailing list