]>
git.proxmox.com Git - pve-firewall.git/blob - src/PVE/API2/Firewall/IPSet.pm
0e73dd4abf83fae1cd1f90749bf24444af5dd06c
1 package PVE
::API2
::Firewall
::IPSetBase
;
5 use PVE
::Exception
qw(raise raise_param_exc);
6 use PVE
::JSONSchema
qw(get_standard_option);
10 use base
qw(PVE::RESTHandler);
12 my $api_properties = {
14 description
=> "Network/IP specification in CIDR format.",
15 type
=> 'string', format
=> 'IPv4orCIDR',
17 name
=> get_standard_option
('ipset-name'),
29 my ($class, $param) = @_;
31 die "implement this in subclass";
33 #return ($fw_conf, $rules);
37 my ($class, $param, $fw_conf, $rules) = @_;
39 die "implement this in subclass";
42 my $additional_param_hash = {};
44 sub additional_parameters
{
45 my ($class, $new_value) = @_;
47 if (defined($new_value)) {
48 $additional_param_hash->{$class} = $new_value;
53 my $org = $additional_param_hash->{$class} || {};
54 foreach my $p (keys %$org) { $copy->{$p} = $org->{$p}; }
58 sub register_get_ipset
{
61 my $properties = $class->additional_parameters();
63 $properties->{name
} = $api_properties->{name
};
65 $class->register_method({
69 description
=> "List IPSet content",
71 additionalProperties
=> 0,
72 properties
=> $properties,
90 digest
=> get_standard_option
('pve-config-digest', { optional
=> 0} ),
93 links
=> [ { rel
=> 'child', href
=> "{cidr}" } ],
98 my ($fw_conf, $ipset) = $class->load_config($param);
100 my $digest = $fw_conf->{digest
};
103 foreach my $entry (@$ipset) {
104 my $data = {digest
=> $digest};
105 foreach my $k (qw(cidr comment nomatch)) {
106 $data->{$k} = $entry->{$k} if $entry->{$k};
115 sub register_create_ip
{
118 my $properties = $class->additional_parameters();
120 $properties->{name
} = $api_properties->{name
};
121 $properties->{cidr
} = $api_properties->{cidr
};
122 $properties->{nomatch
} = $api_properties->{nomatch
};
123 $properties->{comment
} = $api_properties->{comment
};
125 $class->register_method({
129 description
=> "Add IP or Network to IPSet.",
132 additionalProperties
=> 0,
133 properties
=> $properties,
135 returns
=> { type
=> "null" },
139 my ($fw_conf, $ipset) = $class->load_config($param);
141 my $cidr = $param->{cidr
};
143 foreach my $entry (@$ipset) {
144 raise_param_exc
({ cidr
=> "address '$cidr' already exists" })
145 if $entry->{cidr
} eq $cidr;
148 my $data = { cidr
=> $cidr };
149 $data->{nomatch
} = 1 if $param->{nomatch
};
150 $data->{comment
} = $param->{comment
} if $param->{comment
};
152 unshift @$ipset, $data;
154 $class->save_ipset($param, $fw_conf, $ipset);
160 sub register_read_ip
{
163 my $properties = $class->additional_parameters();
165 $properties->{name
} = $api_properties->{name
};
166 $properties->{cidr
} = $api_properties->{cidr
};
168 $class->register_method({
172 description
=> "Read IP or Network settings from IPSet.",
175 additionalProperties
=> 0,
176 properties
=> $properties,
178 returns
=> { type
=> "object" },
182 my ($fw_conf, $ipset) = $class->load_config($param);
183 my $digest = $fw_conf->{digest
};
185 foreach my $entry (@$ipset) {
186 if ($entry->{cidr
} eq $param->{cidr
}) {
187 $entry->{digest
} = $digest;
192 raise_param_exc
({ cidr
=> "no such IP/Network" });
196 sub register_update_ip
{
199 my $properties = $class->additional_parameters();
201 $properties->{name
} = $api_properties->{name
};
202 $properties->{cidr
} = $api_properties->{cidr
};
203 $properties->{nomatch
} = $api_properties->{nomatch
};
204 $properties->{comment
} = $api_properties->{comment
};
205 $properties->{digest
} = get_standard_option
('pve-config-digest');
207 $class->register_method({
211 description
=> "Update IP or Network settings",
214 additionalProperties
=> 0,
215 properties
=> $properties,
217 returns
=> { type
=> "null" },
221 my ($fw_conf, $ipset) = $class->load_config($param);
223 PVE
::Tools
::assert_if_modified
($fw_conf->{digest
}, $param->{digest
});
225 foreach my $entry (@$ipset) {
226 if($entry->{cidr
} eq $param->{cidr
}) {
227 $entry->{nomatch
} = $param->{nomatch
};
228 $entry->{comment
} = $param->{comment
};
229 $class->save_ipset($param, $fw_conf, $ipset);
234 raise_param_exc
({ cidr
=> "no such IP/Network" });
238 sub register_delete_ip
{
241 my $properties = $class->additional_parameters();
243 $properties->{name
} = $api_properties->{name
};
244 $properties->{cidr
} = $api_properties->{cidr
};
245 $properties->{digest
} = get_standard_option
('pve-config-digest');
247 $class->register_method({
251 description
=> "Remove IP or Network from IPSet.",
254 additionalProperties
=> 0,
255 properties
=> $properties,
257 returns
=> { type
=> "null" },
261 my ($fw_conf, $ipset) = $class->load_config($param);
263 PVE
::Tools
::assert_if_modified
($fw_conf->{digest
}, $param->{digest
});
267 foreach my $entry (@$ipset) {
268 push @$new, $entry if $entry->{cidr
} ne $param->{cidr
};
271 $class->save_ipset($param, $fw_conf, $new);
277 sub register_handlers
{
280 $class->register_get_ipset();
281 $class->register_create_ip();
282 $class->register_read_ip();
283 $class->register_update_ip();
284 $class->register_delete_ip();
287 package PVE
::API2
::Firewall
::ClusterIPset
;
292 use base
qw(PVE::API2::Firewall::IPSetBase);
295 my ($class, $param) = @_;
297 my $fw_conf = PVE
::Firewall
::load_clusterfw_conf
();
298 my $ipset = $fw_conf->{ipset
}->{$param->{name
}};
299 die "no such IPSet '$param->{name}'\n" if !defined($ipset);
301 return ($fw_conf, $ipset);
305 my ($class, $param, $fw_conf, $ipset) = @_;
307 $fw_conf->{ipset
}->{$param->{name
}} = $ipset;
308 PVE
::Firewall
::save_clusterfw_conf
($fw_conf);
311 __PACKAGE__-
>register_handlers();
313 package PVE
::API2
::Firewall
::BaseIPSetList
;
317 use PVE
::JSONSchema
qw(get_standard_option);
318 use PVE
::Exception
qw(raise_param_exc);
321 use base
qw(PVE::RESTHandler);
326 $class->register_method({
327 name
=> 'ipset_index',
330 description
=> "List IPSets",
332 additionalProperties
=> 0,
339 name
=> get_standard_option
('ipset-name'),
340 digest
=> get_standard_option
('pve-config-digest', { optional
=> 0} ),
347 links
=> [ { rel
=> 'child', href
=> "{name}" } ],
352 my $fw_conf = $class->load_config();
354 my $digest = $fw_conf->{digest
};
357 foreach my $name (keys %{$fw_conf->{ipset
}}) {
361 count
=> scalar(@{$fw_conf->{ipset
}->{$name}})
363 if (my $comment = $fw_conf->{ipset_comments
}->{$name}) {
364 $data->{comment
} = $comment;
373 sub register_create
{
376 $class->register_method({
377 name
=> 'create_ipset',
380 description
=> "Create new IPSet",
383 additionalProperties
=> 0,
385 name
=> get_standard_option
('ipset-name'),
390 rename => get_standard_option
('ipset-name', {
391 description
=> "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.",
394 digest
=> get_standard_option
('pve-config-digest'),
397 returns
=> { type
=> 'null' },
401 my $fw_conf = $class->load_config();
403 my $digest = $fw_conf->{digest
};
405 PVE
::Tools
::assert_if_modified
($digest, $param->{digest
});
407 if (!$param->{rename}) {
408 foreach my $name (keys %{$fw_conf->{ipset
}}) {
409 raise_param_exc
({ name
=> "IPSet '$name' already exists" })
410 if $name eq $param->{name
};
414 if ($param->{rename}) {
415 raise_param_exc
({ name
=> "IPSet '$param->{rename}' does not exists" })
416 if !$fw_conf->{ipset
}->{$param->{rename}};
417 my $data = delete $fw_conf->{ipset
}->{$param->{rename}};
418 $fw_conf->{ipset
}->{$param->{name
}} = $data;
419 if (my $comment = delete $fw_conf->{ipset_comments
}->{$param->{rename}}) {
420 $fw_conf->{ipset_comments
}->{$param->{name
}} = $comment;
422 $fw_conf->{ipset_comments
}->{$param->{name
}} = $param->{comment
} if defined($param->{comment
});
424 $fw_conf->{ipset
}->{$param->{name
}} = [];
425 $fw_conf->{ipset_comments
}->{$param->{name
}} = $param->{comment
} if defined($param->{comment
});
428 $class->save_config($fw_conf);
434 sub register_delete
{
437 $class->register_method({
438 name
=> 'delete_ipset',
441 description
=> "Delete IPSet",
444 additionalProperties
=> 0,
446 name
=> get_standard_option
('ipset-name'),
447 digest
=> get_standard_option
('pve-config-digest'),
450 returns
=> { type
=> 'null' },
454 my $fw_conf = $class->load_config();
456 PVE
::Tools
::assert_if_modified
($fw_conf->{digest
}, $param->{digest
});
458 return undef if !$fw_conf->{ipset
}->{$param->{name
}};
460 die "IPSet '$param->{name}' is not empty\n"
461 if scalar(@{$fw_conf->{ipset
}->{$param->{name
}}});
463 delete $fw_conf->{ipset
}->{$param->{name
}};
465 $class->save_config($fw_conf);
471 sub register_handlers
{
474 $class->register_index();
475 $class->register_create();
476 $class->register_delete();
479 package PVE
::API2
::Firewall
::ClusterIPSetList
;
485 use base
qw(PVE::API2::Firewall::BaseIPSetList);
490 return PVE
::Firewall
::load_clusterfw_conf
();
494 my ($class, $fw_conf) = @_;
496 PVE
::Firewall
::save_clusterfw_conf
($fw_conf);
499 __PACKAGE__-
>register_handlers();
501 __PACKAGE__-
>register_method ({
502 subclass
=> "PVE::API2::Firewall::ClusterIPset",
504 # set fragment delimiter (no subdirs) - we need that, because CIDR address contain a slash '/'
505 fragmentDelimiter
=> '',