compute digest per section.
my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
- my $options = $cluster_conf->{options};
-
- return $options;
+ return PVE::Firewall::copy_opject_with_digest($cluster_conf->{options});
}});
my $option_properties = {
description => "A list of settings you want to delete.",
optional => 1,
},
+ digest => get_standard_option('pve-config-digest'),
}),
},
returns => { type => "null" },
my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
+ my (undef, $digest) = PVE::Firewall::copy_opject_with_digest($cluster_conf->{options});
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
+
if ($param->{delete}) {
foreach my $opt (PVE::Tools::split_list($param->{delete})) {
raise_param_exc({ delete => "no such option '$opt'" })
use base qw(PVE::RESTHandler);
+my $get_security_group_list = sub {
+ my ($cluster_conf) = @_;
+
+ my $res = [];
+ foreach my $group (keys %{$cluster_conf->{groups}}) {
+ my $data = {
+ name => $group,
+ };
+ if (my $comment = $cluster_conf->{group_comments}->{$group}) {
+ $data->{comment} = $comment;
+ }
+ push @$res, $data;
+ }
+
+ my ($list, $digest) = PVE::Firewall::copy_list_with_digest($res);
+
+ return wantarray ? ($list, $digest) : $list;
+};
+
__PACKAGE__->register_method({
name => 'list_security_groups',
path => '',
my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
- my $digest = $cluster_conf->{digest};
-
- my $res = [];
- foreach my $group (keys %{$cluster_conf->{groups}}) {
- my $data = {
- name => $group,
- digest => $digest,
- count => scalar(@{$cluster_conf->{groups}->{$group}})
- };
- if (my $comment = $cluster_conf->{group_comments}->{$group}) {
- $data->{comment} = $comment;
- }
- push @$res, $data;
- }
-
- return $res;
+ return &$get_security_group_list($cluster_conf);
}});
__PACKAGE__->register_method({
my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
- my $digest = $cluster_conf->{digest};
-
- PVE::Tools::assert_if_modified($digest, $param->{digest});
-
- if (!$param->{rename}) {
- foreach my $name (keys %{$cluster_conf->{groups}}) {
- raise_param_exc({ name => "Security group '$name' already exists" })
- if $name eq $param->{name};
- }
- }
-
if ($param->{rename}) {
+ my (undef, $digest) = &$get_security_group_list($cluster_conf);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
+
raise_param_exc({ name => "Security group '$param->{rename}' does not exists" })
if !$cluster_conf->{groups}->{$param->{rename}};
+
my $data = delete $cluster_conf->{groups}->{$param->{rename}};
$cluster_conf->{groups}->{$param->{name}} = $data;
if (my $comment = delete $cluster_conf->{group_comments}->{$param->{rename}}) {
}
$cluster_conf->{group_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
} else {
+ foreach my $name (keys %{$cluster_conf->{groups}}) {
+ raise_param_exc({ name => "Security group '$name' already exists" })
+ if $name eq $param->{name};
+ }
+
$cluster_conf->{groups}->{$param->{name}} = [];
$cluster_conf->{group_comments}->{$param->{name}} = $param->{comment} if defined($param->{comment});
}
my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
- PVE::Tools::assert_if_modified($cluster_conf->{digest}, $param->{digest});
-
return undef if !$cluster_conf->{groups}->{$param->{name}};
+ my (undef, $digest) = &$get_security_group_list($cluster_conf);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
+
die "Security group '$param->{name}' is not empty\n"
if scalar(@{$cluster_conf->{groups}->{$param->{name}}});
my $hostfw_conf = PVE::Firewall::load_hostfw_conf();
- my $options = $hostfw_conf->{options} || {};
-
- my $digest = $hostfw_conf->{digest};
-
- $options->{digest} = $digest;
-
- return $options;
+ return PVE::Firewall::copy_opject_with_digest($hostfw_conf->{options});
}});
1;
my ($fw_conf, $ipset) = $class->load_config($param);
- my $digest = $fw_conf->{digest};
-
- my $res = [];
- foreach my $entry (@$ipset) {
- my $data = {digest => $digest};
- foreach my $k (qw(cidr comment nomatch)) {
- $data->{$k} = $entry->{$k} if $entry->{$k};
- }
- push @$res, $data;
- }
-
- return $res;
+ return PVE::Firewall::copy_list_with_digest($ipset);
}});
}
my ($param) = @_;
my ($fw_conf, $ipset) = $class->load_config($param);
- my $digest = $fw_conf->{digest};
- foreach my $entry (@$ipset) {
+ my $list = PVE::Firewall::copy_list_with_digest($ipset);
+
+ foreach my $entry (@$list) {
if ($entry->{cidr} eq $param->{cidr}) {
- $entry->{digest} = $digest;
return $entry;
}
}
my ($fw_conf, $ipset) = $class->load_config($param);
- PVE::Tools::assert_if_modified($fw_conf->{digest}, $param->{digest});
+ my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
+ warn "TEST:$digest:$param->{digest}:\n";
foreach my $entry (@$ipset) {
if($entry->{cidr} eq $param->{cidr}) {
my ($fw_conf, $ipset) = $class->load_config($param);
- PVE::Tools::assert_if_modified($fw_conf->{digest}, $param->{digest});
+ my (undef, $digest) = PVE::Firewall::copy_list_with_digest($ipset);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
my $new = [];
use base qw(PVE::RESTHandler);
+my $get_ipset_list = sub {
+ my ($fw_conf) = @_;
+
+ my $res = [];
+ foreach my $name (keys %{$fw_conf->{ipset}}) {
+ my $data = {
+ name => $name,
+ };
+ if (my $comment = $fw_conf->{ipset_comments}->{$name}) {
+ $data->{comment} = $comment;
+ }
+ push @$res, $data;
+ }
+
+ my ($list, $digest) = PVE::Firewall::copy_list_with_digest($res);
+
+ return wantarray ? ($list, $digest) : $list;
+};
+
sub register_index {
my ($class) = @_;
my $fw_conf = $class->load_config();
- my $digest = $fw_conf->{digest};
-
- my $res = [];
- foreach my $name (keys %{$fw_conf->{ipset}}) {
- my $data = {
- name => $name,
- digest => $digest,
- count => scalar(@{$fw_conf->{ipset}->{$name}})
- };
- if (my $comment = $fw_conf->{ipset_comments}->{$name}) {
- $data->{comment} = $comment;
- }
- push @$res, $data;
- }
-
- return $res;
+ return &$get_ipset_list($fw_conf);
}});
}
my $fw_conf = $class->load_config();
- my $digest = $fw_conf->{digest};
-
- PVE::Tools::assert_if_modified($digest, $param->{digest});
-
- if (!$param->{rename}) {
- foreach my $name (keys %{$fw_conf->{ipset}}) {
- raise_param_exc({ name => "IPSet '$name' already exists" })
- if $name eq $param->{name};
- }
- }
-
if ($param->{rename}) {
+ my (undef, $digest) = &$get_ipset_list($fw_conf);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
+
raise_param_exc({ name => "IPSet '$param->{rename}' does not exists" })
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 {
+ } 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});
}
my $fw_conf = $class->load_config();
- PVE::Tools::assert_if_modified($fw_conf->{digest}, $param->{digest});
-
return undef if !$fw_conf->{ipset}->{$param->{name}};
+ my (undef, $digest) = &$get_ipset_list($fw_conf);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
+
die "IPSet '$param->{name}' is not empty\n"
if scalar(@{$fw_conf->{ipset}->{$param->{name}}});
my ($fw_conf, $rules) = $class->load_config($param);
- my $digest = $fw_conf->{digest};
-
- my $res = [];
+ my ($list, $digest) = PVE::Firewall::copy_list_with_digest($rules);
my $ind = 0;
- foreach my $rule (@$rules) {
- push @$res, PVE::Firewall::cleanup_fw_rule($rule, $digest, $ind++);
+ foreach my $rule (@$list) {
+ $rule->{pos} = $ind++;
}
- return $res;
+ return $list;
}});
}
my ($fw_conf, $rules) = $class->load_config($param);
- my $digest = $fw_conf->{digest};
+ my ($list, $digest) = PVE::Firewall::copy_list_with_digest($rules);
- die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
+ die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$list);
- my $rule = $rules->[$param->{pos}];
-
- return PVE::Firewall::cleanup_fw_rule($rule, $digest, $param->{pos});
+ my $rule = $list->[$param->{pos}];
+ $rule->{pos} = $param->{pos};
+
+ return $rule;
}});
}
my ($fw_conf, $rules) = $class->load_config($param);
- PVE::Tools::assert_if_modified($fw_conf->{digest}, $param->{digest});
+ my (undef, $digest) = PVE::Firewall::copy_list_with_digest($rules);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
my ($fw_conf, $rules) = $class->load_config($param);
- PVE::Tools::assert_if_modified($fw_conf->{digest}, $param->{digest});
+ my (undef, $digest) = PVE::Firewall::copy_list_with_digest($rules);
+ PVE::Tools::assert_if_modified($digest, $param->{digest});
die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
my $vmfw_conf = PVE::Firewall::load_vmfw_conf($vmid);
- my $options = $vmfw_conf->{options} || {};
+ return PVE::Firewall::copy_opject_with_digest($vmfw_conf->{options});
- my $digest = $vmfw_conf->{digest};
-
- $options->{digest} = $digest;
-
- return $options;
}});
1;
# helper function for API
+sub copy_opject_with_digest {
+ my ($object) = @_;
+
+ my $sha = Digest::SHA->new('sha1');
+
+ my $res = {};
+ foreach my $k (sort keys %$object) {
+ my $v = $object->{$k};
+ $res->{$k} = $v;
+ $sha->add($k, ':', $v, "\n");
+ }
+
+ my $digest = $sha->b64digest;
+
+ $res->{digest} = $digest;
+
+ return wantarray ? ($res, $digest) : $res;
+}
+
+sub copy_list_with_digest {
+ my ($list) = @_;
+
+ my $sha = Digest::SHA->new('sha1');
+
+ my $res = [];
+ foreach my $entry (@$list) {
+ my $data = {};
+ foreach my $k (sort keys %$entry) {
+ my $v = $entry->{$k};
+ $data->{$k} = $v;
+ $sha->add($k, ':', $v, "\n");
+ }
+ push @$res, $data;
+ }
+
+ my $digest = $sha->b64digest;
+
+ foreach my $entry (@$res) {
+ $entry->{digest} = $digest;
+ }
+
+ return wantarray ? ($res, $digest) : $res;
+}
+
my $rule_properties = {
pos => {
description => "Update rule at position <pos>.",
},
};
-sub cleanup_fw_rule {
- my ($rule, $digest, $pos) = @_;
-
- my $r = {};
-
- foreach my $k (keys %$rule) {
- next if !$rule_properties->{$k};
- my $v = $rule->{$k};
- next if !defined($v);
- $r->{$k} = $v;
- $r->{digest} = $digest;
- $r->{pos} = $pos;
- }
-
- return $r;
-}
-
sub add_rule_properties {
my ($properties) = @_;
my $section;
- my $digest = Digest::SHA->new('sha1');
-
while (defined(my $line = <$fh>)) {
- $digest->add($line);
-
next if $line =~ m/^#/;
next if $line =~ m/^\s*$/;
push @{$res->{$section}}, $rule;
}
- $res->{digest} = $digest->b64digest;
-
return $res;
}
my $section;
- my $digest = Digest::SHA->new('sha1');
-
while (defined(my $line = <$fh>)) {
- $digest->add($line);
-
next if $line =~ m/^#/;
next if $line =~ m/^\s*$/;
push @{$res->{$section}}, $rule;
}
- $res->{digest} = $digest->b64digest;
-
return $res;
}
ipset_comments => {},
};
- my $digest = Digest::SHA->new('sha1');
-
while (defined(my $line = <$fh>)) {
- $digest->add($line);
-
next if $line =~ m/^#/;
next if $line =~ m/^\s*$/;
}
}
- $res->{digest} = $digest->b64digest;
return $res;
}