]> git.proxmox.com Git - pve-firewall.git/blob - src/PVE/API2/Firewall/Groups.pm
rename groups.fw to cluster.fw
[pve-firewall.git] / src / PVE / API2 / Firewall / Groups.pm
1 package PVE::API2::Firewall::Groups;
2
3 use strict;
4 use warnings;
5 use PVE::JSONSchema qw(get_standard_option);
6
7 use PVE::Firewall;
8
9
10 use Data::Dumper; # fixme: remove
11
12 use base qw(PVE::RESTHandler);
13
14 __PACKAGE__->register_method({
15 name => 'list',
16 path => '',
17 method => 'GET',
18 description => "List security groups.",
19 proxyto => 'node',
20 parameters => {
21 additionalProperties => 0,
22 properties => {
23 node => get_standard_option('pve-node'),
24 },
25 },
26 returns => {
27 type => 'array',
28 items => {
29 type => "object",
30 properties => {
31 name => {
32 description => "Security group name.",
33 type => 'string',
34 },
35 },
36 },
37 links => [ { rel => 'child', href => "{name}" } ],
38 },
39 code => sub {
40 my ($param) = @_;
41
42 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
43
44 my $res = [];
45 foreach my $group (keys %{$cluster_conf->{rules}}) {
46 push @$res, { name => $group, count => scalar(@{$cluster_conf->{rules}->{$group}}) };
47 }
48
49 return $res;
50 }});
51
52 __PACKAGE__->register_method({
53 name => 'get_rules',
54 path => '{group}',
55 method => 'GET',
56 description => "List security groups rules.",
57 proxyto => 'node',
58 parameters => {
59 additionalProperties => 0,
60 properties => {
61 node => get_standard_option('pve-node'),
62 group => {
63 description => "Security group name.",
64 type => 'string',
65 },
66 },
67 },
68 returns => {
69 type => 'array',
70 items => {
71 type => "object",
72 properties => {
73 pos => {
74 type => 'integer',
75 }
76 },
77 },
78 links => [ { rel => 'child', href => "{pos}" } ],
79 },
80 code => sub {
81 my ($param) = @_;
82
83 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
84
85 my $rules = $cluster_conf->{rules}->{$param->{group}};
86 die "no such security group\n" if !defined($rules);
87
88 my $digest = $cluster_conf->{digest};
89
90 my $res = [];
91
92 my $ind = 0;
93 foreach my $rule (@$rules) {
94 push @$res, PVE::Firewall::cleanup_fw_rule($rule, $digest, $ind++);
95 }
96
97 return $res;
98 }});
99
100 __PACKAGE__->register_method({
101 name => 'get_rule',
102 path => '{group}/{pos}',
103 method => 'GET',
104 description => "Get single rule data.",
105 proxyto => 'node',
106 parameters => {
107 additionalProperties => 0,
108 properties => {
109 node => get_standard_option('pve-node'),
110 group => {
111 description => "Security group name.",
112 type => 'string',
113 },
114 pos => {
115 description => "Return rule from position <pos>.",
116 type => 'integer',
117 minimum => 0,
118 },
119 },
120 },
121 returns => {
122 type => "object",
123 properties => {
124 pos => {
125 type => 'integer',
126 }
127 },
128 },
129 code => sub {
130 my ($param) = @_;
131
132 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
133
134 my $rules = $cluster_conf->{rules}->{$param->{group}};
135 die "no such security group\n" if !defined($rules);
136
137 my $digest = $cluster_conf->{digest};
138 # fixme: check digest
139
140 die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
141
142 my $rule = $rules->[$param->{pos}];
143
144 return PVE::Firewall::cleanup_fw_rule($rule, $digest, $param->{pos});
145 }});
146
147
148 __PACKAGE__->register_method({
149 name => 'create_rule',
150 path => '{group}',
151 method => 'POST',
152 description => "Create new rule.",
153 proxyto => 'node',
154 protected => 1,
155 parameters => {
156 additionalProperties => 0,
157 properties => PVE::Firewall::add_rule_properties({
158 node => get_standard_option('pve-node'),
159 group => {
160 description => "Security group name.",
161 type => 'string',
162 },
163 }),
164 },
165 returns => { type => "null" },
166 code => sub {
167 my ($param) = @_;
168
169 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
170
171 my $rules = $cluster_conf->{rules}->{$param->{group}};
172 die "no such security group\n" if !defined($rules);
173
174 my $digest = $cluster_conf->{digest};
175
176 my $rule = { type => 'out', action => 'ACCEPT', enable => 0};
177
178 PVE::Firewall::copy_rule_data($rule, $param);
179
180 unshift @$rules, $rule;
181
182 PVE::Firewall::save_clusterfw_conf($cluster_conf);
183
184 return undef;
185 }});
186
187 __PACKAGE__->register_method({
188 name => 'update_rule',
189 path => '{group}/{pos}',
190 method => 'PUT',
191 description => "Modify rule data.",
192 proxyto => 'node',
193 protected => 1,
194 parameters => {
195 additionalProperties => 0,
196 properties => PVE::Firewall::add_rule_properties({
197 node => get_standard_option('pve-node'),
198 group => {
199 description => "Security group name.",
200 type => 'string',
201 },
202 moveto => {
203 description => "Move rule to new position <moveto>. Other arguments are ignored.",
204 type => 'integer',
205 minimum => 0,
206 optional => 1,
207 },
208 }),
209 },
210 returns => { type => "null" },
211 code => sub {
212 my ($param) = @_;
213
214 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
215
216 my $rules = $cluster_conf->{rules}->{$param->{group}};
217 die "no such security group\n" if !defined($rules);
218
219 my $digest = $cluster_conf->{digest};
220 # fixme: check digest
221
222 die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
223
224 my $rule = $rules->[$param->{pos}];
225
226 my $moveto = $param->{moveto};
227 if (defined($moveto) && $moveto != $param->{pos}) {
228 my $newrules = [];
229 for (my $i = 0; $i < scalar(@$rules); $i++) {
230 next if $i == $param->{pos};
231 if ($i == $moveto) {
232 push @$newrules, $rule;
233 }
234 push @$newrules, $rules->[$i];
235 }
236 push @$newrules, $rule if $moveto >= scalar(@$rules);
237
238 $cluster_conf->{rules}->{$param->{group}} = $newrules;
239 } else {
240 PVE::Firewall::copy_rule_data($rule, $param);
241 }
242
243 PVE::Firewall::save_clusterfw_conf($cluster_conf);
244
245 return undef;
246 }});
247
248 __PACKAGE__->register_method({
249 name => 'delete_rule',
250 path => '{group}/{pos}',
251 method => 'DELETE',
252 description => "Delete rule.",
253 proxyto => 'node',
254 protected => 1,
255 parameters => {
256 additionalProperties => 0,
257 properties => {
258 node => get_standard_option('pve-node'),
259 group => {
260 description => "Security group name.",
261 type => 'string',
262 },
263 pos => {
264 description => "Delete rule at position <pos>.",
265 type => 'integer',
266 minimum => 0,
267 },
268 },
269 },
270 returns => { type => "null" },
271 code => sub {
272 my ($param) = @_;
273
274 my $cluster_conf = PVE::Firewall::load_clusterfw_conf();
275
276 my $rules = $cluster_conf->{rules}->{$param->{group}};
277 die "no such security group\n" if !defined($rules);
278
279 my $digest = $cluster_conf->{digest};
280 # fixme: check digest
281
282 die "no rule at position $param->{pos}\n" if $param->{pos} >= scalar(@$rules);
283
284 splice(@$rules, $param->{pos}, 1);
285
286 PVE::Firewall::save_clusterfw_conf($cluster_conf);
287
288 return undef;
289 }});
290
291 1;