X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FAPI2%2FFirewall%2FIPSet.pm;h=45851d442dc7fed406b067938f0650854a0a2532;hp=c9372fac138ab4b5beff39eaf30cb54b20ff7f03;hb=9acc720fadfd443a4bac4746222aeeb39dc03e86;hpb=76aad6c578798e0fe2a51cd18f423df37848dee7 diff --git a/src/PVE/API2/Firewall/IPSet.pm b/src/PVE/API2/Firewall/IPSet.pm index c9372fa..45851d4 100644 --- a/src/PVE/API2/Firewall/IPSet.pm +++ b/src/PVE/API2/Firewall/IPSet.pm @@ -14,10 +14,7 @@ my $api_properties = { description => "Network/IP specification in CIDR format.", type => 'string', format => 'IPv4orCIDR', }, - name => { - description => "IP set name.", - type => 'string', - }, + name => get_standard_option('ipset-name'), comment => { type => 'string', optional => 1, @@ -32,11 +29,9 @@ sub load_config { my ($class, $param) = @_; die "implement this in subclass"; - - #return ($fw_conf, $rules); } -sub save_rules { +sub save_ipset { my ($class, $param, $fw_conf, $rules) = @_; die "implement this in subclass"; @@ -89,7 +84,8 @@ sub register_get_ipset { nomatch => { type => 'boolean', optional => 1, - }, + }, + digest => get_standard_option('pve-config-digest', { optional => 0} ), }, }, links => [ { rel => 'child', href => "{cidr}" } ], @@ -99,7 +95,7 @@ sub register_get_ipset { my ($fw_conf, $ipset) = $class->load_config($param); - return $ipset; + return PVE::Firewall::copy_list_with_digest($ipset); }}); } @@ -112,7 +108,7 @@ sub register_create_ip { $properties->{cidr} = $api_properties->{cidr}; $properties->{nomatch} = $api_properties->{nomatch}; $properties->{comment} = $api_properties->{comment}; - + $class->register_method({ name => 'create_ip', path => '', @@ -172,8 +168,12 @@ sub register_read_ip { my ($fw_conf, $ipset) = $class->load_config($param); - foreach my $entry (@$ipset) { - return $entry if $entry->{cidr} eq $param->{cidr}; + my $list = PVE::Firewall::copy_list_with_digest($ipset); + + foreach my $entry (@$list) { + if ($entry->{cidr} eq $param->{cidr}) { + return $entry; + } } raise_param_exc({ cidr => "no such IP/Network" }); @@ -189,7 +189,8 @@ sub register_update_ip { $properties->{cidr} = $api_properties->{cidr}; $properties->{nomatch} = $api_properties->{nomatch}; $properties->{comment} = $api_properties->{comment}; - + $properties->{digest} = get_standard_option('pve-config-digest'); + $class->register_method({ name => 'update_ip', path => '{cidr}', @@ -206,6 +207,10 @@ sub register_update_ip { my ($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}); + warn "TEST:$digest:$param->{digest}:\n"; + foreach my $entry (@$ipset) { if($entry->{cidr} eq $param->{cidr}) { $entry->{nomatch} = $param->{nomatch}; @@ -226,7 +231,8 @@ sub register_delete_ip { $properties->{name} = $api_properties->{name}; $properties->{cidr} = $api_properties->{cidr}; - + $properties->{digest} = get_standard_option('pve-config-digest'); + $class->register_method({ name => 'remove_ip', path => '{cidr}', @@ -243,6 +249,9 @@ sub register_delete_ip { my ($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}); + my $new = []; foreach my $entry (@$ipset) { @@ -295,11 +304,31 @@ package PVE::API2::Firewall::BaseIPSetList; use strict; use warnings; -use PVE::Firewall; +use PVE::JSONSchema qw(get_standard_option); use PVE::Exception qw(raise_param_exc); +use PVE::Firewall; 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) = @_; @@ -316,10 +345,12 @@ sub register_index { items => { type => "object", properties => { - name => { - description => "IPSet name.", + name => get_standard_option('ipset-name'), + digest => get_standard_option('pve-config-digest', { optional => 0} ), + comment => { type => 'string', - }, + optional => 1, + } }, }, links => [ { rel => 'child', href => "{name}" } ], @@ -329,12 +360,7 @@ sub register_index { my $fw_conf = $class->load_config(); - my $res = []; - foreach my $name (keys %{$fw_conf->{ipset}}) { - push @$res, { name => $name, count => scalar(@{$fw_conf->{ipset}->{$name}}) }; - } - - return $res; + return &$get_ipset_list($fw_conf); }}); } @@ -350,11 +376,16 @@ sub register_create { parameters => { additionalProperties => 0, properties => { - name => { - # fixme: verify format - description => "IP set name.", + name => get_standard_option('ipset-name'), + comment => { type => 'string', + optional => 1, }, + rename => get_standard_option('ipset-name', { + description => "Rename an existing IPSet. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing IPSet.", + optional => 1, + }), + digest => get_standard_option('pve-config-digest'), } }, returns => { type => 'null' }, @@ -363,12 +394,29 @@ sub register_create { my $fw_conf = $class->load_config(); - 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 { + 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}); } - $fw_conf->{ipset}->{$param->{name}} = []; $class->save_config($fw_conf); return undef; @@ -387,12 +435,9 @@ sub register_delete { parameters => { additionalProperties => 0, properties => { - name => { - # fixme: verify format - description => "IP set name.", - type => 'string', - }, - } + name => get_standard_option('ipset-name'), + digest => get_standard_option('pve-config-digest'), + }, }, returns => { type => 'null' }, code => sub { @@ -402,6 +447,9 @@ sub register_delete { 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}}});