]> git.proxmox.com Git - pve-network.git/blame - PVE/API2/Network/SDN/Zones.pm
api: zones: code/indentation/format cleanups
[pve-network.git] / PVE / API2 / Network / SDN / Zones.pm
CommitLineData
4140be9e
AD
1package PVE::API2::Network::SDN::Zones;
2
3use strict;
4use warnings;
5
7f507618
TL
6use Storable qw(dclone);
7
8use PVE::Cluster qw(cfs_read_file cfs_write_file);
9use PVE::Exception qw(raise raise_param_exc);
10use PVE::JSONSchema qw(get_standard_option);
11use PVE::RPCEnvironment;
4140be9e
AD
12use PVE::SafeSyslog;
13use PVE::Tools qw(extract_param);
7f507618 14
4ad78442 15use PVE::Network::SDN::Dns;
7f507618
TL
16use PVE::Network::SDN::Subnets;
17use PVE::Network::SDN::Vnets;
18use PVE::Network::SDN;
19
4140be9e
AD
20use PVE::Network::SDN::Zones::EvpnPlugin;
21use PVE::Network::SDN::Zones::FaucetPlugin;
7f507618
TL
22use PVE::Network::SDN::Zones::Plugin;
23use PVE::Network::SDN::Zones::QinQPlugin;
880ae857 24use PVE::Network::SDN::Zones::SimplePlugin;
7f507618
TL
25use PVE::Network::SDN::Zones::VlanPlugin;
26use PVE::Network::SDN::Zones::VxlanPlugin;
27use PVE::Network::SDN::Zones;
4140be9e
AD
28
29use PVE::RESTHandler;
4140be9e
AD
30use base qw(PVE::RESTHandler);
31
32my $sdn_zones_type_enum = PVE::Network::SDN::Zones::Plugin->lookup_types();
33
34my $api_sdn_zones_config = sub {
35 my ($cfg, $id) = @_;
36
37 my $scfg = dclone(PVE::Network::SDN::Zones::sdn_zones_config($cfg, $id));
38 $scfg->{zone} = $id;
39 $scfg->{digest} = $cfg->{digest};
40
c2b9c173 41 if ($scfg->{nodes}) {
e382bf71
AD
42 $scfg->{nodes} = PVE::Network::SDN::encode_value($scfg->{type}, 'nodes', $scfg->{nodes});
43 }
44
45 if ($scfg->{exitnodes}) {
46 $scfg->{exitnodes} = PVE::Network::SDN::encode_value($scfg->{type}, 'exitnodes', $scfg->{exitnodes});
c2b9c173
AD
47 }
48
6f5f42e4
AD
49 my $pending = $scfg->{pending};
50 if ($pending->{nodes}) {
e382bf71
AD
51 $pending->{nodes} = PVE::Network::SDN::encode_value($scfg->{type}, 'nodes', $pending->{nodes});
52 }
53
54 if ($pending->{exitnodes}) {
55 $pending->{exitnodes} = PVE::Network::SDN::encode_value($scfg->{type}, 'exitnodes', $pending->{exitnodes});
6f5f42e4
AD
56 }
57
4140be9e
AD
58 return $scfg;
59};
60
61__PACKAGE__->register_method ({
62 name => 'index',
63 path => '',
64 method => 'GET',
65 description => "SDN zones index.",
66 permissions => {
3551b612 67 description => "Only list entries where you have 'SDN.Audit' or 'SDN.Allocate' permissions on '/sdn/zones/<zone>'",
4140be9e
AD
68 user => 'all',
69 },
70 parameters => {
71 additionalProperties => 0,
72 properties => {
73 type => {
7f507618 74 description => "Only list SDN zones of specific type",
4140be9e
AD
75 type => 'string',
76 enum => $sdn_zones_type_enum,
77 optional => 1,
78 },
6f5f42e4
AD
79 running => {
80 type => 'boolean',
81 optional => 1,
82 description => "Display running config.",
83 },
84 pending => {
85 type => 'boolean',
86 optional => 1,
87 description => "Display pending config.",
88 },
4140be9e
AD
89 },
90 },
91 returns => {
92 type => 'array',
93 items => {
94 type => "object",
0f700635 95 properties => { zone => { type => 'string'},
4140be9e 96 type => { type => 'string'},
6f5f42e4 97 mtu => { type => 'integer', optional => 1 },
4ad78442
AD
98 dns => { type => 'string', optional => 1},
99 reversedns => { type => 'string', optional => 1},
100 dnszone => { type => 'string', optional => 1},
331e2330 101 ipam => { type => 'string', optional => 1},
6f5f42e4
AD
102 pending => { optional => 1},
103 state => { type => 'string', optional => 1},
104 nodes => { type => 'string', optional => 1},
4140be9e
AD
105 },
106 },
107 links => [ { rel => 'child', href => "{zone}" } ],
108 },
109 code => sub {
110 my ($param) = @_;
111
112 my $rpcenv = PVE::RPCEnvironment::get();
113 my $authuser = $rpcenv->get_user();
114
6f5f42e4 115 my $cfg = {};
7f507618 116 if ($param->{pending}) {
d73c7c36 117 my $running_cfg = PVE::Network::SDN::running_config();
6f5f42e4
AD
118 my $config = PVE::Network::SDN::Zones::config();
119 $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'zones');
120 } elsif ($param->{running}) {
d73c7c36 121 my $running_cfg = PVE::Network::SDN::running_config();
6f5f42e4
AD
122 $cfg = $running_cfg->{zones};
123 } else {
124 $cfg = PVE::Network::SDN::Zones::config();
125 }
4140be9e
AD
126
127 my @sids = PVE::Network::SDN::Zones::sdn_zones_ids($cfg);
128 my $res = [];
7f507618 129 for my $id (@sids) {
3551b612
AD
130 my $privs = [ 'SDN.Audit', 'SDN.Allocate' ];
131 next if !$rpcenv->check_any($authuser, "/sdn/zones/$id", $privs, 1);
4140be9e
AD
132
133 my $scfg = &$api_sdn_zones_config($cfg, $id);
134 next if $param->{type} && $param->{type} ne $scfg->{type};
135
136 my $plugin_config = $cfg->{ids}->{$id};
137 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($plugin_config->{type});
138 push @$res, $scfg;
139 }
140
141 return $res;
142 }});
143
144__PACKAGE__->register_method ({
145 name => 'read',
146 path => '{zone}',
147 method => 'GET',
148 description => "Read sdn zone configuration.",
3551b612
AD
149 permissions => {
150 check => ['perm', '/sdn/zones/{zone}', ['SDN.Allocate']],
151 },
4140be9e
AD
152
153 parameters => {
154 additionalProperties => 0,
155 properties => {
156 zone => get_standard_option('pve-sdn-zone-id'),
6f5f42e4
AD
157 running => {
158 type => 'boolean',
159 optional => 1,
160 description => "Display running config.",
161 },
162 pending => {
163 type => 'boolean',
164 optional => 1,
165 description => "Display pending config.",
166 }
4140be9e
AD
167 },
168 },
169 returns => { type => 'object' },
170 code => sub {
171 my ($param) = @_;
172
6f5f42e4 173 my $cfg = {};
7f507618 174 if ($param->{pending}) {
d73c7c36 175 my $running_cfg = PVE::Network::SDN::running_config();
6f5f42e4
AD
176 my $config = PVE::Network::SDN::Zones::config();
177 $cfg = PVE::Network::SDN::pending_config($running_cfg, $config, 'zones');
178 } elsif ($param->{running}) {
d73c7c36 179 my $running_cfg = PVE::Network::SDN::running_config();
6f5f42e4
AD
180 $cfg = $running_cfg->{zones};
181 } else {
182 $cfg = PVE::Network::SDN::Zones::config();
183 }
4140be9e
AD
184
185 return &$api_sdn_zones_config($cfg, $param->{zone});
186 }});
187
188__PACKAGE__->register_method ({
189 name => 'create',
190 protected => 1,
191 path => '',
192 method => 'POST',
193 description => "Create a new sdn zone object.",
3551b612
AD
194 permissions => {
195 check => ['perm', '/sdn/zones', ['SDN.Allocate']],
196 },
4140be9e
AD
197 parameters => PVE::Network::SDN::Zones::Plugin->createSchema(),
198 returns => { type => 'null' },
199 code => sub {
200 my ($param) = @_;
201
202 my $type = extract_param($param, 'type');
203 my $id = extract_param($param, 'zone');
204
205 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($type);
206 my $opts = $plugin->check_config($id, $param, 1, 1);
207
7f507618
TL
208 PVE::Cluster::check_cfs_quorum();
209 mkdir("/etc/pve/sdn");
45c3f15c 210
7f507618
TL
211 PVE::Network::SDN::lock_sdn_config(sub {
212 my $zone_cfg = PVE::Network::SDN::Zones::config();
213 my $controller_cfg = PVE::Network::SDN::Controllers::config();
214 my $dns_cfg = PVE::Network::SDN::Dns::config();
4140be9e 215
7f507618
TL
216 my $scfg = undef;
217 if ($scfg = PVE::Network::SDN::Zones::sdn_zones_config($zone_cfg, $id, 1)) {
218 die "sdn zone object ID '$id' already defined\n";
219 }
4140be9e 220
7f507618
TL
221 my $dnsserver = $opts->{dns};
222 raise_param_exc({ dns => "$dnsserver don't exist"})
223 if $dnsserver && !$dns_cfg->{ids}->{$dnsserver};
4140be9e 224
7f507618
TL
225 my $reversednsserver = $opts->{reversedns};
226 raise_param_exc({ reversedns => "$reversednsserver don't exist"})
227 if $reversednsserver && !$dns_cfg->{ids}->{$reversednsserver};
331e2330 228
7f507618
TL
229 my $dnszone = $opts->{dnszone};
230 raise_param_exc({ dnszone => "missing dns server"})
231 if $dnszone && !$dnsserver;
4140be9e 232
7f507618
TL
233 my $ipam = $opts->{ipam};
234 my $ipam_cfg = PVE::Network::SDN::Ipams::config();
235 raise_param_exc({ ipam => "$ipam not existing"}) if $ipam && !$ipam_cfg->{ids}->{$ipam};
4140be9e 236
7f507618
TL
237 $zone_cfg->{ids}->{$id} = $opts;
238 $plugin->on_update_hook($id, $zone_cfg, $controller_cfg);
239
240 PVE::Network::SDN::Zones::write_config($zone_cfg);
4140be9e 241
7f507618
TL
242 }, "create sdn zone object failed");
243
244 return;
4140be9e
AD
245 }});
246
4140be9e
AD
247__PACKAGE__->register_method ({
248 name => 'update',
249 protected => 1,
250 path => '{zone}',
251 method => 'PUT',
252 description => "Update sdn zone object configuration.",
3551b612
AD
253 permissions => {
254 check => ['perm', '/sdn/zones', ['SDN.Allocate']],
255 },
4140be9e
AD
256 parameters => PVE::Network::SDN::Zones::Plugin->updateSchema(),
257 returns => { type => 'null' },
258 code => sub {
259 my ($param) = @_;
260
261 my $id = extract_param($param, 'zone');
262 my $digest = extract_param($param, 'digest');
263
7f507618 264 PVE::Network::SDN::lock_sdn_config(sub {
a2b32a94
AD
265 my $zone_cfg = PVE::Network::SDN::Zones::config();
266 my $controller_cfg = PVE::Network::SDN::Controllers::config();
4ad78442 267 my $dns_cfg = PVE::Network::SDN::Dns::config();
4140be9e 268
a2b32a94 269 PVE::SectionConfig::assert_if_modified($zone_cfg, $digest);
4140be9e 270
a2b32a94 271 my $scfg = PVE::Network::SDN::Zones::sdn_zones_config($zone_cfg, $id);
4140be9e
AD
272
273 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($scfg->{type});
274 my $opts = $plugin->check_config($id, $param, 0, 1);
275
7f507618 276 if ($opts->{ipam} && !$scfg->{ipam} || $opts->{ipam} ne $scfg->{ipam}) {
e8736dac 277
7f507618 278 # don't allow ipam change if subnet are defined for now, need to implement resync ipam content
e8736dac 279 my $subnets_cfg = PVE::Network::SDN::Subnets::config();
7f507618 280 for my $subnetid (sort keys %{$subnets_cfg->{ids}}) {
e8736dac 281 my $subnet = PVE::Network::SDN::Subnets::sdn_subnets_config($subnets_cfg, $subnetid);
7f507618
TL
282 raise_param_exc({ ipam => "can't change ipam if a subnet is already defined in this zone"})
283 if $subnet->{zone} eq $id;
e8736dac
AD
284 }
285 }
286
7f507618 287 for my $k (%$opts) {
4140be9e
AD
288 $scfg->{$k} = $opts->{$k};
289 }
290
4ad78442 291 my $dnsserver = $opts->{dns};
4ad78442 292 raise_param_exc({ dns => "$dnsserver don't exist"}) if $dnsserver && !$dns_cfg->{ids}->{$dnsserver};
7f507618
TL
293
294 my $reversednsserver = $opts->{reversedns};
4ad78442 295 raise_param_exc({ reversedns => "$reversednsserver don't exist"}) if $reversednsserver && !$dns_cfg->{ids}->{$reversednsserver};
7f507618
TL
296
297 my $dnszone = $opts->{dnszone};
4ad78442
AD
298 raise_param_exc({ dnszone => "missing dns server"}) if $dnszone && !$dnsserver;
299
331e2330
AD
300 my $ipam = $opts->{ipam};
301 my $ipam_cfg = PVE::Network::SDN::Ipams::config();
302 raise_param_exc({ ipam => "$ipam not existing"}) if $ipam && !$ipam_cfg->{ids}->{$ipam};
303
a2b32a94 304 $plugin->on_update_hook($id, $zone_cfg, $controller_cfg);
4140be9e 305
a2b32a94 306 PVE::Network::SDN::Zones::write_config($zone_cfg);
4140be9e 307
7f507618 308 }, "update sdn zone object failed");
4140be9e 309
7f507618 310 return;
4140be9e
AD
311 }});
312
313__PACKAGE__->register_method ({
314 name => 'delete',
315 protected => 1,
316 path => '{zone}',
317 method => 'DELETE',
318 description => "Delete sdn zone object configuration.",
3551b612
AD
319 permissions => {
320 check => ['perm', '/sdn/zones', ['SDN.Allocate']],
321 },
4140be9e 322 parameters => {
7f507618 323 additionalProperties => 0,
4140be9e
AD
324 properties => {
325 zone => get_standard_option('pve-sdn-zone-id', {
7f507618
TL
326 completion => \&PVE::Network::SDN::Zones::complete_sdn_zones,
327 }),
4140be9e
AD
328 },
329 },
330 returns => { type => 'null' },
331 code => sub {
332 my ($param) = @_;
333
334 my $id = extract_param($param, 'zone');
335
7f507618
TL
336 PVE::Network::SDN::lock_sdn_config(sub {
337 my $cfg = PVE::Network::SDN::Zones::config();
338 my $scfg = PVE::Network::SDN::Zones::sdn_zones_config($cfg, $id);
4140be9e 339
7f507618
TL
340 my $plugin = PVE::Network::SDN::Zones::Plugin->lookup($scfg->{type});
341 my $vnet_cfg = PVE::Network::SDN::Vnets::config();
4140be9e 342
7f507618 343 $plugin->on_delete_hook($id, $vnet_cfg);
4140be9e 344
7f507618 345 delete $cfg->{ids}->{$id};
4140be9e 346
7f507618
TL
347 PVE::Network::SDN::Zones::write_config($cfg);
348 }, "delete sdn zone object failed");
4140be9e 349
7f507618 350 return;
4140be9e
AD
351 }});
352
3531;