]> git.proxmox.com Git - pve-firewall.git/blame - src/PVE/API2/Firewall/IPSet.pm
ipset API: add get/update methods
[pve-firewall.git] / src / PVE / API2 / Firewall / IPSet.pm
CommitLineData
009ee3ac
DM
1package PVE::API2::Firewall::IPSetBase;
2
3use strict;
4use warnings;
4a11bba5 5use PVE::Exception qw(raise raise_param_exc);
009ee3ac
DM
6use PVE::JSONSchema qw(get_standard_option);
7
8use PVE::Firewall;
9
10use base qw(PVE::RESTHandler);
11
12my $api_properties = {
13 cidr => {
14 description => "Network/IP specification in CIDR format.",
15 type => 'string', format => 'IPv4orCIDR',
16 },
17 name => {
18 description => "IP set name.",
19 type => 'string',
20 },
21 comment => {
22 type => 'string',
23 optional => 1,
24 },
25 nomatch => {
26 type => 'boolean',
27 optional => 1,
28 },
29};
30
31sub load_config {
32 my ($class, $param) = @_;
33
34 die "implement this in subclass";
35
36 #return ($fw_conf, $rules);
37}
38
39sub save_rules {
40 my ($class, $param, $fw_conf, $rules) = @_;
41
42 die "implement this in subclass";
43}
44
45my $additional_param_hash = {};
46
47sub additional_parameters {
48 my ($class, $new_value) = @_;
49
50 if (defined($new_value)) {
51 $additional_param_hash->{$class} = $new_value;
52 }
53
54 # return a copy
55 my $copy = {};
56 my $org = $additional_param_hash->{$class} || {};
57 foreach my $p (keys %$org) { $copy->{$p} = $org->{$p}; }
58 return $copy;
59}
60
61sub register_get_ipset {
62 my ($class) = @_;
63
64 my $properties = $class->additional_parameters();
65
66 $properties->{name} = $api_properties->{name};
67
68 $class->register_method({
69 name => 'get_ipset',
70 path => '',
71 method => 'GET',
72 description => "List IPSet content",
73 parameters => {
74 additionalProperties => 0,
75 properties => $properties,
76 },
77 returns => {
78 type => 'array',
79 items => {
80 type => "object",
81 properties => {
82 cidr => {
83 type => 'string',
84 },
85 comment => {
86 type => 'string',
87 optional => 1,
88 },
89 nomatch => {
90 type => 'boolean',
91 optional => 1,
92 },
93 },
94 },
95 links => [ { rel => 'child', href => "{cidr}" } ],
96 },
97 code => sub {
98 my ($param) = @_;
99
100 my ($fw_conf, $ipset) = $class->load_config($param);
101
102 return $ipset;
103 }});
104}
105
a33c74f6 106sub register_create_ip {
009ee3ac
DM
107 my ($class) = @_;
108
109 my $properties = $class->additional_parameters();
110
111 $properties->{name} = $api_properties->{name};
112 $properties->{cidr} = $api_properties->{cidr};
113 $properties->{nomatch} = $api_properties->{nomatch};
114 $properties->{comment} = $api_properties->{comment};
115
116 $class->register_method({
a33c74f6 117 name => 'create_ip',
009ee3ac
DM
118 path => '',
119 method => 'POST',
120 description => "Add IP or Network to IPSet.",
121 protected => 1,
122 parameters => {
123 additionalProperties => 0,
124 properties => $properties,
125 },
126 returns => { type => "null" },
127 code => sub {
128 my ($param) = @_;
129
130 my ($fw_conf, $ipset) = $class->load_config($param);
131
4a11bba5
DM
132 my $cidr = $param->{cidr};
133
134 foreach my $entry (@$ipset) {
135 raise_param_exc({ cidr => "address '$cidr' already exists" })
136 if $entry->{cidr} eq $cidr;
137 }
138
139 my $data = { cidr => $cidr };
009ee3ac
DM
140 $data->{nomatch} = 1 if $param->{nomatch};
141 $data->{comment} = $param->{comment} if $param->{comment};
142
009ee3ac
DM
143 unshift @$ipset, $data;
144
145 $class->save_ipset($param, $fw_conf, $ipset);
146
147 return undef;
148 }});
149}
150
a33c74f6
DM
151sub register_read_ip {
152 my ($class) = @_;
153
154 my $properties = $class->additional_parameters();
155
156 $properties->{name} = $api_properties->{name};
157 $properties->{cidr} = $api_properties->{cidr};
158
159 $class->register_method({
160 name => 'read_ip',
161 path => '{cidr}',
162 method => 'GET',
163 description => "Read IP or Network settings from IPSet.",
164 protected => 1,
165 parameters => {
166 additionalProperties => 0,
167 properties => $properties,
168 },
169 returns => { type => "object" },
170 code => sub {
171 my ($param) = @_;
172
173 my ($fw_conf, $ipset) = $class->load_config($param);
174
175 foreach my $entry (@$ipset) {
176 return $entry if $entry->{cidr} eq $param->{cidr};
177 }
178
179 raise_param_exc({ cidr => "no such IP/Network" });
180 }});
181}
182
183sub register_update_ip {
184 my ($class) = @_;
185
186 my $properties = $class->additional_parameters();
187
188 $properties->{name} = $api_properties->{name};
189 $properties->{cidr} = $api_properties->{cidr};
190 $properties->{nomatch} = $api_properties->{nomatch};
191 $properties->{comment} = $api_properties->{comment};
192
193 $class->register_method({
194 name => 'update_ip',
195 path => '{cidr}',
196 method => 'PUT',
197 description => "Update IP or Network settings",
198 protected => 1,
199 parameters => {
200 additionalProperties => 0,
201 properties => $properties,
202 },
203 returns => { type => "null" },
204 code => sub {
205 my ($param) = @_;
206
207 my ($fw_conf, $ipset) = $class->load_config($param);
208
209 foreach my $entry (@$ipset) {
210 if($entry->{cidr} eq $param->{cidr}) {
211 $entry->{nomatch} = $param->{nomatch};
212 $entry->{comment} = $param->{comment};
213 $class->save_ipset($param, $fw_conf, $ipset);
214 return;
215 }
216 }
217
218 raise_param_exc({ cidr => "no such IP/Network" });
219 }});
220}
221
222sub register_delete_ip {
009ee3ac
DM
223 my ($class) = @_;
224
225 my $properties = $class->additional_parameters();
226
227 $properties->{name} = $api_properties->{name};
228 $properties->{cidr} = $api_properties->{cidr};
229
230 $class->register_method({
231 name => 'remove_ip',
232 path => '{cidr}',
233 method => 'DELETE',
234 description => "Remove IP or Network from IPSet.",
235 protected => 1,
236 parameters => {
237 additionalProperties => 0,
238 properties => $properties,
239 },
240 returns => { type => "null" },
241 code => sub {
242 my ($param) = @_;
243
244 my ($fw_conf, $ipset) = $class->load_config($param);
245
4a11bba5
DM
246 my $new = [];
247
248 foreach my $entry (@$ipset) {
249 push @$new, $entry if $entry->{cidr} ne $param->{cidr};
250 }
009ee3ac 251
4a11bba5
DM
252 $class->save_ipset($param, $fw_conf, $new);
253
009ee3ac
DM
254 return undef;
255 }});
256}
257
258sub register_handlers {
259 my ($class) = @_;
260
261 $class->register_get_ipset();
a33c74f6
DM
262 $class->register_create_ip();
263 $class->register_read_ip();
264 $class->register_update_ip();
265 $class->register_delete_ip();
009ee3ac
DM
266}
267
268package PVE::API2::Firewall::ClusterIPset;
269
270use strict;
271use warnings;
272
273use base qw(PVE::API2::Firewall::IPSetBase);
274
275sub load_config {
276 my ($class, $param) = @_;
277
278 my $fw_conf = PVE::Firewall::load_clusterfw_conf();
279 my $ipset = $fw_conf->{ipset}->{$param->{name}};
280 die "no such IPSet '$param->{name}'\n" if !defined($ipset);
281
282 return ($fw_conf, $ipset);
283}
284
285sub save_ipset {
286 my ($class, $param, $fw_conf, $ipset) = @_;
287
288 $fw_conf->{ipset}->{$param->{name}} = $ipset;
289 PVE::Firewall::save_clusterfw_conf($fw_conf);
290}
291
292__PACKAGE__->register_handlers();
293
2941;