X-Git-Url: https://git.proxmox.com/?p=pve-firewall.git;a=blobdiff_plain;f=src%2FPVE%2FAPI2%2FFirewall%2FAliases.pm;h=33ac669d6381f76c6f5c8ce46156925bb22ca1d7;hp=a3a379455bdbf6f795853f7952a00d4441c0f9cf;hb=HEAD;hpb=cdc39d63b2361e30bab76c715123e88a6d9589b6 diff --git a/src/PVE/API2/Firewall/Aliases.pm b/src/PVE/API2/Firewall/Aliases.pm index a3a3794..33ac669 100644 --- a/src/PVE/API2/Firewall/Aliases.pm +++ b/src/PVE/API2/Firewall/Aliases.pm @@ -9,10 +9,10 @@ use PVE::Firewall; use base qw(PVE::RESTHandler); -my $api_properties = { +my $api_properties = { cidr => { description => "Network/IP specification in CIDR format.", - type => 'string', format => 'IPv4orCIDR', + type => 'string', format => 'IPorCIDR', }, name => get_standard_option('pve-fw-alias'), rename => get_standard_option('pve-fw-alias', { @@ -25,6 +25,12 @@ my $api_properties = { }, }; +sub lock_config { + my ($class, $param, $code) = @_; + + die "implement this in subclass"; +} + sub load_config { my ($class, $param) = @_; @@ -39,6 +45,12 @@ sub save_aliases { die "implement this in subclass"; } +sub rule_env { + my ($class, $param) = @_; + + die "implement this in subclass"; +} + my $additional_param_hash = {}; sub additional_parameters { @@ -75,6 +87,7 @@ sub register_get_aliases { path => '', method => 'GET', description => "List aliases", + permissions => PVE::Firewall::rules_audit_permissions($class->rule_env()), parameters => { additionalProperties => 0, properties => $properties, @@ -90,7 +103,7 @@ sub register_get_aliases { type => 'string', optional => 1, }, - digest => get_standard_option('pve-config-digest', { optional => 0} ), + digest => get_standard_option('pve-config-digest', { optional => 0} ), }, }, links => [ { rel => 'child', href => "{name}" } ], @@ -120,6 +133,7 @@ sub register_create_alias { path => '', method => 'POST', description => "Create IP or Network Alias.", + permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()), protected => 1, parameters => { additionalProperties => 0, @@ -129,19 +143,23 @@ sub register_create_alias { code => sub { my ($param) = @_; - my ($fw_conf, $aliases) = $class->load_config($param); + $class->lock_config($param, sub { + my ($param) = @_; - my $name = lc($param->{name}); - - raise_param_exc({ name => "alias '$param->{name}' already exists" }) - if defined($aliases->{$name}); - - my $data = { name => $param->{name}, cidr => $param->{cidr} }; - $data->{comment} = $param->{comment} if $param->{comment}; + my ($fw_conf, $aliases) = $class->load_config($param); + + my $name = lc($param->{name}); - $aliases->{$name} = $data; + raise_param_exc({ name => "alias '$param->{name}' already exists" }) + if defined($aliases->{$name}); - $class->save_aliases($param, $fw_conf, $aliases); + my $data = { name => $param->{name}, cidr => $param->{cidr} }; + $data->{comment} = $param->{comment} if $param->{comment}; + + $aliases->{$name} = $data; + + $class->save_aliases($param, $fw_conf, $aliases); + }); return undef; }}); @@ -153,12 +171,13 @@ sub register_read_alias { my $properties = $class->additional_parameters(); $properties->{name} = $api_properties->{name}; - + $class->register_method({ name => 'read_alias', path => '{name}', method => 'GET', description => "Read alias.", + permissions => PVE::Firewall::rules_audit_permissions($class->rule_env()), parameters => { additionalProperties => 0, properties => $properties, @@ -194,6 +213,7 @@ sub register_update_alias { path => '{name}', method => 'PUT', description => "Update IP or Network alias.", + permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()), protected => 1, parameters => { additionalProperties => 0, @@ -203,34 +223,39 @@ sub register_update_alias { code => sub { my ($param) = @_; - my ($fw_conf, $aliases) = $class->load_config($param); + $class->lock_config($param, sub { + my ($param) = @_; - my $list = &$aliases_to_list($aliases); + my ($fw_conf, $aliases) = $class->load_config($param); - my (undef, $digest) = PVE::Firewall::copy_list_with_digest($list); + my $list = &$aliases_to_list($aliases); - PVE::Tools::assert_if_modified($digest, $param->{digest}); + my (undef, $digest) = PVE::Firewall::copy_list_with_digest($list); - my $name = lc($param->{name}); + PVE::Tools::assert_if_modified($digest, $param->{digest}); - raise_param_exc({ name => "no such alias" }) if !$aliases->{$name}; + my $name = lc($param->{name}); - my $data = { name => $param->{name}, cidr => $param->{cidr} }; - $data->{comment} = $param->{comment} if $param->{comment}; + raise_param_exc({ name => "no such alias" }) if !$aliases->{$name}; - $aliases->{$name} = $data; + my $data = { name => $param->{name}, cidr => $param->{cidr} }; + $data->{comment} = $param->{comment} if $param->{comment}; - my $rename = lc($param->{rename}); + $aliases->{$name} = $data; - if ($rename && ($name ne $rename)) { - raise_param_exc({ name => "alias '$param->{rename}' already exists" }) - if defined($aliases->{$rename}); - $aliases->{$name}->{name} = $param->{rename}; - $aliases->{$rename} = $aliases->{$name}; - delete $aliases->{$name}; - } + my $rename = $param->{rename}; + $rename = lc($rename) if $rename; + + if ($rename && ($name ne $rename)) { + raise_param_exc({ name => "alias '$param->{rename}' already exists" }) + if defined($aliases->{$rename}); + $aliases->{$name}->{name} = $param->{rename}; + $aliases->{$rename} = $aliases->{$name}; + delete $aliases->{$name}; + } - $class->save_aliases($param, $fw_conf, $aliases); + $class->save_aliases($param, $fw_conf, $aliases); + }); return undef; }}); @@ -242,7 +267,6 @@ sub register_delete_alias { my $properties = $class->additional_parameters(); $properties->{name} = $api_properties->{name}; - $properties->{cidr} = $api_properties->{cidr}; $properties->{digest} = get_standard_option('pve-config-digest'); $class->register_method({ @@ -250,6 +274,7 @@ sub register_delete_alias { path => '{name}', method => 'DELETE', description => "Remove IP or Network alias.", + permissions => PVE::Firewall::rules_modify_permissions($class->rule_env()), protected => 1, parameters => { additionalProperties => 0, @@ -259,17 +284,21 @@ sub register_delete_alias { code => sub { my ($param) = @_; - my ($fw_conf, $aliases) = $class->load_config($param); + $class->lock_config($param, sub { + my ($param) = @_; - my $list = &$aliases_to_list($aliases); - my (undef, $digest) = PVE::Firewall::copy_list_with_digest($list); - PVE::Tools::assert_if_modified($digest, $param->{digest}); + my ($fw_conf, $aliases) = $class->load_config($param); - my $name = lc($param->{name}); - delete $aliases->{$name}; + my $list = &$aliases_to_list($aliases); + my (undef, $digest) = PVE::Firewall::copy_list_with_digest($list); + PVE::Tools::assert_if_modified($digest, $param->{digest}); + + my $name = lc($param->{name}); + delete $aliases->{$name}; + + $class->save_aliases($param, $fw_conf, $aliases); + }); - $class->save_aliases($param, $fw_conf, $aliases); - return undef; }}); } @@ -291,6 +320,18 @@ use warnings; use base qw(PVE::API2::Firewall::AliasesBase); +sub rule_env { + my ($class, $param) = @_; + + return 'cluster'; +} + +sub lock_config { + my ($class, $param, $code) = @_; + + PVE::Firewall::lock_clusterfw_conf(10, $code, $param); +} + sub load_config { my ($class, $param) = @_; @@ -309,4 +350,92 @@ sub save_aliases { __PACKAGE__->register_handlers(); +package PVE::API2::Firewall::VMAliases; + +use strict; +use warnings; +use PVE::JSONSchema qw(get_standard_option); + +use base qw(PVE::API2::Firewall::AliasesBase); + +sub rule_env { + my ($class, $param) = @_; + + return 'vm'; +} + +__PACKAGE__->additional_parameters({ + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), +}); + +sub lock_config { + my ($class, $param, $code) = @_; + + PVE::Firewall::lock_vmfw_conf($param->{vmid}, 10, $code, $param); +} + +sub load_config { + my ($class, $param) = @_; + + my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); + my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'vm', $param->{vmid}); + my $aliases = $fw_conf->{aliases}; + + return ($fw_conf, $aliases); +} + +sub save_aliases { + my ($class, $param, $fw_conf, $aliases) = @_; + + $fw_conf->{aliases} = $aliases; + PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf); +} + +__PACKAGE__->register_handlers(); + +package PVE::API2::Firewall::CTAliases; + +use strict; +use warnings; +use PVE::JSONSchema qw(get_standard_option); + +use base qw(PVE::API2::Firewall::AliasesBase); + +sub rule_env { + my ($class, $param) = @_; + + return 'ct'; +} + +__PACKAGE__->additional_parameters({ + node => get_standard_option('pve-node'), + vmid => get_standard_option('pve-vmid'), +}); + +sub lock_config { + my ($class, $param, $code) = @_; + + PVE::Firewall::lock_vmfw_conf($param->{vmid}, 10, $code, $param); +} + +sub load_config { + my ($class, $param) = @_; + + my $cluster_conf = PVE::Firewall::load_clusterfw_conf(); + my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, 'ct', $param->{vmid}); + my $aliases = $fw_conf->{aliases}; + + return ($fw_conf, $aliases); +} + +sub save_aliases { + my ($class, $param, $fw_conf, $aliases) = @_; + + $fw_conf->{aliases} = $aliases; + PVE::Firewall::save_vmfw_conf($param->{vmid}, $fw_conf); +} + +__PACKAGE__->register_handlers(); + 1;