always pass cluster_conf to load_vmfw_conf
[pve-firewall.git] / src / PVE / API2 / Firewall / VM.pm
1 package PVE::API2::Firewall::VMBase;
2
3 use strict;
4 use warnings;
5 use PVE::JSONSchema qw(get_standard_option);
6 use PVE::Cluster;
7 use PVE::Firewall;
8 use PVE::API2::Firewall::Rules;
9 use PVE::API2::Firewall::Aliases;
10
11 use Data::Dumper; # fixme: remove
12
13 use base qw(PVE::RESTHandler);
14
15 my $option_properties = {
16     enable => {
17         description => "Enable host firewall rules.",
18         type => 'boolean',
19         optional => 1,
20     },
21     macfilter => {
22         description => "Enable/disable MAC address filter.",
23         type => 'boolean',
24         optional => 1,
25     },
26     dhcp => {
27         description => "Enable DHCP.",
28         type => 'boolean',
29         optional => 1,
30     },
31     policy_in => {
32         description => "Input policy.",
33         type => 'string',
34         optional => 1,
35         enum => ['ACCEPT', 'REJECT', 'DROP'],
36     },
37     policy_out => { 
38         description => "Output policy.",
39         type => 'string',
40         optional => 1,
41         enum => ['ACCEPT', 'REJECT', 'DROP'],
42     },
43     log_level_in =>  get_standard_option('pve-fw-loglevel', {
44         description => "Log level for incoming traffic." }),
45     log_level_out =>  get_standard_option('pve-fw-loglevel', {
46         description => "Log level for outgoing traffic." }),
47
48 };
49
50 my $add_option_properties = sub {
51     my ($properties) = @_;
52
53     foreach my $k (keys %$option_properties) {
54         $properties->{$k} = $option_properties->{$k};
55     }
56     
57     return $properties;
58 };
59
60 sub register_handlers {
61     my ($class, $rule_env) = @_;
62
63     $class->register_method({
64         name => 'index',
65         path => '',
66         method => 'GET',
67         permissions => { user => 'all' },
68         description => "Directory index.",
69         parameters => {
70             additionalProperties => 0,
71             properties => {
72                 node => get_standard_option('pve-node'),
73                 vmid => get_standard_option('pve-vmid'),
74             },
75         },
76         returns => {
77             type => 'array',
78             items => {
79                 type => "object",
80                 properties => {},
81             },
82             links => [ { rel => 'child', href => "{name}" } ],
83         },
84         code => sub {
85             my ($param) = @_;
86
87             my $result = [
88                 { name => 'rules' },
89                 { name => 'aliases' },
90                 { name => 'options' },
91                 ];
92
93             return $result;
94         }});
95
96
97     $class->register_method({
98         name => 'get_options',
99         path => 'options',
100         method => 'GET',
101         description => "Get VM firewall options.",
102         proxyto => 'node',
103         parameters => {
104             additionalProperties => 0,
105             properties => {
106                 node => get_standard_option('pve-node'),
107                 vmid => get_standard_option('pve-vmid'),
108             },
109         },
110         returns => {
111             type => "object",
112             #additionalProperties => 1,
113             properties => $option_properties,
114         },
115         code => sub {
116             my ($param) = @_;
117
118             my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
119             my $vmfw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, $rule_env, $param->{vmid});
120
121             return PVE::Firewall::copy_opject_with_digest($vmfw_conf->{options});
122         }});
123
124     $class->register_method({
125         name => 'set_options',
126         path => 'options',
127         method => 'PUT',
128         description => "Set Firewall options.",
129         protected => 1,
130         proxyto => 'node',
131         parameters => {
132             additionalProperties => 0,
133             properties => &$add_option_properties({
134                 node => get_standard_option('pve-node'),
135                 vmid => get_standard_option('pve-vmid'),
136                 delete => {
137                     type => 'string', format => 'pve-configid-list',
138                     description => "A list of settings you want to delete.",
139                     optional => 1,
140                 },
141                 digest => get_standard_option('pve-config-digest'),
142             }),
143         },
144         returns => { type => "null" },
145         code => sub {
146             my ($param) = @_;
147
148
149             my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
150             my $vmfw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, $rule_env, $param->{vmid});
151
152             my (undef, $digest) = PVE::Firewall::copy_opject_with_digest($vmfw_conf->{options});
153             PVE::Tools::assert_if_modified($digest, $param->{digest});
154
155             if ($param->{delete}) {
156                 foreach my $opt (PVE::Tools::split_list($param->{delete})) {
157                     raise_param_exc({ delete => "no such option '$opt'" }) 
158                         if !$option_properties->{$opt};
159                     delete $vmfw_conf->{options}->{$opt};
160                 }
161             }
162
163             if (defined($param->{enable})) {
164                 $param->{enable} = $param->{enable} ? 1 : 0;
165             }
166
167             foreach my $k (keys %$option_properties) {
168                 next if !defined($param->{$k});
169                 $vmfw_conf->{options}->{$k} = $param->{$k}; 
170             }
171
172             PVE::Firewall::save_vmfw_conf($param->{vmid}, $vmfw_conf);
173             
174             return undef;
175         }});
176
177     $class->register_method({
178         name => 'log', 
179         path => 'log', 
180         method => 'GET',
181         description => "Read firewall log",
182         proxyto => 'node',
183         permissions => {
184             check => ['perm', '/vms/{vmid}', [ 'VM.Console' ]],
185         },
186         protected => 1,
187         parameters => {
188             additionalProperties => 0,
189             properties => {
190                 node => get_standard_option('pve-node'),
191                 vmid => get_standard_option('pve-vmid'),
192                 start => {
193                     type => 'integer',
194                     minimum => 0,
195                     optional => 1,
196                 },
197                 limit => {
198                     type => 'integer',
199                     minimum => 0,
200                     optional => 1,
201                 },
202             },
203         },
204         returns => {
205             type => 'array',
206             items => { 
207                 type => "object",
208                 properties => {
209                     n => {
210                         description=>  "Line number",
211                         type=> 'integer',
212                     },
213                     t => {
214                         description=>  "Line text",
215                         type => 'string',
216                     }
217                 }
218             }
219         },
220         code => sub {
221             my ($param) = @_;
222
223             my $rpcenv = PVE::RPCEnvironment::get();
224             my $user = $rpcenv->get_user();
225             my $vmid = $param->{vmid};
226
227             my ($count, $lines) = PVE::Tools::dump_logfile("/var/log/pve-firewall.log", 
228                                                            $param->{start}, $param->{limit},
229                                                            "^$vmid ");
230             
231             $rpcenv->set_result_attrib('total', $count);
232             
233             return $lines; 
234         }});
235 }
236
237 package PVE::API2::Firewall::VM;
238
239 use strict;
240 use warnings;
241
242 use base qw(PVE::API2::Firewall::VMBase);
243
244 __PACKAGE__->register_method ({
245     subclass => "PVE::API2::Firewall::VMRules",  
246     path => 'rules',
247 });
248
249 __PACKAGE__->register_method ({
250     subclass => "PVE::API2::Firewall::VMAliases",  
251     path => 'aliases',
252 });
253
254 __PACKAGE__->register_method ({
255     subclass => "PVE::API2::Firewall::VMIPSetList",  
256     path => 'ipset',
257 });
258
259 __PACKAGE__->register_handlers('vm');
260
261 package PVE::API2::Firewall::CT;
262
263 use strict;
264 use warnings;
265
266 use base qw(PVE::API2::Firewall::VMBase);
267
268 __PACKAGE__->register_method ({
269     subclass => "PVE::API2::Firewall::CTRules",  
270     path => 'rules',
271 });
272
273 __PACKAGE__->register_method ({
274     subclass => "PVE::API2::Firewall::CTAliases",  
275     path => 'aliases',
276 });
277
278 __PACKAGE__->register_method ({
279     subclass => "PVE::API2::Firewall::CTIPSetList",  
280     path => 'ipset',
281 });
282
283 __PACKAGE__->register_handlers('vm');
284
285 1;