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 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel