X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FAPI2%2FFirewall%2FGroups.pm;h=e8f211603b687fc9705cb6acdb4ac77f7848bf9c;hp=6a07fd09d1a294c96deff43075ad937d4feab9d2;hb=5c9da37bf649c4b23994a5342d3340c488a65999;hpb=b4366f0078a37b8542dbeca999dc39cbd4a00f7f diff --git a/src/PVE/API2/Firewall/Groups.pm b/src/PVE/API2/Firewall/Groups.pm index 6a07fd0..e8f2116 100644 --- a/src/PVE/API2/Firewall/Groups.pm +++ b/src/PVE/API2/Firewall/Groups.pm @@ -3,275 +3,128 @@ 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); -__PACKAGE__->register_method({ - name => 'list', - path => '', - method => 'GET', - description => "List security groups.", - parameters => { - additionalProperties => 0, - }, - returns => { - type => 'array', - items => { - type => "object", - properties => { - name => { - description => "Security group name.", - type => 'string', - }, - }, - }, - links => [ { rel => 'child', href => "{name}" } ], - }, - code => sub { - my ($param) = @_; +my $get_security_group_list = sub { + my ($cluster_conf) = @_; - 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}}) }; + 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; + } - return $res; - }}); + my ($list, $digest) = PVE::Firewall::copy_list_with_digest($res); + + return wantarray ? ($list, $digest) : $list; +}; __PACKAGE__->register_method({ - name => 'get_rules', - path => '{group}', + name => 'list_security_groups', + path => '', method => 'GET', - description => "List security groups rules.", + description => "List security groups.", + permissions => { user => 'all' }, parameters => { additionalProperties => 0, - properties => { - group => { - description => "Security group name.", - type => 'string', - }, - }, + properties => {}, }, returns => { type => 'array', items => { type => "object", - properties => { - pos => { - type => 'integer', + properties => { + 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 => "{pos}" } ], + links => [ { rel => 'child', href => "{group}" } ], }, code => sub { my ($param) = @_; my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - my $rules = $cluster_conf->{groups}->{$param->{group}}; - die "no such security group\n" if !defined($rules); - - my $digest = $cluster_conf->{digest}; - - my $res = []; - - my $ind = 0; - foreach my $rule (@$rules) { - push @$res, PVE::Firewall::cleanup_fw_rule($rule, $digest, $ind++); - } - - return $res; + return &$get_security_group_list($cluster_conf); }}); __PACKAGE__->register_method({ - name => 'get_rule', - path => '{group}/{pos}', - method => 'GET', - description => "Get single rule data.", - parameters => { - additionalProperties => 0, - properties => { - group => { - description => "Security group name.", - type => 'string', - }, - pos => { - description => "Return rule from position .", - type => 'integer', - minimum => 0, - }, - }, - }, - returns => { - type => "object", - properties => { - pos => { - type => 'integer', - } - }, - }, - code => sub { - my ($param) = @_; - - my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - - my $rules = $cluster_conf->{groups}->{$param->{group}}; - die "no such security group\n" if !defined($rules); - - my $digest = $cluster_conf->{digest}; - # fixme: check digest - - die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules); - - my $rule = $rules->[$param->{pos}]; - - return PVE::Firewall::cleanup_fw_rule($rule, $digest, $param->{pos}); - }}); - - -__PACKAGE__->register_method({ - name => 'create_rule', - path => '{group}', + name => 'create_security_group', + path => '', method => 'POST', - description => "Create new rule.", + description => "Create new security group.", protected => 1, - parameters => { - additionalProperties => 0, - properties => PVE::Firewall::add_rule_properties({ - group => { - description => "Security group name.", - type => 'string', - }, - }), + permissions => { + check => ['perm', '/', [ 'Sys.Modify' ]], }, - returns => { type => "null" }, - code => sub { - my ($param) = @_; - - my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - - my $rules = $cluster_conf->{groups}->{$param->{group}}; - die "no such security group\n" if !defined($rules); - - my $digest = $cluster_conf->{digest}; - - my $rule = { type => 'out', action => 'ACCEPT', enable => 0}; - - PVE::Firewall::copy_rule_data($rule, $param); - - unshift @$rules, $rule; - - PVE::Firewall::save_clusterfw_conf($cluster_conf); - - return undef; - }}); - -__PACKAGE__->register_method({ - name => 'update_rule', - path => '{group}/{pos}', - method => 'PUT', - description => "Modify rule data.", - protected => 1, parameters => { - additionalProperties => 0, - properties => PVE::Firewall::add_rule_properties({ - group => { - description => "Security group name.", + additionalProperties => 0, + properties => { + group => get_standard_option('pve-security-group-name'), + comment => { type => 'string', - }, - moveto => { - description => "Move rule to new position . Other arguments are ignored.", - type => 'integer', - minimum => 0, 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 => "null" }, + returns => { type => 'null' }, code => sub { my ($param) = @_; my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - my $rules = $cluster_conf->{groups}->{$param->{group}}; - die "no such security group\n" if !defined($rules); + if ($param->{rename}) { + my (undef, $digest) = &$get_security_group_list($cluster_conf); + PVE::Tools::assert_if_modified($digest, $param->{digest}); - my $digest = $cluster_conf->{digest}; - # fixme: check digest - - die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules); - - my $rule = $rules->[$param->{pos}]; + raise_param_exc({ group => "Security group '$param->{rename}' does not exists" }) + if !$cluster_conf->{groups}->{$param->{rename}}; - my $moveto = $param->{moveto}; - if (defined($moveto) && $moveto != $param->{pos}) { - my $newrules = []; - for (my $i = 0; $i < scalar(@$rules); $i++) { - next if $i == $param->{pos}; - if ($i == $moveto) { - push @$newrules, $rule; - } - push @$newrules, $rules->[$i]; + 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; } - push @$newrules, $rule if $moveto >= scalar(@$rules); - - $cluster_conf->{groups}->{$param->{group}} = $newrules; + $cluster_conf->{group_comments}->{$param->{group}} = $param->{comment} if defined($param->{comment}); } else { - PVE::Firewall::copy_rule_data($rule, $param); + 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_rule', - path => '{group}/{pos}', - method => 'DELETE', - description => "Delete rule.", - protected => 1, - parameters => { - additionalProperties => 0, - properties => { - group => { - description => "Security group name.", - type => 'string', - }, - pos => { - description => "Delete rule at position .", - type => 'integer', - minimum => 0, - }, - }, - }, - returns => { type => "null" }, - code => sub { - my ($param) = @_; - - my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); - - my $rules = $cluster_conf->{groups}->{$param->{group}}; - die "no such security group\n" if !defined($rules); - - my $digest = $cluster_conf->{digest}; - # fixme: check digest - die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules); - - splice(@$rules, $param->{pos}, 1); - - PVE::Firewall::save_clusterfw_conf($cluster_conf); - return undef; - }}); + }}); + +__PACKAGE__->register_method ({ + subclass => "PVE::API2::Firewall::GroupRules", + path => '{group}', +}); 1;