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