]> git.proxmox.com Git - pve-firewall.git/blame - src/PVE/API2/Firewall/VM.pm
whitespace fixup
[pve-firewall.git] / src / PVE / API2 / Firewall / VM.pm
CommitLineData
b6b8e6ad 1package PVE::API2::Firewall::VMBase;
e7b35711
DM
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
e313afe0 15my $option_properties = $PVE::Firewall::vm_option_properties;
2822f5c4
DM
16
17my $add_option_properties = sub {
18 my ($properties) = @_;
19
20 foreach my $k (keys %$option_properties) {
21 $properties->{$k} = $option_properties->{$k};
22 }
23
24 return $properties;
25};
b6b8e6ad
DM
26
27sub register_handlers {
28 my ($class, $rule_env) = @_;
29
30 $class->register_method({
31 name => 'index',
32 path => '',
33 method => 'GET',
34 permissions => { user => 'all' },
35 description => "Directory index.",
36 parameters => {
37 additionalProperties => 0,
38 properties => {
39 node => get_standard_option('pve-node'),
40 vmid => get_standard_option('pve-vmid'),
41 },
e7b35711 42 },
b6b8e6ad
DM
43 returns => {
44 type => 'array',
45 items => {
46 type => "object",
47 properties => {},
2822f5c4 48 },
b6b8e6ad
DM
49 links => [ { rel => 'child', href => "{name}" } ],
50 },
51 code => sub {
52 my ($param) = @_;
e7b35711 53
b6b8e6ad
DM
54 my $result = [
55 { name => 'rules' },
56 { name => 'aliases' },
947d6ea2
DM
57 { name => 'ipset' },
58 { name => 'refs' },
b6b8e6ad
DM
59 { name => 'options' },
60 ];
e7b35711 61
b6b8e6ad
DM
62 return $result;
63 }});
2822f5c4 64
b6b8e6ad
DM
65
66 $class->register_method({
67 name => 'get_options',
68 path => 'options',
69 method => 'GET',
70 description => "Get VM firewall options.",
71 proxyto => 'node',
16c8f5d7
DM
72 permissions => {
73 check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
74 },
b6b8e6ad
DM
75 parameters => {
76 additionalProperties => 0,
77 properties => {
78 node => get_standard_option('pve-node'),
79 vmid => get_standard_option('pve-vmid'),
2822f5c4
DM
80 },
81 },
b6b8e6ad 82 returns => {
2822f5c4 83 type => "object",
b6b8e6ad
DM
84 #additionalProperties => 1,
85 properties => $option_properties,
86 },
87 code => sub {
88 my ($param) = @_;
89
42ec8178
DM
90 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
91 my $vmfw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, $rule_env, $param->{vmid});
b6b8e6ad
DM
92
93 return PVE::Firewall::copy_opject_with_digest($vmfw_conf->{options});
94 }});
95
96 $class->register_method({
97 name => 'set_options',
98 path => 'options',
99 method => 'PUT',
100 description => "Set Firewall options.",
101 protected => 1,
102 proxyto => 'node',
16c8f5d7
DM
103 permissions => {
104 check => ['perm', '/vms/{vmid}', [ 'VM.Config.Network' ]],
105 },
b6b8e6ad
DM
106 parameters => {
107 additionalProperties => 0,
108 properties => &$add_option_properties({
109 node => get_standard_option('pve-node'),
110 vmid => get_standard_option('pve-vmid'),
111 delete => {
112 type => 'string', format => 'pve-configid-list',
113 description => "A list of settings you want to delete.",
114 optional => 1,
2822f5c4 115 },
b6b8e6ad
DM
116 digest => get_standard_option('pve-config-digest'),
117 }),
118 },
119 returns => { type => "null" },
120 code => sub {
121 my ($param) = @_;
122
42ec8178
DM
123
124 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
125 my $vmfw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, $rule_env, $param->{vmid});
b6b8e6ad
DM
126
127 my (undef, $digest) = PVE::Firewall::copy_opject_with_digest($vmfw_conf->{options});
128 PVE::Tools::assert_if_modified($digest, $param->{digest});
129
130 if ($param->{delete}) {
131 foreach my $opt (PVE::Tools::split_list($param->{delete})) {
132 raise_param_exc({ delete => "no such option '$opt'" })
133 if !$option_properties->{$opt};
134 delete $vmfw_conf->{options}->{$opt};
2822f5c4
DM
135 }
136 }
2822f5c4 137
b6b8e6ad
DM
138 if (defined($param->{enable})) {
139 $param->{enable} = $param->{enable} ? 1 : 0;
140 }
141
142 foreach my $k (keys %$option_properties) {
143 next if !defined($param->{$k});
144 $vmfw_conf->{options}->{$k} = $param->{$k};
145 }
146
147 PVE::Firewall::save_vmfw_conf($param->{vmid}, $vmfw_conf);
148
149 return undef;
150 }});
2822f5c4 151
b6b8e6ad
DM
152 $class->register_method({
153 name => 'log',
154 path => 'log',
155 method => 'GET',
156 description => "Read firewall log",
157 proxyto => 'node',
158 permissions => {
159 check => ['perm', '/vms/{vmid}', [ 'VM.Console' ]],
160 },
161 protected => 1,
162 parameters => {
163 additionalProperties => 0,
164 properties => {
165 node => get_standard_option('pve-node'),
166 vmid => get_standard_option('pve-vmid'),
167 start => {
168 type => 'integer',
169 minimum => 0,
170 optional => 1,
171 },
172 limit => {
173 type => 'integer',
174 minimum => 0,
175 optional => 1,
176 },
177 },
178 },
179 returns => {
180 type => 'array',
181 items => {
182 type => "object",
183 properties => {
184 n => {
185 description=> "Line number",
186 type=> 'integer',
187 },
188 t => {
189 description=> "Line text",
190 type => 'string',
191 }
192 }
193 }
194 },
195 code => sub {
196 my ($param) = @_;
e7b35711 197
b6b8e6ad
DM
198 my $rpcenv = PVE::RPCEnvironment::get();
199 my $user = $rpcenv->get_user();
200 my $vmid = $param->{vmid};
201
202 my ($count, $lines) = PVE::Tools::dump_logfile("/var/log/pve-firewall.log",
203 $param->{start}, $param->{limit},
204 "^$vmid ");
205
206 $rpcenv->set_result_attrib('total', $count);
2822f5c4 207
b6b8e6ad
DM
208 return $lines;
209 }});
947d6ea2
DM
210
211
212 $class->register_method({
213 name => 'refs',
214 path => 'refs',
215 method => 'GET',
216 description => "Lists possible IPSet/Alias reference which are allowed in source/dest properties.",
16c8f5d7
DM
217 permissions => {
218 check => ['perm', '/vms/{vmid}', [ 'VM.Audit' ]],
219 },
947d6ea2
DM
220 parameters => {
221 additionalProperties => 0,
222 properties => {
223 node => get_standard_option('pve-node'),
224 vmid => get_standard_option('pve-vmid'),
f2c0865c
DM
225 type => {
226 description => "Only list references of specified type.",
227 type => 'string',
228 enum => ['alias', 'ipset'],
229 optional => 1,
230 },
947d6ea2
DM
231 },
232 },
233 returns => {
234 type => 'array',
235 items => {
236 type => "object",
237 properties => {
238 type => {
239 type => 'string',
240 enum => ['alias', 'ipset'],
241 },
242 name => {
243 type => 'string',
244 },
245 comment => {
246 type => 'string',
247 optional => 1,
248 },
249 },
250 },
251 },
252 code => sub {
253 my ($param) = @_;
254
255 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
256 my $fw_conf = PVE::Firewall::load_vmfw_conf($cluster_conf, $rule_env, $param->{vmid});
257
258 my $ipsets = {};
259 my $aliases = {};
260
261 foreach my $conf (($cluster_conf, $fw_conf)) {
262 next if !$conf;
f2c0865c
DM
263 if (!$param->{type} || $param->{type} eq 'ipset') {
264 foreach my $name (keys %{$conf->{ipset}}) {
265 my $data = {
266 type => 'ipset',
267 name => $name,
268 ref => "+$name",
269 };
270 if (my $comment = $conf->{ipset_comments}->{$name}) {
271 $data->{comment} = $comment;
272 }
273 $ipsets->{$name} = $data;
947d6ea2 274 }
947d6ea2
DM
275 }
276
f2c0865c
DM
277 if (!$param->{type} || $param->{type} eq 'alias') {
278 foreach my $name (keys %{$conf->{aliases}}) {
279 my $e = $conf->{aliases}->{$name};
280 my $data = {
281 type => 'alias',
282 name => $name,
283 ref => $name,
284 };
285 $data->{comment} = $e->{comment} if $e->{comment};
286 $aliases->{$name} = $data;
287 }
947d6ea2
DM
288 }
289 }
290
291 my $res = [];
292 foreach my $e (values %$ipsets) { push @$res, $e; };
293 foreach my $e (values %$aliases) { push @$res, $e; };
294
295 return $res;
296 }});
b6b8e6ad
DM
297}
298
299package PVE::API2::Firewall::VM;
300
301use strict;
302use warnings;
303
304use base qw(PVE::API2::Firewall::VMBase);
305
306__PACKAGE__->register_method ({
307 subclass => "PVE::API2::Firewall::VMRules",
308 path => 'rules',
309});
310
311__PACKAGE__->register_method ({
312 subclass => "PVE::API2::Firewall::VMAliases",
313 path => 'aliases',
314});
315
1210ae94
DM
316__PACKAGE__->register_method ({
317 subclass => "PVE::API2::Firewall::VMIPSetList",
318 path => 'ipset',
319});
320
b6b8e6ad
DM
321__PACKAGE__->register_handlers('vm');
322
323package PVE::API2::Firewall::CT;
324
325use strict;
326use warnings;
327
328use base qw(PVE::API2::Firewall::VMBase);
329
330__PACKAGE__->register_method ({
331 subclass => "PVE::API2::Firewall::CTRules",
332 path => 'rules',
333});
334
335__PACKAGE__->register_method ({
336 subclass => "PVE::API2::Firewall::CTAliases",
337 path => 'aliases',
338});
339
1210ae94
DM
340__PACKAGE__->register_method ({
341 subclass => "PVE::API2::Firewall::CTIPSetList",
342 path => 'ipset',
343});
344
b6b8e6ad 345__PACKAGE__->register_handlers('vm');
e7b35711
DM
346
3471;