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