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