]> git.proxmox.com Git - pve-firewall.git/blame - src/PVE/API2/Firewall/VM.pm
improve error handling
[pve-firewall.git] / src / PVE / API2 / Firewall / VM.pm
CommitLineData
e7b35711
DM
1package PVE::API2::Firewall::VM;
2
3use strict;
4use warnings;
5use PVE::JSONSchema qw(get_standard_option);
6use PVE::Cluster;
7use PVE::Firewall;
464f933e 8use PVE::API2::Firewall::Rules;
e76a9f53 9use PVE::API2::Firewall::Aliases;
e7b35711
DM
10
11use Data::Dumper; # fixme: remove
12
13use base qw(PVE::RESTHandler);
14
464f933e
DM
15__PACKAGE__->register_method ({
16 subclass => "PVE::API2::Firewall::VMRules",
17 path => 'rules',
18});
19
e76a9f53
DM
20__PACKAGE__->register_method ({
21 subclass => "PVE::API2::Firewall::VMAliases",
22 path => 'aliases',
23});
24
e7b35711
DM
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
2822f5c4
DM
57my $option_properties = {
58 enable => {
59 description => "Enable host firewall rules.",
60 type => 'boolean',
61 optional => 1,
62 },
44269d27
DM
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 },
2822f5c4
DM
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 },
44269d27
DM
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
2822f5c4
DM
90};
91
92my $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};
e7b35711
DM
101__PACKAGE__->register_method({
102 name => 'get_options',
103 path => 'options',
104 method => 'GET',
2822f5c4 105 description => "Get VM firewall options.",
e7b35711
DM
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",
2822f5c4
DM
116 #additionalProperties => 1,
117 properties => $option_properties,
e7b35711
DM
118 },
119 code => sub {
120 my ($param) = @_;
121
2822f5c4 122 my $vmfw_conf = PVE::Firewall::load_vmfw_conf($param->{vmid});
e7b35711 123
2822f5c4
DM
124 return PVE::Firewall::copy_opject_with_digest($vmfw_conf->{options});
125 }});
e7b35711 126
2822f5c4
DM
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) = @_;
e7b35711 150
2822f5c4 151 my $vmfw_conf = PVE::Firewall::load_vmfw_conf($param->{vmid});
e7b35711 152
2822f5c4
DM
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 ");
e7b35711 231
2822f5c4
DM
232 $rpcenv->set_result_attrib('total', $count);
233
234 return $lines;
e7b35711
DM
235 }});
236
2371;