]> git.proxmox.com Git - pve-firewall.git/blame - src/PVE/API2/Firewall/IPSet.pm
api: add locking helpers
[pve-firewall.git] / src / PVE / API2 / Firewall / IPSet.pm
CommitLineData
009ee3ac
DM
1package PVE::API2::Firewall::IPSetBase;
2
3use strict;
4use warnings;
4a11bba5 5use PVE::Exception qw(raise raise_param_exc);
009ee3ac
DM
6use PVE::JSONSchema qw(get_standard_option);
7
8use PVE::Firewall;
9
10use base qw(PVE::RESTHandler);
11
75a12a9d 12my $api_properties = {
009ee3ac
DM
13 cidr => {
14 description => "Network/IP specification in CIDR format.",
ae029a88 15 type => 'string', format => 'IPorCIDRorAlias',
009ee3ac 16 },
e74a87f5 17 name => get_standard_option('ipset-name'),
009ee3ac
DM
18 comment => {
19 type => 'string',
20 optional => 1,
21 },
22 nomatch => {
23 type => 'boolean',
24 optional => 1,
25 },
26};
27
05496017
FG
28sub lock_config {
29 my ($class, $param, $code) = @_;
30
31 die "implement this in subclass";
32}
33
009ee3ac
DM
34sub load_config {
35 my ($class, $param) = @_;
36
37 die "implement this in subclass";
1210ae94
DM
38
39 #return ($cluster_conf, $fw_conf, $ipset);
009ee3ac
DM
40}
41
1210ae94
DM
42sub save_config {
43 my ($class, $param, $fw_conf) = @_;
009ee3ac
DM
44
45 die "implement this in subclass";
46}
47
9f6845cf
DM
48sub rule_env {
49 my ($class, $param) = @_;
75a12a9d 50
9f6845cf
DM
51 die "implement this in subclass";
52}
53
1210ae94
DM
54sub save_ipset {
55 my ($class, $param, $fw_conf, $ipset) = @_;
56
57 if (!defined($ipset)) {
58 delete $fw_conf->{ipset}->{$param->{name}};
59 } else {
60 $fw_conf->{ipset}->{$param->{name}} = $ipset;
61 }
62
63 $class->save_config($param, $fw_conf);
64}
65
009ee3ac
DM
66my $additional_param_hash = {};
67
68sub additional_parameters {
69 my ($class, $new_value) = @_;
70
71 if (defined($new_value)) {
72 $additional_param_hash->{$class} = $new_value;
73 }
74
75 # return a copy
76 my $copy = {};
77 my $org = $additional_param_hash->{$class} || {};
78 foreach my $p (keys %$org) { $copy->{$p} = $org->{$p}; }
79 return $copy;
80}
81
82sub register_get_ipset {
83 my ($class) = @_;
84
85 my $properties = $class->additional_parameters();
86
87 $properties->{name} = $api_properties->{name};
88
89 $class->register_method({
90 name => 'get_ipset',
91 path => '',
92 method => 'GET',
93 description => "List IPSet content",
9f6845cf 94 permissions => PVE::Firewall::rules_audit_permissions($class->rule_env()),
009ee3ac
DM
95 parameters => {
96 additionalProperties => 0,
97 properties => $properties,
98 },
99 returns => {
100 type => 'array',
101 items => {
102 type => "object",
103 properties => {
104 cidr => {
105 type => 'string',
106 },
107 comment => {
108 type => 'string',
109 optional => 1,
110 },
111 nomatch => {
112 type => 'boolean',
113 optional => 1,
d72c631c 114 },
75a12a9d 115 digest => get_standard_option('pve-config-digest', { optional => 0} ),
009ee3ac
DM
116 },
117 },
118 links => [ { rel => 'child', href => "{cidr}" } ],
119 },
120 code => sub {
121 my ($param) = @_;
122
1210ae94 123 my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
009ee3ac 124
5d38d64f 125 return PVE::Firewall::copy_list_with_digest($ipset);
009ee3ac
DM
126 }});
127}
128
1210ae94
DM
129sub register_delete_ipset {
130 my ($class) = @_;
131
132 my $properties = $class->additional_parameters();
133
134 $properties->{name} = get_standard_option('ipset-name');
135
136 $class->register_method({
137 name => 'delete_ipset',
138 path => '',
139 method => 'DELETE',
140 description => "Delete IPSet",
141 protected => 1,
9f6845cf 142 permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()),
1210ae94
DM
143 parameters => {
144 additionalProperties => 0,
145 properties => $properties,
146 },
147 returns => { type => 'null' },
148 code => sub {
149 my ($param) = @_;
75a12a9d 150
1210ae94
DM
151 my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
152
75a12a9d 153 die "IPSet '$param->{name}' is not empty\n"
1210ae94
DM
154 if scalar(@$ipset);
155
156 $class->save_ipset($param, $fw_conf, undef);
157
158 return undef;
159 }});
160}
161
a33c74f6 162sub register_create_ip {
009ee3ac
DM
163 my ($class) = @_;
164
165 my $properties = $class->additional_parameters();
166
167 $properties->{name} = $api_properties->{name};
168 $properties->{cidr} = $api_properties->{cidr};
169 $properties->{nomatch} = $api_properties->{nomatch};
170 $properties->{comment} = $api_properties->{comment};
d72c631c 171
009ee3ac 172 $class->register_method({
a33c74f6 173 name => 'create_ip',
009ee3ac
DM
174 path => '',
175 method => 'POST',
176 description => "Add IP or Network to IPSet.",
177 protected => 1,
9f6845cf 178 permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()),
009ee3ac
DM
179 parameters => {
180 additionalProperties => 0,
181 properties => $properties,
182 },
183 returns => { type => "null" },
184 code => sub {
185 my ($param) = @_;
186
1210ae94 187 my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
009ee3ac 188
4a11bba5 189 my $cidr = $param->{cidr};
75a12a9d 190
4a11bba5 191 foreach my $entry (@$ipset) {
75a12a9d 192 raise_param_exc({ cidr => "address '$cidr' already exists" })
4a11bba5
DM
193 if $entry->{cidr} eq $cidr;
194 }
195
1b36f6ec
WB
196 raise_param_exc({ cidr => "a zero prefix is not allowed in ipset entries" })
197 if $cidr =~ m!/0+$!;
198
6c221576 199 # make sure alias exists (if $cidr is an alias)
f9792937
DM
200 PVE::Firewall::resolve_alias($cluster_conf, $fw_conf, $cidr)
201 if $cidr =~ m/^${PVE::Firewall::ip_alias_pattern}$/;
7c619bbb 202
4a11bba5 203 my $data = { cidr => $cidr };
7c619bbb 204
009ee3ac
DM
205 $data->{nomatch} = 1 if $param->{nomatch};
206 $data->{comment} = $param->{comment} if $param->{comment};
207
009ee3ac
DM
208 unshift @$ipset, $data;
209
210 $class->save_ipset($param, $fw_conf, $ipset);
211
212 return undef;
213 }});
214}
215
a33c74f6
DM
216sub register_read_ip {
217 my ($class) = @_;
218
219 my $properties = $class->additional_parameters();
220
221 $properties->{name} = $api_properties->{name};
222 $properties->{cidr} = $api_properties->{cidr};
75a12a9d 223
a33c74f6
DM
224 $class->register_method({
225 name => 'read_ip',
226 path => '{cidr}',
227 method => 'GET',
228 description => "Read IP or Network settings from IPSet.",
9f6845cf 229 permissions => PVE::Firewall::rules_audit_permissions($class->rule_env()),
a33c74f6
DM
230 protected => 1,
231 parameters => {
232 additionalProperties => 0,
233 properties => $properties,
234 },
235 returns => { type => "object" },
236 code => sub {
237 my ($param) = @_;
238
1210ae94 239 my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
a33c74f6 240
5d38d64f
DM
241 my $list = PVE::Firewall::copy_list_with_digest($ipset);
242
243 foreach my $entry (@$list) {
d72c631c 244 if ($entry->{cidr} eq $param->{cidr}) {
d72c631c
DM
245 return $entry;
246 }
a33c74f6
DM
247 }
248
249 raise_param_exc({ cidr => "no such IP/Network" });
250 }});
251}
252
253sub register_update_ip {
254 my ($class) = @_;
255
256 my $properties = $class->additional_parameters();
257
258 $properties->{name} = $api_properties->{name};
259 $properties->{cidr} = $api_properties->{cidr};
260 $properties->{nomatch} = $api_properties->{nomatch};
261 $properties->{comment} = $api_properties->{comment};
d72c631c
DM
262 $properties->{digest} = get_standard_option('pve-config-digest');
263
a33c74f6
DM
264 $class->register_method({
265 name => 'update_ip',
266 path => '{cidr}',
267 method => 'PUT',
268 description => "Update IP or Network settings",
269 protected => 1,
9f6845cf 270 permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()),
a33c74f6
DM
271 parameters => {
272 additionalProperties => 0,
273 properties => $properties,
274 },
275 returns => { type => "null" },
276 code => sub {
277 my ($param) = @_;
278
1210ae94 279 my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
a33c74f6 280
5d38d64f
DM
281 my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
282 PVE::Tools::assert_if_modified($digest, $param->{digest});
d72c631c 283
a33c74f6
DM
284 foreach my $entry (@$ipset) {
285 if($entry->{cidr} eq $param->{cidr}) {
286 $entry->{nomatch} = $param->{nomatch};
287 $entry->{comment} = $param->{comment};
288 $class->save_ipset($param, $fw_conf, $ipset);
289 return;
290 }
291 }
292
293 raise_param_exc({ cidr => "no such IP/Network" });
294 }});
295}
296
297sub register_delete_ip {
009ee3ac
DM
298 my ($class) = @_;
299
300 my $properties = $class->additional_parameters();
301
302 $properties->{name} = $api_properties->{name};
303 $properties->{cidr} = $api_properties->{cidr};
d72c631c
DM
304 $properties->{digest} = get_standard_option('pve-config-digest');
305
009ee3ac
DM
306 $class->register_method({
307 name => 'remove_ip',
308 path => '{cidr}',
309 method => 'DELETE',
310 description => "Remove IP or Network from IPSet.",
311 protected => 1,
9f6845cf 312 permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()),
009ee3ac
DM
313 parameters => {
314 additionalProperties => 0,
315 properties => $properties,
316 },
317 returns => { type => "null" },
318 code => sub {
319 my ($param) = @_;
320
1210ae94 321 my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
009ee3ac 322
5d38d64f
DM
323 my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
324 PVE::Tools::assert_if_modified($digest, $param->{digest});
d72c631c 325
4a11bba5 326 my $new = [];
75a12a9d 327
4a11bba5
DM
328 foreach my $entry (@$ipset) {
329 push @$new, $entry if $entry->{cidr} ne $param->{cidr};
330 }
009ee3ac 331
4a11bba5 332 $class->save_ipset($param, $fw_conf, $new);
75a12a9d 333
009ee3ac
DM
334 return undef;
335 }});
336}
337
338sub register_handlers {
339 my ($class) = @_;
340
1210ae94 341 $class->register_delete_ipset();
009ee3ac 342 $class->register_get_ipset();
a33c74f6
DM
343 $class->register_create_ip();
344 $class->register_read_ip();
345 $class->register_update_ip();
346 $class->register_delete_ip();
009ee3ac
DM
347}
348
349package PVE::API2::Firewall::ClusterIPset;
350
351use strict;
352use warnings;
353
354use base qw(PVE::API2::Firewall::IPSetBase);
355
9f6845cf
DM
356sub rule_env {
357 my ($class, $param) = @_;
75a12a9d 358
9f6845cf
DM
359 return 'cluster';
360}
361
05496017
FG
362sub lock_config {
363 my ($class, $param, $code) = @_;
364
365 PVE::Firewall::lock_clusterfw_conf(10, $code, $param);
366}
367
009ee3ac
DM
368sub load_config {
369 my ($class, $param) = @_;
370
371 my $fw_conf = PVE::Firewall::load_clusterfw_conf();
372 my $ipset = $fw_conf->{ipset}->{$param->{name}};
373 die "no such IPSet '$param->{name}'\n" if !defined($ipset);
374
1210ae94 375 return (undef, $fw_conf, $ipset);
009ee3ac
DM
376}
377
1210ae94
DM
378sub save_config {
379 my ($class, $param, $fw_conf) = @_;
009ee3ac 380
009ee3ac
DM
381 PVE::Firewall::save_clusterfw_conf($fw_conf);
382}
383
384__PACKAGE__->register_handlers();
385
1210ae94
DM
386package PVE::API2::Firewall::VMIPset;
387
388use strict;
389use warnings;
390use PVE::JSONSchema qw(get_standard_option);
391
392use base qw(PVE::API2::Firewall::IPSetBase);
393
9f6845cf
DM
394sub rule_env {
395 my ($class, $param) = @_;
75a12a9d 396
9f6845cf
DM
397 return 'vm';
398}
399
75a12a9d 400__PACKAGE__->additional_parameters({
1210ae94 401 node => get_standard_option('pve-node'),
75a12a9d 402 vmid => get_standard_option('pve-vmid'),
1210ae94
DM
403});
404
05496017
FG
405sub lock_config {
406 my ($class, $param, $code) = @_;
407
408 PVE::Firewall::lock_vmfw_conf($param->{vmid}, 10, $code, $param);
409}
410
1210ae94
DM
411sub load_config {
412 my ($class, $param) = @_;
413
414 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
415 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'vm', $param->{vmid});
416 my $ipset = $fw_conf->{ipset}->{$param->{name}};
417 die "no such IPSet '$param->{name}'\n" if !defined($ipset);
418
419 return ($cluster_conf, $fw_conf, $ipset);
420}
421
422sub save_config {
423 my ($class, $param, $fw_conf) = @_;
424
425 PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf);
426}
427
428__PACKAGE__->register_handlers();
429
430package PVE::API2::Firewall::CTIPset;
431
432use strict;
433use warnings;
434use PVE::JSONSchema qw(get_standard_option);
435
436use base qw(PVE::API2::Firewall::IPSetBase);
437
9f6845cf
DM
438sub rule_env {
439 my ($class, $param) = @_;
75a12a9d 440
9f6845cf
DM
441 return 'ct';
442}
443
75a12a9d 444__PACKAGE__->additional_parameters({
1210ae94 445 node => get_standard_option('pve-node'),
75a12a9d 446 vmid => get_standard_option('pve-vmid'),
1210ae94
DM
447});
448
05496017
FG
449sub lock_config {
450 my ($class, $param, $code) = @_;
451
452 PVE::Firewall::lock_vmfw_conf($param->{vmid}, 10, $code, $param);
453}
454
1210ae94
DM
455sub load_config {
456 my ($class, $param) = @_;
457
458 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
459 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'ct', $param->{vmid});
460 my $ipset = $fw_conf->{ipset}->{$param->{name}};
461 die "no such IPSet '$param->{name}'\n" if !defined($ipset);
462
463 return ($cluster_conf, $fw_conf, $ipset);
464}
465
466sub save_config {
467 my ($class, $param, $fw_conf) = @_;
468
469 PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf);
470}
471
472__PACKAGE__->register_handlers();
473
c85c87f9
DM
474package PVE::API2::Firewall::BaseIPSetList;
475
476use strict;
477use warnings;
e74a87f5 478use PVE::JSONSchema qw(get_standard_option);
c85c87f9 479use PVE::Exception qw(raise_param_exc);
e74a87f5 480use PVE::Firewall;
c85c87f9
DM
481
482use base qw(PVE::RESTHandler);
483
05496017
FG
484sub lock_config {
485 my ($class, $param, $code) = @_;
486
487 die "implement this in subclass";
488}
489
1210ae94
DM
490sub load_config {
491 my ($class, $param) = @_;
75a12a9d 492
1210ae94
DM
493 die "implement this in subclass";
494
495 #return ($cluster_conf, $fw_conf);
496}
497
498sub save_config {
499 my ($class, $param, $fw_conf) = @_;
500
501 die "implement this in subclass";
502}
503
9f6845cf
DM
504sub rule_env {
505 my ($class, $param) = @_;
75a12a9d 506
9f6845cf
DM
507 die "implement this in subclass";
508}
509
1210ae94
DM
510my $additional_param_hash_list = {};
511
512sub additional_parameters {
513 my ($class, $new_value) = @_;
514
515 if (defined($new_value)) {
516 $additional_param_hash_list->{$class} = $new_value;
517 }
518
519 # return a copy
520 my $copy = {};
521 my $org = $additional_param_hash_list->{$class} || {};
522 foreach my $p (keys %$org) { $copy->{$p} = $org->{$p}; }
523 return $copy;
524}
525
5d38d64f
DM
526my $get_ipset_list = sub {
527 my ($fw_conf) = @_;
528
529 my $res = [];
53bbbf31 530 foreach my $name (sort keys %{$fw_conf->{ipset}}) {
75a12a9d 531 my $data = {
5d38d64f
DM
532 name => $name,
533 };
534 if (my $comment = $fw_conf->{ipset_comments}->{$name}) {
535 $data->{comment} = $comment;
536 }
537 push @$res, $data;
538 }
539
540 my ($list, $digest) = PVE::Firewall::copy_list_with_digest($res);
541
542 return wantarray ? ($list, $digest) : $list;
543};
544
c85c87f9
DM
545sub register_index {
546 my ($class) = @_;
547
1210ae94
DM
548 my $properties = $class->additional_parameters();
549
c85c87f9
DM
550 $class->register_method({
551 name => 'ipset_index',
552 path => '',
553 method => 'GET',
554 description => "List IPSets",
9f6845cf 555 permissions => PVE::Firewall::rules_audit_permissions($class->rule_env()),
c85c87f9
DM
556 parameters => {
557 additionalProperties => 0,
1210ae94 558 properties => $properties,
c85c87f9
DM
559 },
560 returns => {
561 type => 'array',
562 items => {
563 type => "object",
75a12a9d 564 properties => {
e74a87f5 565 name => get_standard_option('ipset-name'),
d72c631c 566 digest => get_standard_option('pve-config-digest', { optional => 0} ),
75a12a9d 567 comment => {
d72c631c
DM
568 type => 'string',
569 optional => 1,
570 }
c85c87f9
DM
571 },
572 },
573 links => [ { rel => 'child', href => "{name}" } ],
574 },
575 code => sub {
576 my ($param) = @_;
75a12a9d 577
1210ae94 578 my ($cluster_conf, $fw_conf) = $class->load_config($param);
c85c87f9 579
75a12a9d 580 return &$get_ipset_list($fw_conf);
c85c87f9
DM
581 }});
582}
583
584sub register_create {
585 my ($class) = @_;
586
1210ae94
DM
587 my $properties = $class->additional_parameters();
588
589 $properties->{name} = get_standard_option('ipset-name');
590
591 $properties->{comment} = { type => 'string', optional => 1 };
592
593 $properties->{digest} = get_standard_option('pve-config-digest');
594
595 $properties->{rename} = get_standard_option('ipset-name', {
596 description => "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.",
597 optional => 1 });
598
c85c87f9
DM
599 $class->register_method({
600 name => 'create_ipset',
601 path => '',
602 method => 'POST',
603 description => "Create new IPSet",
604 protected => 1,
9f6845cf 605 permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()),
c85c87f9
DM
606 parameters => {
607 additionalProperties => 0,
1210ae94 608 properties => $properties,
c85c87f9
DM
609 },
610 returns => { type => 'null' },
611 code => sub {
612 my ($param) = @_;
75a12a9d 613
1210ae94 614 my ($cluster_conf, $fw_conf) = $class->load_config($param);
c85c87f9 615
bc374ca7 616 if ($param->{rename}) {
5d38d64f
DM
617 my (undef, $digest) = &$get_ipset_list($fw_conf);
618 PVE::Tools::assert_if_modified($digest, $param->{digest});
619
75a12a9d 620 raise_param_exc({ name => "IPSet '$param->{rename}' does not exist" })
bc374ca7 621 if !$fw_conf->{ipset}->{$param->{rename}};
5d38d64f 622
5da1a229
DC
623 # prevent overwriting existing ipset
624 raise_param_exc({ name => "IPSet '$param->{name}' does already exist"})
625 if $fw_conf->{ipset}->{$param->{name}} &&
626 $param->{name} ne $param->{rename};
627
bc374ca7
DM
628 my $data = delete $fw_conf->{ipset}->{$param->{rename}};
629 $fw_conf->{ipset}->{$param->{name}} = $data;
d72c631c
DM
630 if (my $comment = delete $fw_conf->{ipset_comments}->{$param->{rename}}) {
631 $fw_conf->{ipset_comments}->{$param->{name}} = $comment;
632 }
633 $fw_conf->{ipset_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
75a12a9d 634 } else {
5d38d64f 635 foreach my $name (keys %{$fw_conf->{ipset}}) {
75a12a9d 636 raise_param_exc({ name => "IPSet '$name' already exists" })
5d38d64f
DM
637 if $name eq $param->{name};
638 }
639
bc374ca7 640 $fw_conf->{ipset}->{$param->{name}} = [];
d72c631c 641 $fw_conf->{ipset_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
bc374ca7
DM
642 }
643
1210ae94 644 $class->save_config($param, $fw_conf);
c85c87f9
DM
645
646 return undef;
647 }});
648}
649
1210ae94 650sub register_handlers {
c85c87f9
DM
651 my ($class) = @_;
652
1210ae94
DM
653 $class->register_index();
654 $class->register_create();
655}
c85c87f9 656
1210ae94 657package PVE::API2::Firewall::ClusterIPSetList;
c85c87f9 658
1210ae94
DM
659use strict;
660use warnings;
661use PVE::Firewall;
5d38d64f 662
1210ae94
DM
663use base qw(PVE::API2::Firewall::BaseIPSetList);
664
9f6845cf
DM
665sub rule_env {
666 my ($class, $param) = @_;
75a12a9d 667
9f6845cf
DM
668 return 'cluster';
669}
670
05496017
FG
671sub lock_config {
672 my ($class, $param, $code) = @_;
673
674 PVE::Firewall::lock_clusterfw_conf(10, $code, $param);
675}
676
1210ae94
DM
677sub load_config {
678 my ($class, $param) = @_;
75a12a9d 679
1210ae94
DM
680 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
681 return (undef, $cluster_conf);
682}
c85c87f9 683
1210ae94
DM
684sub save_config {
685 my ($class, $param, $fw_conf) = @_;
c85c87f9 686
1210ae94
DM
687 PVE::Firewall::save_clusterfw_conf($fw_conf);
688}
c85c87f9 689
1210ae94
DM
690__PACKAGE__->register_handlers();
691
692__PACKAGE__->register_method ({
75a12a9d 693 subclass => "PVE::API2::Firewall::ClusterIPset",
1210ae94 694 path => '{name}',
75a12a9d
TL
695 # set fragment delimiter (no subdirs) - we need that, because CIDR address contain a slash '/'
696 fragmentDelimiter => '',
1210ae94
DM
697});
698
699package PVE::API2::Firewall::VMIPSetList;
700
701use strict;
702use warnings;
703use PVE::JSONSchema qw(get_standard_option);
704use PVE::Firewall;
705
706use base qw(PVE::API2::Firewall::BaseIPSetList);
707
75a12a9d 708__PACKAGE__->additional_parameters({
1210ae94 709 node => get_standard_option('pve-node'),
75a12a9d 710 vmid => get_standard_option('pve-vmid'),
1210ae94
DM
711});
712
9f6845cf
DM
713sub rule_env {
714 my ($class, $param) = @_;
75a12a9d 715
9f6845cf
DM
716 return 'vm';
717}
718
05496017
FG
719sub lock_config {
720 my ($class, $param, $code) = @_;
721
722 PVE::Firewall::lock_vmfw_conf($param->{vmid}, 10, $code, $param);
723}
724
1210ae94
DM
725sub load_config {
726 my ($class, $param) = @_;
75a12a9d 727
1210ae94
DM
728 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
729 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'vm', $param->{vmid});
730 return ($cluster_conf, $fw_conf);
c85c87f9
DM
731}
732
1210ae94
DM
733sub save_config {
734 my ($class, $param, $fw_conf) = @_;
c85c87f9 735
1210ae94 736 PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf);
c85c87f9
DM
737}
738
1210ae94
DM
739__PACKAGE__->register_handlers();
740
741__PACKAGE__->register_method ({
75a12a9d 742 subclass => "PVE::API2::Firewall::VMIPset",
1210ae94 743 path => '{name}',
75a12a9d
TL
744 # set fragment delimiter (no subdirs) - we need that, because CIDR address contain a slash '/'
745 fragmentDelimiter => '',
1210ae94
DM
746});
747
748package PVE::API2::Firewall::CTIPSetList;
c85c87f9
DM
749
750use strict;
751use warnings;
1210ae94 752use PVE::JSONSchema qw(get_standard_option);
c85c87f9
DM
753use PVE::Firewall;
754
755use base qw(PVE::API2::Firewall::BaseIPSetList);
756
75a12a9d 757__PACKAGE__->additional_parameters({
1210ae94 758 node => get_standard_option('pve-node'),
75a12a9d 759 vmid => get_standard_option('pve-vmid'),
1210ae94
DM
760});
761
9f6845cf
DM
762sub rule_env {
763 my ($class, $param) = @_;
75a12a9d 764
9f6845cf
DM
765 return 'ct';
766}
767
05496017
FG
768sub lock_config {
769 my ($class, $param, $code) = @_;
770
771 PVE::Firewall::lock_vmfw_conf($param->{vmid}, 10, $code, $param);
772}
773
c85c87f9 774sub load_config {
1210ae94 775 my ($class, $param) = @_;
75a12a9d 776
1210ae94
DM
777 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
778 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'ct', $param->{vmid});
779 return ($cluster_conf, $fw_conf);
c85c87f9
DM
780}
781
782sub save_config {
1210ae94 783 my ($class, $param, $fw_conf) = @_;
c85c87f9 784
1210ae94 785 PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf);
c85c87f9
DM
786}
787
788__PACKAGE__->register_handlers();
789
790__PACKAGE__->register_method ({
75a12a9d 791 subclass => "PVE::API2::Firewall::CTIPset",
c85c87f9 792 path => '{name}',
75a12a9d
TL
793 # set fragment delimiter (no subdirs) - we need that, because CIDR address contain a slash '/'
794 fragmentDelimiter => '',
c85c87f9
DM
795});
796
009ee3ac 7971;