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