code cleanup
[pve-access-control.git] / PVE / API2 / Pool.pm
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
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
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});
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
187 # fixme: return format!
188 __PACKAGE__->register_method ({
189     name => 'read_pool', 
190     path => '{poolid}', 
191     method => 'GET',
192     permissions => { 
193         check => ['perm', '/access', ['Sys.Audit']],
194     },
195     description => "Get group configuration.",
196     parameters => {
197         additionalProperties => 0,
198         properties => {
199             poolid => {type => 'string', format => 'pve-poolid' },
200         },
201     },
202     returns => {
203         type => 'array',
204         items => {
205             type => "object",
206             additionalProperties => 0,
207             properties => {
208                 type => { type => 'string', enum => ['vm', 'storage'] },
209                 id => { type => 'string' },
210                 vmid => { type => 'integer', optional => 1 },
211                 storage => { type => 'string', optional => 1 },
212             },
213         },
214     },
215     code => sub {
216         my ($param) = @_;
217
218         my $usercfg = cfs_read_file("user.cfg");
219
220         my $pool = $param->{poolid};
221         
222         my $data = $usercfg->{pools}->{$pool};
223
224         die "pool '$pool' does not exist\n" 
225             if !$data;
226  
227         my $res = [];
228
229         foreach my $vmid (keys %{$data->{vms}}) {
230             push @$res, {
231                 id => "vm/$vmid",
232                 vmid => $vmid + 0, 
233                 type => 'vm',
234             };
235         }
236
237         foreach my $storage (keys %{$data->{storage}}) {
238             push @$res, {
239                 id => "storage/$storage",
240                 storage => $storage, 
241                 type => 'storage',
242             };
243         }
244
245         return $res;
246     }});
247
248
249 __PACKAGE__->register_method ({
250     name => 'delete_pool', 
251     protected => 1,
252     path => '{poolid}', 
253     method => 'DELETE',
254     permissions => { 
255         check => ['perm', '/access', ['Sys.Modify']],
256     },
257     description => "Delete group.",
258     parameters => {
259         additionalProperties => 0,
260         properties => {
261             poolid => { type => 'string', format => 'pve-poolid' },
262         }
263     },
264     returns => { type => 'null' },
265     code => sub {
266         my ($param) = @_;
267
268         PVE::AccessControl::lock_user_config(
269             sub {
270
271                 my $usercfg = cfs_read_file("user.cfg");
272
273                 my $pool = $param->{poolid};
274         
275                 my $data = $usercfg->{pools}->{$pool};
276                 
277                 die "pool '$pool' does not exist\n" 
278                     if !$data;
279         
280                 delete ($usercfg->{pools}->{$pool});
281
282                 PVE::AccessControl::delete_pool_acl($pool, $usercfg);
283
284                 cfs_write_file("user.cfg", $usercfg);
285             }, "delete pool failed");
286         
287         return undef;
288     }});
289
290 1;