do not use triggers
[pve-firewall.git] / src / PVE / API2 / Firewall / Aliases.pm
CommitLineData
81d574a7
DM
1package PVE::API2::Firewall::AliasesBase;
2
3use strict;
4use warnings;
5use PVE::Exception qw(raise raise_param_exc);
6use PVE::JSONSchema qw(get_standard_option);
7
8use PVE::Firewall;
9
10use base qw(PVE::RESTHandler);
11
12my $api_properties = {
13 cidr => {
14 description => "Network/IP specification in CIDR format.",
ae029a88 15 type => 'string', format => 'IPorCIDR',
81d574a7
DM
16 },
17 name => get_standard_option('pve-fw-alias'),
cdc39d63
DM
18 rename => get_standard_option('pve-fw-alias', {
19 description => "Rename an existing alias.",
20 optional => 1,
21 }),
81d574a7
DM
22 comment => {
23 type => 'string',
24 optional => 1,
cdc39d63 25 },
81d574a7
DM
26};
27
28sub load_config {
29 my ($class, $param) = @_;
30
31 die "implement this in subclass";
32
33 #return ($fw_conf, $rules);
34}
35
36sub save_aliases {
37 my ($class, $param, $fw_conf, $aliases) = @_;
38
39 die "implement this in subclass";
40}
41
42my $additional_param_hash = {};
43
44sub additional_parameters {
45 my ($class, $new_value) = @_;
46
47 if (defined($new_value)) {
48 $additional_param_hash->{$class} = $new_value;
49 }
50
51 # return a copy
52 my $copy = {};
53 my $org = $additional_param_hash->{$class} || {};
54 foreach my $p (keys %$org) { $copy->{$p} = $org->{$p}; }
55 return $copy;
56}
57
58my $aliases_to_list = sub {
59 my ($aliases) = @_;
60
61 my $list = [];
62 foreach my $k (sort keys %$aliases) {
63 push @$list, $aliases->{$k};
64 }
65 return $list;
66};
67
68sub register_get_aliases {
69 my ($class) = @_;
70
71 my $properties = $class->additional_parameters();
72
73 $class->register_method({
74 name => 'get_aliases',
75 path => '',
76 method => 'GET',
77 description => "List aliases",
78 parameters => {
79 additionalProperties => 0,
80 properties => $properties,
81 },
82 returns => {
83 type => 'array',
84 items => {
85 type => "object",
86 properties => {
87 name => { type => 'string' },
88 cidr => { type => 'string' },
89 comment => {
90 type => 'string',
91 optional => 1,
92 },
93 digest => get_standard_option('pve-config-digest', { optional => 0} ),
94 },
95 },
96 links => [ { rel => 'child', href => "{name}" } ],
97 },
98 code => sub {
99 my ($param) = @_;
100
101 my ($fw_conf, $aliases) = $class->load_config($param);
102
103 my $list = &$aliases_to_list($aliases);
104
105 return PVE::Firewall::copy_list_with_digest($list);
106 }});
107}
108
109sub register_create_alias {
110 my ($class) = @_;
111
112 my $properties = $class->additional_parameters();
113
114 $properties->{name} = $api_properties->{name};
115 $properties->{cidr} = $api_properties->{cidr};
116 $properties->{comment} = $api_properties->{comment};
117
118 $class->register_method({
119 name => 'create_alias',
120 path => '',
121 method => 'POST',
122 description => "Create IP or Network Alias.",
123 protected => 1,
124 parameters => {
125 additionalProperties => 0,
126 properties => $properties,
127 },
128 returns => { type => "null" },
129 code => sub {
130 my ($param) = @_;
131
132 my ($fw_conf, $aliases) = $class->load_config($param);
133
134 my $name = lc($param->{name});
135
136 raise_param_exc({ name => "alias '$param->{name}' already exists" })
137 if defined($aliases->{$name});
138
139 my $data = { name => $param->{name}, cidr => $param->{cidr} };
140 $data->{comment} = $param->{comment} if $param->{comment};
141
142 $aliases->{$name} = $data;
143
144 $class->save_aliases($param, $fw_conf, $aliases);
145
146 return undef;
147 }});
148}
149
150sub register_read_alias {
151 my ($class) = @_;
152
153 my $properties = $class->additional_parameters();
154
155 $properties->{name} = $api_properties->{name};
81d574a7
DM
156
157 $class->register_method({
158 name => 'read_alias',
159 path => '{name}',
160 method => 'GET',
161 description => "Read alias.",
162 parameters => {
163 additionalProperties => 0,
164 properties => $properties,
165 },
166 returns => { type => "object" },
167 code => sub {
168 my ($param) = @_;
169
170 my ($fw_conf, $aliases) = $class->load_config($param);
171
172 my $name = lc($param->{name});
173
174 raise_param_exc({ name => "no such alias" })
175 if !defined($aliases->{$name});
176
177 return $aliases->{$name};
178 }});
179}
180
181sub register_update_alias {
182 my ($class) = @_;
183
184 my $properties = $class->additional_parameters();
185
186 $properties->{name} = $api_properties->{name};
cdc39d63 187 $properties->{rename} = $api_properties->{rename};
81d574a7
DM
188 $properties->{cidr} = $api_properties->{cidr};
189 $properties->{comment} = $api_properties->{comment};
190 $properties->{digest} = get_standard_option('pve-config-digest');
191
192 $class->register_method({
193 name => 'update_alias',
194 path => '{name}',
195 method => 'PUT',
196 description => "Update IP or Network alias.",
197 protected => 1,
198 parameters => {
199 additionalProperties => 0,
200 properties => $properties,
201 },
202 returns => { type => "null" },
203 code => sub {
204 my ($param) = @_;
205
206 my ($fw_conf, $aliases) = $class->load_config($param);
207
208 my $list = &$aliases_to_list($aliases);
209
210 my (undef, $digest) = PVE::Firewall::copy_list_with_digest($list);
211
212 PVE::Tools::assert_if_modified($digest, $param->{digest});
213
214 my $name = lc($param->{name});
215
216 raise_param_exc({ name => "no such alias" }) if !$aliases->{$name};
217
218 my $data = { name => $param->{name}, cidr => $param->{cidr} };
219 $data->{comment} = $param->{comment} if $param->{comment};
220
221 $aliases->{$name} = $data;
222
cdc39d63
DM
223 my $rename = lc($param->{rename});
224
225 if ($rename && ($name ne $rename)) {
226 raise_param_exc({ name => "alias '$param->{rename}' already exists" })
227 if defined($aliases->{$rename});
228 $aliases->{$name}->{name} = $param->{rename};
229 $aliases->{$rename} = $aliases->{$name};
230 delete $aliases->{$name};
231 }
232
81d574a7 233 $class->save_aliases($param, $fw_conf, $aliases);
cdc39d63
DM
234
235 return undef;
81d574a7
DM
236 }});
237}
238
239sub register_delete_alias {
240 my ($class) = @_;
241
242 my $properties = $class->additional_parameters();
243
244 $properties->{name} = $api_properties->{name};
81d574a7
DM
245 $properties->{digest} = get_standard_option('pve-config-digest');
246
247 $class->register_method({
248 name => 'remove_alias',
249 path => '{name}',
250 method => 'DELETE',
251 description => "Remove IP or Network alias.",
252 protected => 1,
253 parameters => {
254 additionalProperties => 0,
255 properties => $properties,
256 },
257 returns => { type => "null" },
258 code => sub {
259 my ($param) = @_;
260
261 my ($fw_conf, $aliases) = $class->load_config($param);
262
263 my $list = &$aliases_to_list($aliases);
264 my (undef, $digest) = PVE::Firewall::copy_list_with_digest($list);
265 PVE::Tools::assert_if_modified($digest, $param->{digest});
266
267 my $name = lc($param->{name});
268 delete $aliases->{$name};
269
270 $class->save_aliases($param, $fw_conf, $aliases);
271
272 return undef;
273 }});
274}
275
276sub register_handlers {
277 my ($class) = @_;
278
279 $class->register_get_aliases();
280 $class->register_create_alias();
281 $class->register_read_alias();
282 $class->register_update_alias();
283 $class->register_delete_alias();
284}
285
286package PVE::API2::Firewall::ClusterAliases;
287
288use strict;
289use warnings;
290
291use base qw(PVE::API2::Firewall::AliasesBase);
292
293sub load_config {
294 my ($class, $param) = @_;
295
296 my $fw_conf = PVE::Firewall::load_clusterfw_conf();
297 my $aliases = $fw_conf->{aliases};
298
299 return ($fw_conf, $aliases);
300}
301
302sub save_aliases {
303 my ($class, $param, $fw_conf, $aliases) = @_;
304
305 $fw_conf->{aliases} = $aliases;
306 PVE::Firewall::save_clusterfw_conf($fw_conf);
307}
308
309__PACKAGE__->register_handlers();
310
e76a9f53
DM
311package PVE::API2::Firewall::VMAliases;
312
313use strict;
314use warnings;
315use PVE::JSONSchema qw(get_standard_option);
316
317use base qw(PVE::API2::Firewall::AliasesBase);
318
319__PACKAGE__->additional_parameters({
320 node => get_standard_option('pve-node'),
321 vmid => get_standard_option('pve-vmid'),
322});
323
324sub load_config {
325 my ($class, $param) = @_;
326
42ec8178
DM
327 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
328 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'vm', $param->{vmid});
b6b8e6ad
DM
329 my $aliases = $fw_conf->{aliases};
330
331 return ($fw_conf, $aliases);
332}
333
334sub save_aliases {
335 my ($class, $param, $fw_conf, $aliases) = @_;
336
337 $fw_conf->{aliases} = $aliases;
338 PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf);
339}
340
341__PACKAGE__->register_handlers();
342
343package PVE::API2::Firewall::CTAliases;
344
345use strict;
346use warnings;
347use PVE::JSONSchema qw(get_standard_option);
348
349use base qw(PVE::API2::Firewall::AliasesBase);
350
351__PACKAGE__->additional_parameters({
352 node => get_standard_option('pve-node'),
353 vmid => get_standard_option('pve-vmid'),
354});
355
356sub load_config {
357 my ($class, $param) = @_;
358
42ec8178
DM
359 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
360 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'ct', $param->{vmid});
e76a9f53
DM
361 my $aliases = $fw_conf->{aliases};
362
363 return ($fw_conf, $aliases);
364}
365
366sub save_aliases {
367 my ($class, $param, $fw_conf, $aliases) = @_;
368
369 $fw_conf->{aliases} = $aliases;
370 PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf);
371}
372
373__PACKAGE__->register_handlers();
374
81d574a7 3751;