]>
git.proxmox.com Git - pve-firewall.git/blob - src/PVE/API2/Firewall/Rules.pm
1 package PVE
::API2
::Firewall
::RulesBase
;
5 use PVE
::JSONSchema
qw(get_standard_option);
6 use PVE
::Exception
qw(raise raise_param_exc);
10 use base
qw(PVE::RESTHandler);
12 my $api_properties = {
14 description
=> "Rule position.",
21 my ($class, $param) = @_;
23 die "implement this in subclass";
25 #return ($cluster_conf, $fw_conf, $rules);
29 my ($class, $param, $fw_conf, $rules) = @_;
31 die "implement this in subclass";
34 my $additional_param_hash = {};
37 my ($class, $param) = @_;
39 die "implement this in subclass";
42 sub additional_parameters
{
43 my ($class, $new_value) = @_;
45 if (defined($new_value)) {
46 $additional_param_hash->{$class} = $new_value;
51 my $org = $additional_param_hash->{$class} || {};
52 foreach my $p (keys %$org) { $copy->{$p} = $org->{$p}; }
56 my $rules_modify_permissions = sub {
59 if ($rule_env eq 'host') {
61 check
=> ['perm', '/nodes/{node}', [ 'Sys.Modify' ]],
63 } elsif ($rule_env eq 'cluster' || $rule_env eq 'group') {
65 check
=> ['perm', '/', [ 'Sys.Modify' ]],
67 } elsif ($rule_env eq 'vm' || $rule_env eq 'ct') {
69 check
=> ['perm', '/vms/{vmid}', [ 'VM.Config.Network' ]],
76 my $rules_audit_permissions = sub {
79 if ($rule_env eq 'host') {
81 check
=> ['perm', '/nodes/{node}', [ 'Sys.Audit' ]],
83 } elsif ($rule_env eq 'cluster' || $rule_env eq 'group') {
85 check
=> ['perm', '/', [ 'Sys.Audit' ]],
87 } elsif ($rule_env eq 'vm' || $rule_env eq 'ct') {
89 check
=> ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
96 sub register_get_rules
{
99 my $properties = $class->additional_parameters();
101 my $rule_env = $class->rule_env();
103 $class->register_method({
107 description
=> "List rules.",
108 permissions
=> &$rules_audit_permissions($rule_env),
110 additionalProperties
=> 0,
111 properties
=> $properties,
113 proxyto
=> $rule_env eq 'host' ?
'node' : undef,
124 links
=> [ { rel
=> 'child', href
=> "{pos}" } ],
129 my ($cluster_conf, $fw_conf, $rules) = $class->load_config($param);
131 my ($list, $digest) = PVE
::Firewall
::copy_list_with_digest
($rules);
134 foreach my $rule (@$list) {
135 $rule->{pos} = $ind++;
142 sub register_get_rule
{
145 my $properties = $class->additional_parameters();
147 $properties->{pos} = $api_properties->{pos};
149 my $rule_env = $class->rule_env();
151 $class->register_method({
155 description
=> "Get single rule data.",
156 permissions
=> &$rules_audit_permissions($rule_env),
158 additionalProperties
=> 0,
159 properties
=> $properties,
161 proxyto
=> $rule_env eq 'host' ?
'node' : undef,
173 my ($cluster_conf, $fw_conf, $rules) = $class->load_config($param);
175 my ($list, $digest) = PVE
::Firewall
::copy_list_with_digest
($rules);
177 die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$list);
179 my $rule = $list->[$param->{pos}];
180 $rule->{pos} = $param->{pos};
186 sub register_create_rule
{
189 my $properties = $class->additional_parameters();
191 my $create_rule_properties = PVE
::Firewall
::add_rule_properties
($properties);
192 $create_rule_properties->{action
}->{optional
} = 0;
193 $create_rule_properties->{type
}->{optional
} = 0;
195 my $rule_env = $class->rule_env();
197 $class->register_method({
198 name
=> 'create_rule',
201 description
=> "Create new rule.",
203 permissions
=> &$rules_modify_permissions($rule_env),
205 additionalProperties
=> 0,
206 properties
=> $create_rule_properties,
208 proxyto
=> $rule_env eq 'host' ?
'node' : undef,
209 returns
=> { type
=> "null" },
213 my ($cluster_conf, $fw_conf, $rules) = $class->load_config($param);
217 PVE
::Firewall
::copy_rule_data
($rule, $param);
218 PVE
::Firewall
::verify_rule
($rule, $cluster_conf, $fw_conf, $class->rule_env());
220 $rule->{enable
} = 0 if !defined($param->{enable
});
222 unshift @$rules, $rule;
224 $class->save_rules($param, $fw_conf, $rules);
230 sub register_update_rule
{
233 my $properties = $class->additional_parameters();
235 $properties->{pos} = $api_properties->{pos};
237 my $rule_env = $class->rule_env();
239 $properties->{moveto
} = {
240 description
=> "Move rule to new position <moveto>. Other arguments are ignored.",
246 $properties->{delete} = {
247 type
=> 'string', format
=> 'pve-configid-list',
248 description
=> "A list of settings you want to delete.",
252 my $update_rule_properties = PVE
::Firewall
::add_rule_properties
($properties);
254 $class->register_method({
255 name
=> 'update_rule',
258 description
=> "Modify rule data.",
260 permissions
=> &$rules_modify_permissions($rule_env),
262 additionalProperties
=> 0,
263 properties
=> $update_rule_properties,
265 proxyto
=> $rule_env eq 'host' ?
'node' : undef,
266 returns
=> { type
=> "null" },
270 my ($cluster_conf, $fw_conf, $rules) = $class->load_config($param);
272 my (undef, $digest) = PVE
::Firewall
::copy_list_with_digest
($rules);
273 PVE
::Tools
::assert_if_modified
($digest, $param->{digest
});
275 die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
277 my $rule = $rules->[$param->{pos}];
279 my $moveto = $param->{moveto
};
280 if (defined($moveto) && $moveto != $param->{pos}) {
282 for (my $i = 0; $i < scalar(@$rules); $i++) {
283 next if $i == $param->{pos};
285 push @$newrules, $rule;
287 push @$newrules, $rules->[$i];
289 push @$newrules, $rule if $moveto >= scalar(@$rules);
292 PVE
::Firewall
::copy_rule_data
($rule, $param);
294 PVE
::Firewall
::delete_rule_properties
($rule, $param->{'delete'}) if $param->{'delete'};
296 PVE
::Firewall
::verify_rule
($rule, $cluster_conf, $fw_conf, $class->rule_env());
299 $class->save_rules($param, $fw_conf, $rules);
305 sub register_delete_rule
{
308 my $properties = $class->additional_parameters();
310 $properties->{pos} = $api_properties->{pos};
312 $properties->{digest
} = get_standard_option
('pve-config-digest');
314 my $rule_env = $class->rule_env();
316 $class->register_method({
317 name
=> 'delete_rule',
320 description
=> "Delete rule.",
322 permissions
=> &$rules_modify_permissions($rule_env),
324 additionalProperties
=> 0,
325 properties
=> $properties,
327 proxyto
=> $rule_env eq 'host' ?
'node' : undef,
328 returns
=> { type
=> "null" },
332 my ($cluster_conf, $fw_conf, $rules) = $class->load_config($param);
334 my (undef, $digest) = PVE
::Firewall
::copy_list_with_digest
($rules);
335 PVE
::Tools
::assert_if_modified
($digest, $param->{digest
});
337 die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
339 splice(@$rules, $param->{pos}, 1);
341 $class->save_rules($param, $fw_conf, $rules);
347 sub register_handlers
{
350 $class->register_get_rules();
351 $class->register_get_rule();
352 $class->register_create_rule();
353 $class->register_update_rule();
354 $class->register_delete_rule();
357 package PVE
::API2
::Firewall
::GroupRules
;
361 use PVE
::JSONSchema
qw(get_standard_option);
363 use base
qw(PVE::API2::Firewall::RulesBase);
365 __PACKAGE__-
>additional_parameters({ group
=> get_standard_option
('pve-security-group-name') });
369 my ($class, $param) = @_;
375 my ($class, $param) = @_;
377 my $fw_conf = PVE
::Firewall
::load_clusterfw_conf
();
378 my $rules = $fw_conf->{groups
}->{$param->{group
}};
379 die "no such security group '$param->{group}'\n" if !defined($rules);
381 return (undef, $fw_conf, $rules);
385 my ($class, $param, $fw_conf, $rules) = @_;
387 if (!defined($rules)) {
388 delete $fw_conf->{groups
}->{$param->{group
}};
390 $fw_conf->{groups
}->{$param->{group
}} = $rules;
393 PVE
::Firewall
::save_clusterfw_conf
($fw_conf);
396 __PACKAGE__-
>register_method({
397 name
=> 'delete_security_group',
400 description
=> "Delete security group.",
403 additionalProperties
=> 0,
405 group
=> get_standard_option
('pve-security-group-name'),
408 returns
=> { type
=> 'null' },
412 my (undef, $cluster_conf, $rules) = __PACKAGE__-
>load_config($param);
414 die "Security group '$param->{group}' is not empty\n"
417 __PACKAGE__-
>save_rules($param, $cluster_conf, undef);
422 __PACKAGE__-
>register_handlers();
424 package PVE
::API2
::Firewall
::ClusterRules
;
429 use base
qw(PVE::API2::Firewall::RulesBase);
432 my ($class, $param) = @_;
438 my ($class, $param) = @_;
440 my $fw_conf = PVE
::Firewall
::load_clusterfw_conf
();
441 my $rules = $fw_conf->{rules
};
443 return (undef, $fw_conf, $rules);
447 my ($class, $param, $fw_conf, $rules) = @_;
449 $fw_conf->{rules
} = $rules;
450 PVE
::Firewall
::save_clusterfw_conf
($fw_conf);
453 __PACKAGE__-
>register_handlers();
455 package PVE
::API2
::Firewall
::HostRules
;
459 use PVE
::JSONSchema
qw(get_standard_option);
461 use base
qw(PVE::API2::Firewall::RulesBase);
463 __PACKAGE__-
>additional_parameters({ node
=> get_standard_option
('pve-node')});
466 my ($class, $param) = @_;
472 my ($class, $param) = @_;
474 my $cluster_conf = PVE
::Firewall
::load_clusterfw_conf
();
475 my $fw_conf = PVE
::Firewall
::load_hostfw_conf
($cluster_conf);
476 my $rules = $fw_conf->{rules
};
478 return ($cluster_conf, $fw_conf, $rules);
482 my ($class, $param, $fw_conf, $rules) = @_;
484 $fw_conf->{rules
} = $rules;
485 PVE
::Firewall
::save_hostfw_conf
($fw_conf);
488 __PACKAGE__-
>register_handlers();
490 package PVE
::API2
::Firewall
::VMRules
;
494 use PVE
::JSONSchema
qw(get_standard_option);
496 use base
qw(PVE::API2::Firewall::RulesBase);
498 __PACKAGE__-
>additional_parameters({
499 node
=> get_standard_option
('pve-node'),
500 vmid
=> get_standard_option
('pve-vmid'),
504 my ($class, $param) = @_;
510 my ($class, $param) = @_;
512 my $cluster_conf = PVE
::Firewall
::load_clusterfw_conf
();
513 my $fw_conf = PVE
::Firewall
::load_vmfw_conf
($cluster_conf, 'vm', $param->{vmid
});
514 my $rules = $fw_conf->{rules
};
516 return ($cluster_conf, $fw_conf, $rules);
520 my ($class, $param, $fw_conf, $rules) = @_;
522 $fw_conf->{rules
} = $rules;
523 PVE
::Firewall
::save_vmfw_conf
($param->{vmid
}, $fw_conf);
526 __PACKAGE__-
>register_handlers();
528 package PVE
::API2
::Firewall
::CTRules
;
532 use PVE
::JSONSchema
qw(get_standard_option);
534 use base
qw(PVE::API2::Firewall::RulesBase);
536 __PACKAGE__-
>additional_parameters({
537 node
=> get_standard_option
('pve-node'),
538 vmid
=> get_standard_option
('pve-vmid'),
542 my ($class, $param) = @_;
548 my ($class, $param) = @_;
550 my $cluster_conf = PVE
::Firewall
::load_clusterfw_conf
();
551 my $fw_conf = PVE
::Firewall
::load_vmfw_conf
($cluster_conf, 'ct', $param->{vmid
});
552 my $rules = $fw_conf->{rules
};
554 return ($cluster_conf, $fw_conf, $rules);
558 my ($class, $param, $fw_conf, $rules) = @_;
560 $fw_conf->{rules
} = $rules;
561 PVE
::Firewall
::save_vmfw_conf
($param->{vmid
}, $fw_conf);
564 __PACKAGE__-
>register_handlers();