]> git.proxmox.com Git - pve-firewall.git/blob - src/PVE/API2/Firewall/Cluster.pm
e8b44d2f6568b06a9764d4c9b93021790f1d4d8b
[pve-firewall.git] / src / PVE / API2 / Firewall / Cluster.pm
1 package PVE::API2::Firewall::Cluster;
2
3 use strict;
4 use warnings;
5 use PVE::Exception qw(raise raise_param_exc raise_perm_exc);
6 use PVE::JSONSchema qw(get_standard_option);
7
8 use PVE::Firewall;
9 use PVE::API2::Firewall::Aliases;
10 use PVE::API2::Firewall::Rules;
11 use PVE::API2::Firewall::Groups;
12 use PVE::API2::Firewall::IPSet;
13
14 #fixme: locking?
15
16 use Data::Dumper; # fixme: remove
17
18 use base qw(PVE::RESTHandler);
19
20 __PACKAGE__->register_method ({
21 subclass => "PVE::API2::Firewall::Groups",
22 path => 'groups',
23 });
24
25 __PACKAGE__->register_method ({
26 subclass => "PVE::API2::Firewall::ClusterRules",
27 path => 'rules',
28 });
29
30 __PACKAGE__->register_method ({
31 subclass => "PVE::API2::Firewall::ClusterIPSetList",
32 path => 'ipset',
33 });
34
35 __PACKAGE__->register_method ({
36 subclass => "PVE::API2::Firewall::ClusterAliases",
37 path => 'aliases',
38 });
39
40
41 __PACKAGE__->register_method({
42 name => 'index',
43 path => '',
44 method => 'GET',
45 permissions => { user => 'all' },
46 description => "Directory index.",
47 parameters => {
48 additionalProperties => 0,
49 },
50 returns => {
51 type => 'array',
52 items => {
53 type => "object",
54 properties => {},
55 },
56 links => [ { rel => 'child', href => "{name}" } ],
57 },
58 code => sub {
59 my ($param) = @_;
60
61 my $result = [
62 { name => 'aliases' },
63 { name => 'rules' },
64 { name => 'options' },
65 { name => 'groups' },
66 { name => 'ipset' },
67 { name => 'macros' },
68 { name => 'refs' },
69 ];
70
71 return $result;
72 }});
73
74 my $option_properties = {
75 enable => {
76 type => 'boolean',
77 optional => 1,
78 },
79 policy_in => {
80 description => "Input policy.",
81 type => 'string',
82 optional => 1,
83 enum => ['ACCEPT', 'REJECT', 'DROP'],
84 },
85 policy_out => {
86 description => "Output policy.",
87 type => 'string',
88 optional => 1,
89 enum => ['ACCEPT', 'REJECT', 'DROP'],
90 },
91 };
92
93 my $add_option_properties = sub {
94 my ($properties) = @_;
95
96 foreach my $k (keys %$option_properties) {
97 $properties->{$k} = $option_properties->{$k};
98 }
99
100 return $properties;
101 };
102
103
104 __PACKAGE__->register_method({
105 name => 'get_options',
106 path => 'options',
107 method => 'GET',
108 description => "Get Firewall options.",
109 parameters => {
110 additionalProperties => 0,
111 },
112 returns => {
113 type => "object",
114 #additionalProperties => 1,
115 properties => $option_properties,
116 },
117 code => sub {
118 my ($param) = @_;
119
120 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
121
122 return PVE::Firewall::copy_opject_with_digest($cluster_conf->{options});
123 }});
124
125
126 __PACKAGE__->register_method({
127 name => 'set_options',
128 path => 'options',
129 method => 'PUT',
130 description => "Set Firewall options.",
131 protected => 1,
132 parameters => {
133 additionalProperties => 0,
134 properties => &$add_option_properties({
135 delete => {
136 type => 'string', format => 'pve-configid-list',
137 description => "A list of settings you want to delete.",
138 optional => 1,
139 },
140 digest => get_standard_option('pve-config-digest'),
141 }),
142 },
143 returns => { type => "null" },
144 code => sub {
145 my ($param) = @_;
146
147 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
148
149 my (undef, $digest) = PVE::Firewall::copy_opject_with_digest($cluster_conf->{options});
150 PVE::Tools::assert_if_modified($digest, $param->{digest});
151
152 if ($param->{delete}) {
153 foreach my $opt (PVE::Tools::split_list($param->{delete})) {
154 raise_param_exc({ delete => "no such option '$opt'" })
155 if !$option_properties->{$opt};
156 delete $cluster_conf->{options}->{$opt};
157 }
158 }
159
160 if (defined($param->{enable})) {
161 $param->{enable} = $param->{enable} ? 1 : 0;
162 }
163
164 foreach my $k (keys %$option_properties) {
165 next if !defined($param->{$k});
166 $cluster_conf->{options}->{$k} = $param->{$k};
167 }
168
169 PVE::Firewall::save_clusterfw_conf($cluster_conf);
170
171 return undef;
172 }});
173
174 __PACKAGE__->register_method({
175 name => 'get_macros',
176 path => 'macros',
177 method => 'GET',
178 description => "List available macros",
179 parameters => {
180 additionalProperties => 0,
181 },
182 returns => {
183 type => 'array',
184 items => {
185 type => "object",
186 properties => {
187 macro => {
188 description => "Macro name.",
189 type => 'string',
190 },
191 descr => {
192 description => "More verbose description (if available).",
193 type => 'string',
194 }
195 },
196 },
197 },
198 code => sub {
199 my ($param) = @_;
200
201 my $res = [];
202
203 my ($macros, $descr) = PVE::Firewall::get_macros();
204
205 foreach my $macro (keys %$macros) {
206 push @$res, { macro => $macro, descr => $descr->{$macro} || $macro };
207 }
208
209 return $res;
210 }});
211
212 __PACKAGE__->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.",
217 parameters => {
218 additionalProperties => 0,
219 properties => {
220 type => {
221 description => "Only list references of specified type.",
222 type => 'string',
223 enum => ['alias', 'ipset'],
224 optional => 1,
225 },
226 },
227 },
228 returns => {
229 type => 'array',
230 items => {
231 type => "object",
232 properties => {
233 type => {
234 type => 'string',
235 enum => ['alias', 'ipset'],
236 },
237 name => {
238 type => 'string',
239 },
240 ref => {
241 type => 'string',
242 },
243 comment => {
244 type => 'string',
245 optional => 1,
246 },
247 },
248 },
249 },
250 code => sub {
251 my ($param) = @_;
252
253 my $conf = PVE::Firewall::load_clusterfw_conf();
254
255 my $res = [];
256
257 if (!$param->{type} || $param->{type} eq 'ipset') {
258 foreach my $name (keys %{$conf->{ipset}}) {
259 my $data = {
260 type => 'ipset',
261 name => $name,
262 ref => "+$name",
263 };
264 if (my $comment = $conf->{ipset_comments}->{$name}) {
265 $data->{comment} = $comment;
266 }
267 push @$res, $data;
268 }
269 }
270
271 if (!$param->{type} || $param->{type} eq 'alias') {
272 foreach my $name (keys %{$conf->{aliases}}) {
273 my $e = $conf->{aliases}->{$name};
274 my $data = {
275 type => 'alias',
276 name => $name,
277 ref => $name,
278 };
279 $data->{comment} = $e->{comment} if $e->{comment};
280 push @$res, $data;
281 }
282 }
283
284 return $res;
285 }});
286
287 1;