X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FAPI2%2FFirewall%2FGroups.pm;h=9e4d08a4f260dd31e0a28268bff4ecc2c680379d;hp=d7f33b87a85ec6b1fef1ffda47936f0ff7f205fc;hb=e2beb7aa9900c650ec69594a2f26cc2889908134;hpb=d1c53b3e0daad6891ad6a97b6e79d03d7e781a78 diff --git a/src/PVE/API2/Firewall/Groups.pm b/src/PVE/API2/Firewall/Groups.pm index d7f33b8..9e4d08a 100644 --- a/src/PVE/API2/Firewall/Groups.pm +++ b/src/PVE/API2/Firewall/Groups.pm @@ -3,93 +3,158 @@ 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 (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', + name => 'list_security_groups', path => '', method => 'GET', description => "List security groups.", - proxyto => 'node', parameters => { additionalProperties => 0, - properties => { - node => get_standard_option('pve-node'), - }, + properties => {}, }, returns => { type => 'array', items => { type => "object", properties => { - name => { - description => "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 $groups_conf = PVE::Firewall::load_security_groups(); + my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - my $res = []; - foreach my $group (keys %{$groups_conf->{rules}}) { - push @$res, { name => $group, count => scalar(@{$groups_conf->{rules}->{$group}}) }; - } - - return $res; + return &$get_security_group_list($cluster_conf); }}); __PACKAGE__->register_method({ - name => 'get_rules', - path => '{group}', - method => 'GET', - description => "List security groups rules.", - proxyto => 'node', + name => 'create_security_group', + path => '', + method => 'POST', + description => "Create new security group.", + protected => 1, parameters => { - additionalProperties => 0, - properties => { - node => get_standard_option('pve-node'), - group => { - description => "Security group name.", + additionalProperties => 0, + properties => { + group => get_standard_option('pve-security-group-name'), + comment => { type => 'string', + optional => 1, }, + rename => get_standard_option('pve-security-group-name', { + 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 => 'array', - items => { - type => "object", - properties => {}, + returns => { type => 'null' }, + code => sub { + my ($param) = @_; + + my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); + + if ($param->{rename}) { + 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->{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}; + } + + $cluster_conf->{groups}->{$param->{group}} = []; + $cluster_conf->{group_comments}->{$param->{group}} = $param->{comment} if defined($param->{comment}); + } + + PVE::Firewall::save_clusterfw_conf($cluster_conf); + + return undef; + }}); + +__PACKAGE__->register_method({ + name => 'delete_security_group', + path => '{group}', + method => 'DELETE', + description => "Delete security group.", + protected => 1, + parameters => { + additionalProperties => 0, + properties => { + group => get_standard_option('pve-security-group-name'), + digest => get_standard_option('pve-config-digest'), }, }, + returns => { type => 'null' }, code => sub { my ($param) = @_; + + my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - my $groups_conf = PVE::Firewall::load_security_groups(); + return undef if !$cluster_conf->{groups}->{$param->{group}}; - my $rules = $groups_conf->{rules}->{$param->{group}}; - die "no such security group\n" if !defined($rules); + my (undef, $digest) = &$get_security_group_list($cluster_conf); + PVE::Tools::assert_if_modified($digest, $param->{digest}); - my $digest = $groups_conf->{digest}; + die "Security group '$param->{group}' is not empty\n" + if scalar(@{$cluster_conf->{groups}->{$param->{group}}}); - my $res = []; + delete $cluster_conf->{groups}->{$param->{group}}; - my $ind = 0; - foreach my $rule (@$rules) { - push @$res, PVE::Firewall::cleanup_fw_rule($rule, $digest, $ind++); - } + PVE::Firewall::save_clusterfw_conf($cluster_conf); - return $res; + return undef; }}); +__PACKAGE__->register_method ({ + subclass => "PVE::API2::Firewall::GroupRules", + path => '{group}', +}); + 1;