]> git.proxmox.com Git - pve-network.git/blobdiff - PVE/Network/SDN.pm
controllers: add generate_controller_rawconfig
[pve-network.git] / PVE / Network / SDN.pm
index ae0ef4f9538460f816890012b7db877c8f8deb7c..256a7c8b4e518e5d31fe24f2f3bba11fcf1de48d 100644 (file)
@@ -8,32 +8,39 @@ use JSON;
 
 use PVE::Network::SDN::Vnets;
 use PVE::Network::SDN::Zones;
+use PVE::Network::SDN::Controllers;
+use PVE::Network::SDN::Subnets;
 
 use PVE::Tools qw(extract_param dir_glob_regex run_command);
 use PVE::Cluster qw(cfs_read_file cfs_write_file cfs_lock_file);
 
 
-my $version_cfg = "sdn/.version";
+my $running_cfg = "sdn/.running-config";
 
-my $parse_version_cfg = sub {
+my $parse_running_cfg = sub {
     my ($filename, $raw) = @_;
 
-    return 0 if !defined($raw) || $raw eq '';
+    my $cfg = {};
 
-    warn "invalid sdn version '$raw'" if $raw !~ m/\d+$/;
+    return $cfg if !defined($raw) || $raw eq '';
 
-    return $raw,
+    eval {
+       $cfg = from_json($raw);
+    };
+    return {} if $@;
+
+    return $cfg;
 };
 
-my $write_version_cfg = sub {
-    my ($filename, $version) = @_;
+my $write_running_cfg = sub {
+    my ($filename, $cfg) = @_;
 
-    warn "invalid sdn version" if $version !~ m/\d+$/;
+    my $json = to_json($cfg);
 
-    return $version;
+    return $json;
 };
 
-PVE::Cluster::cfs_register_file($version_cfg, $parse_version_cfg, $write_version_cfg);
+PVE::Cluster::cfs_register_file($running_cfg, $parse_running_cfg, $write_running_cfg);
 
 
 # improve me : move status code inside plugins ?
@@ -70,24 +77,89 @@ sub status {
     return($zone_status, $vnet_status);
 }
 
+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 (!defined($config_object->{$key})) {
+               $pending->{$id}->{"pending"}->{$key} = 'deleted';
+               $pending->{$id}->{state} = "changed";
+           } elsif (PVE::Network::SDN::encode_value(undef, $key, $running_object->{$key})
+                        ne PVE::Network::SDN::encode_value(undef, $key, $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 = PVE::Network::SDN::encode_value(undef, $key, $config_object->{$key}) if $config_object->{$key};
+           my $running_value = PVE::Network::SDN::encode_value(undef, $key, $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 increase_version {
+}
+
+sub commit_config {
 
-    my $version = cfs_read_file($version_cfg);
+    my $cfg = cfs_read_file($running_cfg);
+    my $version = $cfg->{version};
 
-    if($version) {
+    if ($version) {
        $version++;
     } else {
        $version = 1;
     }
 
-    cfs_write_file($version_cfg, $version);
+    my $vnets_cfg = PVE::Network::SDN::Vnets::config();
+    my $zones_cfg = PVE::Network::SDN::Zones::config();
+    my $controllers_cfg = PVE::Network::SDN::Controllers::config();
+    my $subnets_cfg = PVE::Network::SDN::Subnets::config();
+
+    my $vnets = { ids => $vnets_cfg->{ids} };
+    my $zones = { ids => $zones_cfg->{ids} };
+    my $controllers = { ids => $controllers_cfg->{ids} };
+    my $subnets = { ids => $subnets_cfg->{ids} };
+
+     $cfg = { version => $version, vnets => $vnets, zones => $zones, controllers => $controllers, subnets => $subnets };
+
+    cfs_write_file($running_cfg, $cfg);
 }
 
 sub lock_sdn_config {
     my ($code, $errmsg) = @_;
 
-    cfs_lock_file($version_cfg, undef, $code);
+    cfs_lock_file($running_cfg, undef, $code);
 
     if (my $err = $@) {
         $errmsg ? die "$errmsg: $err" : die $err;
@@ -102,8 +174,9 @@ sub get_local_vnets {
 
     my $nodename = PVE::INotify::nodename();
 
-    my $vnets_cfg = PVE::Network::SDN::Vnets::config();
-    my $zones_cfg = PVE::Network::SDN::Zones::config();
+    my $cfg = PVE::Network::SDN::config();
+    my $vnets_cfg = $cfg->{vnets};
+    my $zones_cfg = $cfg->{zones};
 
     my @vnetids = PVE::Network::SDN::Vnets::sdn_vnets_ids($vnets_cfg);
 
@@ -113,6 +186,8 @@ sub get_local_vnets {
 
        my $vnet = PVE::Network::SDN::Vnets::sdn_vnets_config($vnets_cfg, $vnetid);
        my $zoneid = $vnet->{zone};
+       my $comments = $vnet->{alias};
+
        my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
 
        next if !$zoneid;
@@ -121,11 +196,39 @@ sub get_local_vnets {
        my $zone_config = PVE::Network::SDN::Zones::sdn_zones_config($zones_cfg, $zoneid);
 
        next if defined($zone_config->{nodes}) && !$zone_config->{nodes}->{$nodename};
-       $vnets->{$vnetid} = { type => 'vnet', active => '1' };
+       $vnets->{$vnetid} = { type => 'vnet', active => '1', comments => $comments };
     }
 
     return $vnets;
 }
 
+sub generate_zone_config {
+    my $raw_config = PVE::Network::SDN::Zones::generate_etc_network_config();
+    PVE::Network::SDN::Zones::write_etc_network_config($raw_config);
+}
+
+sub generate_controller_config {
+    my ($reload) = @_;
+
+    my $raw_config = PVE::Network::SDN::Controllers::generate_controller_config();
+    PVE::Network::SDN::Controllers::write_controller_config($raw_config);
+
+    PVE::Network::SDN::Controllers::reload_controller() if $reload;
+}
+
+sub encode_value {
+    my ($type, $key, $value) = @_;
+
+    if ($key eq 'nodes' || $key eq 'exitnodes') {
+        if(ref($value) eq 'HASH') {
+            return join(',', sort keys(%$value));
+        } else {
+            return $value;
+        }
+    }
+
+    return $value;
+}
+
 1;