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