1 package PVE
::Network
::SDN
;
9 use PVE
::Network
::SDN
::Vnets
;
10 use PVE
::Network
::SDN
::Zones
;
11 use PVE
::Network
::SDN
::Controllers
;
12 use PVE
::Network
::SDN
::Subnets
;
14 use PVE
::Tools
qw(extract_param dir_glob_regex run_command);
15 use PVE
::Cluster
qw(cfs_read_file cfs_write_file cfs_lock_file);
18 my $running_cfg = "sdn/.running-config";
20 my $parse_running_cfg = sub {
21 my ($filename, $raw) = @_;
25 return $cfg if !defined($raw) || $raw eq '';
28 $cfg = from_json
($raw);
35 my $write_running_cfg = sub {
36 my ($filename, $cfg) = @_;
38 my $json = to_json
($cfg);
43 PVE
::Cluster
::cfs_register_file
($running_cfg, $parse_running_cfg, $write_running_cfg);
46 # improve me : move status code inside plugins ?
50 my $cmd = ['ifquery', '-a', '-c', '-o','json'];
53 my $reader = sub { $result .= shift };
56 run_command
($cmd, outfunc
=> $reader);
59 my $resultjson = decode_json
($result);
62 foreach my $interface (@$resultjson) {
63 my $name = $interface->{name
};
64 $interfaces->{$name} = {
65 status
=> $interface->{status
},
66 config
=> $interface->{config
},
67 config_status
=> $interface->{config_status
},
76 my ($zone_status, $vnet_status) = PVE
::Network
::SDN
::Zones
::status
();
77 return($zone_status, $vnet_status);
81 return cfs_read_file
($running_cfg);
85 my ($running_cfg, $cfg, $type) = @_;
89 my $running_objects = $running_cfg->{$type}->{ids
};
90 my $config_objects = $cfg->{ids
};
92 foreach my $id (sort keys %{$running_objects}) {
93 my $running_object = $running_objects->{$id};
94 my $config_object = $config_objects->{$id};
95 foreach my $key (sort keys %{$running_object}) {
96 $pending->{$id}->{$key} = $running_object->{$key};
97 if(!keys %{$config_object}) {
98 $pending->{$id}->{state} = "deleted";
99 } elsif ($running_object->{$key} ne $config_object->{$key}) {
100 $pending->{$id}->{state} = "changed";
105 foreach my $id (sort keys %{$config_objects}) {
106 my $running_object = $running_objects->{$id};
107 my $config_object = $config_objects->{$id};
109 foreach my $key (sort keys %{$config_object}) {
110 my $config_value = $config_object->{$key} if $config_object->{$key};
111 my $running_value = $running_object->{$key} if $running_object->{$key};
112 if($key eq 'type' || $key eq 'vnet') {
113 $pending->{$id}->{$key} = $config_value;
115 $pending->{$id}->{"pending"}->{$key} = $config_value if !defined($running_value) || ($config_value ne $running_value);
117 if(!keys %{$running_object}) {
118 $pending->{$id}->{state} = "new";
119 } elsif (!defined($running_value) && defined($config_value)) {
120 $pending->{$id}->{state} = "changed";
125 return {ids
=> $pending};
131 my $cfg = cfs_read_file
($running_cfg);
132 my $version = $cfg->{version
};
140 my $vnets_cfg = PVE
::Network
::SDN
::Vnets
::config
();
141 my $zones_cfg = PVE
::Network
::SDN
::Zones
::config
();
142 my $controllers_cfg = PVE
::Network
::SDN
::Controllers
::config
();
143 my $subnets_cfg = PVE
::Network
::SDN
::Subnets
::config
();
145 my $vnets = { ids
=> $vnets_cfg->{ids
} };
146 my $zones = { ids
=> $zones_cfg->{ids
} };
147 my $controllers = { ids
=> $controllers_cfg->{ids
} };
148 my $subnets = { ids
=> $subnets_cfg->{ids
} };
150 $cfg = { version
=> $version, vnets
=> $vnets, zones
=> $zones, controllers
=> $controllers, subnets
=> $subnets };
152 cfs_write_file
($running_cfg, $cfg);
155 sub lock_sdn_config
{
156 my ($code, $errmsg) = @_;
158 cfs_lock_file
($running_cfg, undef, $code);
161 $errmsg ?
die "$errmsg: $err" : die $err;
165 sub get_local_vnets
{
167 my $rpcenv = PVE
::RPCEnvironment
::get
();
169 my $authuser = $rpcenv->get_user();
171 my $nodename = PVE
::INotify
::nodename
();
173 my $cfg = PVE
::Network
::SDN
::config
();
174 my $vnets_cfg = $cfg->{vnets
};
175 my $zones_cfg = $cfg->{zones
};
177 my @vnetids = PVE
::Network
::SDN
::Vnets
::sdn_vnets_ids
($vnets_cfg);
181 foreach my $vnetid (@vnetids) {
183 my $vnet = PVE
::Network
::SDN
::Vnets
::sdn_vnets_config
($vnets_cfg, $vnetid);
184 my $zoneid = $vnet->{zone
};
185 my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
188 next if !$rpcenv->check_any($authuser, "/sdn/zones/$zoneid", $privs, 1);
190 my $zone_config = PVE
::Network
::SDN
::Zones
::sdn_zones_config
($zones_cfg, $zoneid);
192 next if defined($zone_config->{nodes
}) && !$zone_config->{nodes
}->{$nodename};
193 $vnets->{$vnetid} = { type
=> 'vnet', active
=> '1' };
199 sub generate_zone_config
{
200 my $raw_config = PVE
::Network
::SDN
::Zones
::generate_etc_network_config
();
201 PVE
::Network
::SDN
::Zones
::write_etc_network_config
($raw_config);
204 sub generate_controller_config
{
207 my $raw_config = PVE
::Network
::SDN
::Controllers
::generate_controller_config
();
208 PVE
::Network
::SDN
::Controllers
::write_controller_config
($raw_config);
210 PVE
::Network
::SDN
::Controllers
::reload_controller
() if $reload;