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