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