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