X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=PVE%2FNetwork%2FSDN.pm;h=2e996e9e5304189bd788195cb9a608b79c6f6154;hb=c7bb4ac53a7346667658079ea9197f5e364c4b84;hp=9d8006ef7b0427475881e7bae6bcf8d362ef8db2;hpb=93dea3aad0be915c18dd3a020d99a7727be43efe;p=pve-network.git diff --git a/PVE/Network/SDN.pm b/PVE/Network/SDN.pm index 9d8006e..2e996e9 100644 --- a/PVE/Network/SDN.pm +++ b/PVE/Network/SDN.pm @@ -6,66 +6,12 @@ use warnings; use Data::Dumper; use JSON; +use PVE::Network::SDN::Zones; + use PVE::Tools qw(extract_param dir_glob_regex run_command); use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file); -use PVE::Network::SDN::Plugin; -use PVE::Network::SDN::VnetPlugin; -use PVE::Network::SDN::VlanPlugin; -use PVE::Network::SDN::VxlanPlugin; -use PVE::Network::SDN::FrrPlugin; - -PVE::Network::SDN::VnetPlugin->register(); -PVE::Network::SDN::VlanPlugin->register(); -PVE::Network::SDN::VxlanPlugin->register(); -PVE::Network::SDN::FrrPlugin->register(); -PVE::Network::SDN::Plugin->init(); - - -sub sdn_config { - my ($cfg, $sdnid, $noerr) = @_; - - die "no sdn ID specified\n" if !$sdnid; - - my $scfg = $cfg->{ids}->{$sdnid}; - die "sdn '$sdnid' does not exists\n" if (!$noerr && !$scfg); - - return $scfg; -} - -sub config { - my $config = cfs_read_file("sdn.cfg.new"); - $config = cfs_read_file("sdn.cfg") if !keys %{$config->{ids}}; - return $config; -} - -sub write_config { - my ($cfg) = @_; - - cfs_write_file("sdn.cfg.new", $cfg); -} - -sub lock_sdn_config { - my ($code, $errmsg) = @_; - cfs_lock_file("sdn.cfg.new", undef, $code); - if (my $err = $@) { - $errmsg ? die "$errmsg: $err" : die $err; - } -} - -sub sdn_ids { - my ($cfg) = @_; - - return keys %{$cfg->{ids}}; -} - -sub complete_sdn { - my ($cmdname, $pname, $cvalue) = @_; - - my $cfg = PVE::Network::SDN::config(); - - return $cmdname eq 'add' ? [] : [ PVE::Network::SDN::sdn_ids($cfg) ]; -} +# improve me : move status code inside plugins ? sub ifquery_check { @@ -93,152 +39,10 @@ sub ifquery_check { return $interfaces; } - -sub generate_etc_network_config { - - my $sdn_cfg = PVE::Cluster::cfs_read_file('sdn.cfg'); - return if !$sdn_cfg; - - #read main config for physical interfaces - my $current_config_file = "/etc/network/interfaces"; - my $fh = IO::File->new($current_config_file); - my $interfaces_config = PVE::INotify::read_etc_network_interfaces(1,$fh); - $fh->close(); - - #check uplinks - my $uplinks = {}; - foreach my $id (keys %{$interfaces_config->{ifaces}}) { - my $interface = $interfaces_config->{ifaces}->{$id}; - if (my $uplink = $interface->{'uplink-id'}) { - die "uplink-id $uplink is already defined on $uplinks->{$uplink}" if $uplinks->{$uplink}; - $interface->{name} = $id; - $uplinks->{$interface->{'uplink-id'}} = $interface; - } - } - - my $vnet_cfg = undef; - my $transport_cfg = undef; - - foreach my $id (keys %{$sdn_cfg->{ids}}) { - if ($sdn_cfg->{ids}->{$id}->{type} eq 'vnet') { - $vnet_cfg->{ids}->{$id} = $sdn_cfg->{ids}->{$id}; - } else { - $transport_cfg->{ids}->{$id} = $sdn_cfg->{ids}->{$id}; - } - } - - #generate configuration - my $config = {}; - foreach my $id (keys %{$vnet_cfg->{ids}}) { - my $vnet = $vnet_cfg->{ids}->{$id}; - my $zone = $vnet->{transportzone}; - - if(!$zone) { - warn "can't generate vnet $vnet : zone $zone don't exist"; - next; - } - - my $plugin_config = $transport_cfg->{ids}->{$zone}; - - if (!defined($plugin_config)) { - warn "can't generate vnet $vnet : zone $zone don't exist"; - next; - } - - my $plugin = PVE::Network::SDN::Plugin->lookup($plugin_config->{type}); - $plugin->generate_sdn_config($plugin_config, $zone, $id, $vnet, $uplinks, $config); - } - - my $network_config = $config->{network}; - my $raw_network_config = ""; - foreach my $iface (keys %$network_config) { - $raw_network_config .= "\n"; - $raw_network_config .= "auto $iface\n"; - $raw_network_config .= "iface $iface\n"; - foreach my $option (@{$network_config->{$iface}}) { - $raw_network_config .= "\t$option\n"; - } - } - - my $frr_config = $config->{frr}; - my $raw_frr_config = ""; - foreach my $asn (keys %$frr_config) { - $raw_frr_config .= "router bgp $asn"; - foreach my $option (@{$frr_config->{$asn}}) { - $raw_frr_config .= " $option\n"; - } - } - - return wantarray ? ($raw_network_config, $raw_frr_config) : $raw_network_config; -} - -sub write_etc_network_config { - my ($rawconfig) = @_; - - return if !$rawconfig; - my $sdn_interfaces_file = "/etc/network/interfaces.d/sdn"; - - my $writefh = IO::File->new($sdn_interfaces_file,">"); - print $writefh $rawconfig; - $writefh->close(); -} - - sub status { - my $cluster_sdn_file = "/etc/pve/sdn.cfg"; - my $local_sdn_file = "/etc/network/interfaces.d/sdn"; - my $err_config = undef; - - return if !-e $cluster_sdn_file; - - if (!-e $local_sdn_file) { - warn "local sdn network configuration is not yet generated, please reload"; - $err_config = 'pending'; - } else { - # fixme : use some kind of versioning info? - my $cluster_sdn_timestamp = (stat($cluster_sdn_file))[9]; - my $local_sdn_timestamp = (stat($local_sdn_file))[9]; - - if ($local_sdn_timestamp < $cluster_sdn_timestamp) { - warn "local sdn network configuration is too old, please reload"; - $err_config = 'unknown'; - } - } - - my $status = ifquery_check(); - - my $network_cfg = PVE::Cluster::cfs_read_file('sdn.cfg'); - my $vnet_cfg = undef; - my $transport_cfg = undef; - - my $vnet_status = {}; - my $transport_status = {}; - - foreach my $id (keys %{$network_cfg->{ids}}) { - if ($network_cfg->{ids}->{$id}->{type} eq 'vnet') { - my $transportzone = $network_cfg->{ids}->{$id}->{transportzone}; - $vnet_status->{$id}->{transportzone} = $transportzone; - $transport_status->{$transportzone}->{status} = 'available' if !defined($transport_status->{$transportzone}->{status}); - - if($err_config) { - $vnet_status->{$id}->{status} = $err_config; - $transport_status->{$transportzone}->{status} = $err_config; - } elsif ($status->{$id}->{status} && $status->{$id}->{status} eq 'pass') { - $vnet_status->{$id}->{status} = 'available'; - my $bridgeport = $status->{$id}->{config}->{'bridge-ports'}; - - if ($status->{$bridgeport}->{status} && $status->{$bridgeport}->{status} ne 'pass') { - $vnet_status->{$id}->{status} = 'error'; - $transport_status->{$transportzone}->{status} = 'error'; - } - } else { - $vnet_status->{$id}->{status} = 'error'; - $transport_status->{$transportzone}->{status} = 'error'; - } - } - } - return($transport_status, $vnet_status); + my ($zone_status, $vnet_status) = PVE::Network::SDN::Zones::status(); + return($zone_status, $vnet_status); } 1;