]>
Commit | Line | Data |
---|---|---|
39c85db8 DM |
1 | package PVE::API2::Pool; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use PVE::Exception qw(raise_param_exc); | |
6 | use PVE::Cluster qw (cfs_read_file cfs_write_file); | |
7 | use PVE::AccessControl; | |
8 | ||
9 | use PVE::SafeSyslog; | |
10 | ||
11 | use Data::Dumper; # fixme: remove | |
12 | ||
13 | use PVE::RESTHandler; | |
14 | ||
15 | use base qw(PVE::RESTHandler); | |
16 | ||
39c85db8 DM |
17 | __PACKAGE__->register_method ({ |
18 | name => 'index', | |
19 | path => '', | |
20 | method => 'GET', | |
21 | description => "Pool index.", | |
22 | permissions => { | |
23 | user => 'all', | |
24 | }, | |
25 | parameters => { | |
26 | additionalProperties => 0, | |
27 | properties => {}, | |
28 | }, | |
29 | returns => { | |
30 | type => 'array', | |
31 | items => { | |
32 | type => "object", | |
33 | properties => { | |
34 | poolid => { type => 'string' }, | |
35 | }, | |
36 | }, | |
37 | links => [ { rel => 'child', href => "{poolid}" } ], | |
38 | }, | |
39 | code => sub { | |
40 | my ($param) = @_; | |
41 | ||
42 | my $rpcenv = PVE::RPCEnvironment::get(); | |
43 | ||
44 | my $res = []; | |
45 | ||
46 | my $usercfg = $rpcenv->{user_cfg}; | |
47 | ||
cab28ea5 DM |
48 | foreach my $pool (keys %{$usercfg->{pools}}) { |
49 | my $entry = { poolid => $pool }; | |
50 | my $data = $usercfg->{pools}->{$pool}; | |
51 | $entry->{comment} = $data->{comment} if defined($data->{comment}); | |
39c85db8 DM |
52 | push @$res, $entry; |
53 | } | |
54 | ||
55 | return $res; | |
56 | }}); | |
57 | ||
58 | __PACKAGE__->register_method ({ | |
59 | name => 'create_pool', | |
60 | protected => 1, | |
61 | path => '', | |
62 | method => 'POST', | |
63 | permissions => { | |
64 | check => ['perm', '/access', ['Sys.Modify']], | |
65 | }, | |
66 | description => "Create new pool.", | |
67 | parameters => { | |
68 | additionalProperties => 0, | |
69 | properties => { | |
70 | poolid => { type => 'string', format => 'pve-poolid' }, | |
71 | comment => { type => 'string', optional => 1 }, | |
72 | }, | |
73 | }, | |
74 | returns => { type => 'null' }, | |
75 | code => sub { | |
76 | my ($param) = @_; | |
77 | ||
78 | PVE::AccessControl::lock_user_config( | |
79 | sub { | |
80 | ||
81 | my $usercfg = cfs_read_file("user.cfg"); | |
82 | ||
83 | my $pool = $param->{poolid}; | |
84 | ||
85 | die "pool '$pool' already exists\n" | |
86 | if $usercfg->{pools}->{$pool}; | |
87 | ||
88 | $usercfg->{pools}->{$pool} = { vms => {}, storage => {} }; | |
89 | ||
90 | $usercfg->{pools}->{$pool}->{comment} = $param->{comment} if $param->{comment}; | |
91 | ||
92 | cfs_write_file("user.cfg", $usercfg); | |
93 | }, "create pool failed"); | |
94 | ||
95 | return undef; | |
96 | }}); | |
97 | ||
98 | __PACKAGE__->register_method ({ | |
99 | name => 'update_pool', | |
100 | protected => 1, | |
101 | path => '{poolid}', | |
102 | method => 'PUT', | |
103 | permissions => { | |
104 | check => ['perm', '/access', ['Sys.Modify']], | |
105 | }, | |
106 | description => "Update pool data.", | |
107 | parameters => { | |
108 | additionalProperties => 0, | |
109 | properties => { | |
110 | poolid => { type => 'string', format => 'pve-poolid' }, | |
111 | comment => { type => 'string', optional => 1 }, | |
112 | vms => { | |
113 | description => "List of virtual machines.", | |
114 | type => 'string', format => 'pve-vmid-list', | |
115 | optional => 1, | |
116 | }, | |
117 | storage => { | |
118 | description => "List of storage IDs.", | |
119 | type => 'string', format => 'pve-storage-id-list', | |
120 | optional => 1, | |
121 | }, | |
122 | delete => { | |
123 | description => "Remove vms/storage (instead of adding it).", | |
124 | type => 'boolean', | |
125 | optional => 1, | |
126 | }, | |
127 | }, | |
128 | }, | |
129 | returns => { type => 'null' }, | |
130 | code => sub { | |
131 | my ($param) = @_; | |
132 | ||
133 | PVE::AccessControl::lock_user_config( | |
134 | sub { | |
135 | ||
136 | my $usercfg = cfs_read_file("user.cfg"); | |
137 | ||
138 | my $pool = $param->{poolid}; | |
139 | ||
140 | my $data = $usercfg->{pools}->{$pool}; | |
141 | ||
142 | die "pool '$pool' does not exist\n" | |
143 | if !$data; | |
144 | ||
145 | $data->{comment} = $param->{comment} if defined($param->{comment}); | |
146 | ||
147 | if (defined($param->{vms})) { | |
148 | foreach my $vmid (PVE::Tools::split_list($param->{vms})) { | |
149 | if ($param->{delete}) { | |
150 | die "VM $vmid is not a pool member\n" | |
151 | if !$data->{vms}->{$vmid}; | |
152 | delete $data->{vms}->{$vmid}; | |
153 | delete $usercfg->{vms}->{$vmid}; | |
154 | } else { | |
155 | die "VM $vmid is already a pool member\n" | |
156 | if $data->{vms}->{$vmid}; | |
157 | die "VM $vmid belongs to pool '$usercfg->{vms}->{$vmid}'\n" | |
158 | if $usercfg->{vms}->{$vmid}; | |
159 | ||
160 | $data->{vms}->{$vmid} = 1; | |
161 | $usercfg->{vms}->{$vmid} = 1; | |
162 | } | |
163 | } | |
164 | } | |
165 | ||
166 | if (defined($param->{storage})) { | |
167 | foreach my $storeid (PVE::Tools::split_list($param->{storage})) { | |
168 | if ($param->{delete}) { | |
169 | die "Storage '$storeid' is not a pool member\n" | |
170 | if !$data->{storage}->{$storeid}; | |
171 | delete $data->{storage}->{$storeid}; | |
172 | } else { | |
173 | die "Storage '$storeid' is already a pool member\n" | |
174 | if $data->{storage}->{$storeid}; | |
175 | ||
176 | $data->{storage}->{$storeid} = 1; | |
177 | } | |
178 | } | |
179 | } | |
180 | ||
181 | cfs_write_file("user.cfg", $usercfg); | |
182 | }, "update pools failed"); | |
183 | ||
184 | return undef; | |
185 | }}); | |
186 | ||
39c85db8 DM |
187 | __PACKAGE__->register_method ({ |
188 | name => 'read_pool', | |
189 | path => '{poolid}', | |
190 | method => 'GET', | |
191 | permissions => { | |
192 | check => ['perm', '/access', ['Sys.Audit']], | |
193 | }, | |
194 | description => "Get group configuration.", | |
195 | parameters => { | |
196 | additionalProperties => 0, | |
197 | properties => { | |
198 | poolid => {type => 'string', format => 'pve-poolid' }, | |
199 | }, | |
200 | }, | |
399932c6 | 201 | returns => { |
9a53427a DM |
202 | type => "object", |
203 | additionalProperties => 0, | |
204 | properties => { | |
205 | comment => { type => 'string', optional => 1 }, | |
206 | members => { | |
207 | type => 'array', | |
208 | items => { | |
209 | type => "object", | |
210 | additionalProperties => 0, | |
211 | properties => { | |
212 | type => { type => 'string', enum => ['vm', 'storage'] }, | |
213 | id => { type => 'string' }, | |
214 | vmid => { type => 'integer', optional => 1 }, | |
215 | storage => { type => 'string', optional => 1 }, | |
216 | }, | |
217 | }, | |
399932c6 DM |
218 | }, |
219 | }, | |
220 | }, | |
39c85db8 DM |
221 | code => sub { |
222 | my ($param) = @_; | |
223 | ||
224 | my $usercfg = cfs_read_file("user.cfg"); | |
225 | ||
226 | my $pool = $param->{poolid}; | |
227 | ||
228 | my $data = $usercfg->{pools}->{$pool}; | |
229 | ||
230 | die "pool '$pool' does not exist\n" | |
231 | if !$data; | |
232 | ||
9a53427a | 233 | my $members = []; |
399932c6 DM |
234 | |
235 | foreach my $vmid (keys %{$data->{vms}}) { | |
9a53427a | 236 | push @$members, { |
399932c6 DM |
237 | id => "vm/$vmid", |
238 | vmid => $vmid + 0, | |
239 | type => 'vm', | |
240 | }; | |
241 | } | |
242 | ||
243 | foreach my $storage (keys %{$data->{storage}}) { | |
9a53427a | 244 | push @$members, { |
399932c6 DM |
245 | id => "storage/$storage", |
246 | storage => $storage, | |
247 | type => 'storage', | |
248 | }; | |
249 | } | |
250 | ||
9a53427a DM |
251 | my $res = { members => $members }; |
252 | $res->{comment} = $data->{comment} if defined($data->{comment}); | |
253 | ||
399932c6 | 254 | return $res; |
39c85db8 DM |
255 | }}); |
256 | ||
257 | ||
258 | __PACKAGE__->register_method ({ | |
259 | name => 'delete_pool', | |
260 | protected => 1, | |
261 | path => '{poolid}', | |
262 | method => 'DELETE', | |
263 | permissions => { | |
264 | check => ['perm', '/access', ['Sys.Modify']], | |
265 | }, | |
266 | description => "Delete group.", | |
267 | parameters => { | |
268 | additionalProperties => 0, | |
269 | properties => { | |
270 | poolid => { type => 'string', format => 'pve-poolid' }, | |
271 | } | |
272 | }, | |
273 | returns => { type => 'null' }, | |
274 | code => sub { | |
275 | my ($param) = @_; | |
276 | ||
277 | PVE::AccessControl::lock_user_config( | |
278 | sub { | |
279 | ||
280 | my $usercfg = cfs_read_file("user.cfg"); | |
281 | ||
282 | my $pool = $param->{poolid}; | |
283 | ||
284 | my $data = $usercfg->{pools}->{$pool}; | |
285 | ||
286 | die "pool '$pool' does not exist\n" | |
287 | if !$data; | |
288 | ||
289 | delete ($usercfg->{pools}->{$pool}); | |
290 | ||
291 | PVE::AccessControl::delete_pool_acl($pool, $usercfg); | |
292 | ||
293 | cfs_write_file("user.cfg", $usercfg); | |
294 | }, "delete pool failed"); | |
295 | ||
296 | return undef; | |
297 | }}); | |
298 | ||
299 | 1; |