my $properties = $class->additional_parameters();
$properties->{name} = get_standard_option('ipset-name');
+ $properties->{force} = {
+ type => 'boolean',
+ optional => 1,
+ description => 'Delete all members of the IPSet, if there are any.',
+ };
$class->register_method({
name => 'delete_ipset',
code => sub {
my ($param) = @_;
- my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
+ $class->lock_config($param, sub {
+ my ($param) = @_;
+
+ my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
- die "IPSet '$param->{name}' is not empty\n"
- if scalar(@$ipset);
+ die "IPSet '$param->{name}' is not empty\n"
+ if scalar(@$ipset) && !$param->{force};
- $class->save_ipset($param, $fw_conf, undef);
+ $class->save_ipset($param, $fw_conf, undef);
+
+ });
return undef;
}});
code => sub {
my ($param) = @_;
- my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
+ $class->lock_config($param, sub {
+ my ($param) = @_;
+
+ my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
+
+ my $cidr = $param->{cidr};
+ if ($cidr =~ m@^(dc/|guest/)?(${PVE::Firewall::ip_alias_pattern})$@) {
+ my $scope = $1 // "";
+ my $alias = $2;
+ # make sure alias exists (if $cidr is an alias)
+ PVE::Firewall::resolve_alias($cluster_conf, $fw_conf, $alias, $scope);
+ } else {
+ $cidr = PVE::Firewall::clean_cidr($cidr);
+ # normalize like config parser, otherwise duplicates might slip through
+ $cidr = PVE::Firewall::parse_ip_or_cidr($cidr);
+ }
- my $cidr = $param->{cidr};
+ foreach my $entry (@$ipset) {
+ raise_param_exc({ cidr => "address '$cidr' already exists" })
+ if $entry->{cidr} eq $cidr;
+ }
- foreach my $entry (@$ipset) {
- raise_param_exc({ cidr => "address '$cidr' already exists" })
- if $entry->{cidr} eq $cidr;
- }
+ raise_param_exc({ cidr => "a zero prefix is not allowed in ipset entries" })
+ if $cidr =~ m!/0+$!;
- raise_param_exc({ cidr => "a zero prefix is not allowed in ipset entries" })
- if $cidr =~ m!/0+$!;
- # make sure alias exists (if $cidr is an alias)
- PVE::Firewall::resolve_alias($cluster_conf, $fw_conf, $cidr)
- if $cidr =~ m/^${PVE::Firewall::ip_alias_pattern}$/;
+ my $data = { cidr => $cidr };
- my $data = { cidr => $cidr };
+ $data->{nomatch} = 1 if $param->{nomatch};
+ $data->{comment} = $param->{comment} if $param->{comment};
- $data->{nomatch} = 1 if $param->{nomatch};
- $data->{comment} = $param->{comment} if $param->{comment};
+ unshift @$ipset, $data;
- unshift @$ipset, $data;
+ $class->save_ipset($param, $fw_conf, $ipset);
- $class->save_ipset($param, $fw_conf, $ipset);
+ });
return undef;
}});
code => sub {
my ($param) = @_;
- my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
+ my $found = $class->lock_config($param, sub {
+ my ($param) = @_;
- my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
- PVE::Tools::assert_if_modified($digest, $param->{digest});
+ my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
+
+ my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
- foreach my $entry (@$ipset) {
- if($entry->{cidr} eq $param->{cidr}) {
- $entry->{nomatch} = $param->{nomatch};
- $entry->{comment} = $param->{comment};
- $class->save_ipset($param, $fw_conf, $ipset);
- return;
+ foreach my $entry (@$ipset) {
+ if($entry->{cidr} eq $param->{cidr}) {
+ $entry->{nomatch} = $param->{nomatch};
+ $entry->{comment} = $param->{comment};
+ $class->save_ipset($param, $fw_conf, $ipset);
+ return 1;
+ }
}
- }
+
+ return 0;
+ });
+
+ return if $found;
raise_param_exc({ cidr => "no such IP/Network" });
}});
code => sub {
my ($param) = @_;
- my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
+ $class->lock_config($param, sub {
+ my ($param) = @_;
- my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
- PVE::Tools::assert_if_modified($digest, $param->{digest});
+ my ($cluster_conf, $fw_conf, $ipset) = $class->load_config($param);
- my $new = [];
+ my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
- foreach my $entry (@$ipset) {
- push @$new, $entry if $entry->{cidr} ne $param->{cidr};
- }
+ my $new = [];
- $class->save_ipset($param, $fw_conf, $new);
+ foreach my $entry (@$ipset) {
+ push @$new, $entry if $entry->{cidr} ne $param->{cidr};
+ }
+
+ $class->save_ipset($param, $fw_conf, $new);
+ });
return undef;
}});
code => sub {
my ($param) = @_;
- my ($cluster_conf, $fw_conf) = $class->load_config($param);
+ $class->lock_config($param, sub {
+ my ($param) = @_;
- if ($param->{rename}) {
- my (undef, $digest) = &$get_ipset_list($fw_conf);
- PVE::Tools::assert_if_modified($digest, $param->{digest});
+ my ($cluster_conf, $fw_conf) = $class->load_config($param);
- raise_param_exc({ name => "IPSet '$param->{rename}' does not exist" })
- if !$fw_conf->{ipset}->{$param->{rename}};
+ if ($param->{rename}) {
+ my (undef, $digest) = &$get_ipset_list($fw_conf);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
- # prevent overwriting existing ipset
- raise_param_exc({ name => "IPSet '$param->{name}' does already exist"})
- if $fw_conf->{ipset}->{$param->{name}} &&
- $param->{name} ne $param->{rename};
+ raise_param_exc({ name => "IPSet '$param->{rename}' does not exist" })
+ if !$fw_conf->{ipset}->{$param->{rename}};
- my $data = delete $fw_conf->{ipset}->{$param->{rename}};
- $fw_conf->{ipset}->{$param->{name}} = $data;
- if (my $comment = delete $fw_conf->{ipset_comments}->{$param->{rename}}) {
- $fw_conf->{ipset_comments}->{$param->{name}} = $comment;
- }
- $fw_conf->{ipset_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
- } else {
- foreach my $name (keys %{$fw_conf->{ipset}}) {
- raise_param_exc({ name => "IPSet '$name' already exists" })
- if $name eq $param->{name};
- }
+ # prevent overwriting existing ipset
+ raise_param_exc({ name => "IPSet '$param->{name}' does already exist"})
+ if $fw_conf->{ipset}->{$param->{name}} &&
+ $param->{name} ne $param->{rename};
- $fw_conf->{ipset}->{$param->{name}} = [];
- $fw_conf->{ipset_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
- }
+ my $data = delete $fw_conf->{ipset}->{$param->{rename}};
+ $fw_conf->{ipset}->{$param->{name}} = $data;
+ if (my $comment = delete $fw_conf->{ipset_comments}->{$param->{rename}}) {
+ $fw_conf->{ipset_comments}->{$param->{name}} = $comment;
+ }
+ $fw_conf->{ipset_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
+ } else {
+ foreach my $name (keys %{$fw_conf->{ipset}}) {
+ raise_param_exc({ name => "IPSet '$name' already exists" })
+ if $name eq $param->{name};
+ }
+
+ $fw_conf->{ipset}->{$param->{name}} = [];
+ $fw_conf->{ipset_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
+ }
- $class->save_config($param, $fw_conf);
+ $class->save_config($param, $fw_conf);
+ });
return undef;
}});