X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FAPI2%2FFirewall%2FGroups.pm;h=8f94b6df72f58bc41bffb9da4e2ea9068cee22fb;hp=0a6126afa0105642eb937e6c21f2aeec733872b9;hb=2f46ee4f78ab45a13f6ca2830bcbaf45a8e8fe7a;hpb=9567aa9160afb99986c37be328cf1a886b005649 diff --git a/src/PVE/API2/Firewall/Groups.pm b/src/PVE/API2/Firewall/Groups.pm index 0a6126a..8f94b6d 100644 --- a/src/PVE/API2/Firewall/Groups.pm +++ b/src/PVE/API2/Firewall/Groups.pm @@ -3,43 +3,64 @@ package PVE::API2::Firewall::Groups; use strict; use warnings; use PVE::JSONSchema qw(get_standard_option); +use PVE::Exception qw(raise raise_param_exc); use PVE::Firewall; use PVE::API2::Firewall::Rules; -use Data::Dumper; # fixme: remove use base qw(PVE::RESTHandler); +my $get_security_group_list = sub { + my ($cluster_conf) = @_; + + my $res = []; + foreach my $group (sort keys %{$cluster_conf->{groups}}) { + my $data = { + group => $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 => '', method => 'GET', description => "List security groups.", + permissions => { user => 'all' }, parameters => { additionalProperties => 0, + properties => {}, }, returns => { type => 'array', items => { type => "object", properties => { - name => get_standard_option('pve-security-group-name'), + group => get_standard_option('pve-security-group-name'), + digest => get_standard_option('pve-config-digest', { optional => 0} ), + comment => { + type => 'string', + optional => 1, + } }, }, - links => [ { rel => 'child', href => "{name}" } ], + links => [ { rel => 'child', href => "{group}" } ], }, code => sub { my ($param) = @_; my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - my $res = []; - foreach my $group (keys %{$cluster_conf->{groups}}) { - push @$res, { name => $group, count => scalar(@{$cluster_conf->{groups}->{$group}}) }; - } - - return $res; + return &$get_security_group_list($cluster_conf); }}); __PACKAGE__->register_method({ @@ -48,14 +69,22 @@ __PACKAGE__->register_method({ method => 'POST', description => "Create new security group.", protected => 1, + permissions => { + check => ['perm', '/', [ 'Sys.Modify' ]], + }, parameters => { additionalProperties => 0, properties => { - name => get_standard_option('pve-security-group-name'), + group => get_standard_option('pve-security-group-name'), + comment => { + type => 'string', + optional => 1, + }, rename => get_standard_option('pve-security-group-name', { - description => "Rename an existing security group.", + description => "Rename/update an existing security group. You can set 'rename' to the same value as 'name' to update the 'comment' of an existing group.", optional => 1, }), + digest => get_standard_option('pve-config-digest'), }, }, returns => { type => 'null' }, @@ -64,53 +93,36 @@ __PACKAGE__->register_method({ my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - foreach my $name (keys %{$cluster_conf->{groups}}) { - raise_param_exc({ name => "Security group '$name' already exists" }) - if $name eq $param->{name}; - } - if ($param->{rename}) { - raise_param_exc({ name => "Security group '$param->{rename}' does not exists" }) + my (undef, $digest) = &$get_security_group_list($cluster_conf); + PVE::Tools::assert_if_modified($digest, $param->{digest}); + + raise_param_exc({ group => "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; - } else { - $cluster_conf->{groups}->{$param->{name}} = []; - } - PVE::Firewall::save_clusterfw_conf($cluster_conf); - - return undef; - }}); + # prevent overwriting an existing group + raise_param_exc({ group => "Security group '$param->{group}' does already exist" }) + if $cluster_conf->{groups}->{$param->{group}} && + $param->{group} ne $param->{rename}; + my $data = delete $cluster_conf->{groups}->{$param->{rename}}; + $cluster_conf->{groups}->{$param->{group}} = $data; + if (my $comment = delete $cluster_conf->{group_comments}->{$param->{rename}}) { + $cluster_conf->{group_comments}->{$param->{group}} = $comment; + } + $cluster_conf->{group_comments}->{$param->{group}} = $param->{comment} if defined($param->{comment}); + } else { + foreach my $name (keys %{$cluster_conf->{groups}}) { + raise_param_exc({ group => "Security group '$name' already exists" }) + if $name eq $param->{group}; + } -__PACKAGE__->register_method({ - name => 'delete_security_group', - path => '{name}', - method => 'DELETE', - description => "Delete security group.", - protected => 1, - parameters => { - additionalProperties => 0, - properties => { - name => get_standard_option('pve-security-group-name'), + $cluster_conf->{groups}->{$param->{group}} = []; + $cluster_conf->{group_comments}->{$param->{group}} = $param->{comment} if defined($param->{comment}); } - }, - returns => { type => 'null' }, - code => sub { - my ($param) = @_; - - my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - - return undef if !$cluster_conf->{groups}->{$param->{name}}; - - die "Security group '$param->{name}' is not empty\n" - if scalar(@{$cluster_conf->{groups}->{$param->{name}}}); - - delete $cluster_conf->{groups}->{$param->{name}}; PVE::Firewall::save_clusterfw_conf($cluster_conf); - + return undef; }});