]> git.proxmox.com Git - pve-manager.git/blob - lib/PVE/API2/Cluster.pm
imported from svn 'pve-manager/pve2'
[pve-manager.git] / lib / PVE / API2 / Cluster.pm
1 package PVE::API2::Cluster;
2
3 use strict;
4 use warnings;
5
6 use PVE::SafeSyslog;
7 use PVE::Tools qw(extract_param);
8 use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
9 use PVE::Storage;
10 use JSON;
11
12 use Data::Dumper; # fixme: remove
13
14 use Apache2::Const qw(:http);
15
16 use PVE::RESTHandler;
17 use PVE::RPCEnvironment;
18
19 use base qw(PVE::RESTHandler);
20
21 my $dc_schema = PVE::Cluster::get_datacenter_schema();
22 my $dc_properties = {
23 delete => {
24 type => 'string', format => 'pve-configid-list',
25 description => "A list of settings you want to delete.",
26 optional => 1,
27 }
28 };
29 foreach my $opt (keys %{$dc_schema->{properties}}) {
30 $dc_properties->{$opt} = $dc_schema->{properties}->{$opt};
31 }
32
33 __PACKAGE__->register_method ({
34 name => 'index',
35 path => '',
36 method => 'GET',
37 description => "Cluster index.",
38 permissions => { user => 'all' },
39 parameters => {
40 additionalProperties => 0,
41 properties => {},
42 },
43 returns => {
44 type => 'array',
45 items => {
46 type => "object",
47 properties => {},
48 },
49 links => [ { rel => 'child', href => "{name}" } ],
50 },
51 code => sub {
52 my ($param) = @_;
53
54 my $result = [
55 { name => 'log' },
56 { name => 'options' },
57 { name => 'resources' },
58 { name => 'tasks' },
59 ];
60
61 return $result;
62 }});
63
64 __PACKAGE__->register_method({
65 name => 'log',
66 path => 'log',
67 method => 'GET',
68 description => "Read cluster log",
69 permissions => { user => 'all' },
70 parameters => {
71 additionalProperties => 0,
72 properties => {
73 max => {
74 type => 'integer',
75 description => "Maximum number of entries.",
76 optional => 1,
77 minimum => 1,
78 }
79 },
80 },
81 returns => {
82 type => 'array',
83 items => {
84 type => "object",
85 properties => {},
86 },
87 },
88 code => sub {
89 my ($param) = @_;
90
91 my $rpcenv = PVE::RPCEnvironment::get();
92
93 my $max = $param->{max} || 0;
94 my $user = $rpcenv->get_user();
95
96 my $admin = $rpcenv->check($user, "/", [ 'Sys.Syslog' ]);
97
98 my $loguser = $admin ? '' : $user;
99
100 my $res = decode_json(PVE::Cluster::get_cluster_log($loguser, $max));
101
102 return $res->{data};
103 }});
104
105 __PACKAGE__->register_method({
106 name => 'resources',
107 path => 'resources',
108 method => 'GET',
109 description => "Resources index (cluster wide).",
110 permissions => { user => 'all' },
111 parameters => {
112 additionalProperties => 0,
113 properties => {},
114 },
115 returns => {
116 type => 'array',
117 items => {
118 type => "object",
119 properties => {
120 },
121 },
122 },
123 code => sub {
124 my ($param) = @_;
125
126 my $rpcenv = PVE::RPCEnvironment::get();
127 my $user = $rpcenv->get_user();
128
129 my $res = [];
130
131 my $nodes = PVE::Cluster::get_nodelist();
132
133 my $rrd = PVE::Cluster::rrd_dump();
134
135 my $vmlist = PVE::Cluster::get_vmlist() || {};
136 my $idlist = $vmlist->{ids} || {};
137
138
139 # we try to generate 'numbers' by using "$X + 0"
140 foreach my $vmid (keys %$idlist) {
141 my $data = $idlist->{$vmid};
142
143 next if !$rpcenv->check($user, "/vms/$vmid", [ 'VM.Audit' ]);
144
145 my $entry = {
146 id => "$data->{type}/$vmid",
147 vmid => $vmid + 0,
148 node => $data->{node},
149 type => $data->{type},
150 };
151
152 if (my $d = $rrd->{"pve2-vm/$vmid"}) {
153
154 $entry->{uptime} = $d->[0] + 0;
155 $entry->{name} = $d->[1];
156
157 $entry->{maxcpu} = $d->[3] + 0;
158 $entry->{cpu} = $d->[4] + 0;
159 $entry->{maxmem} = $d->[5] + 0;
160 $entry->{mem} = $d->[6] + 0;
161 $entry->{maxdisk} = $d->[7] + 0;
162 $entry->{disk} = $d->[8] + 0;
163 }
164
165 push @$res, $entry;
166 }
167
168 foreach my $node (@$nodes) {
169 my $entry = {
170 id => "node/$node",
171 node => $node,
172 type => "node",
173 };
174 if (my $d = $rrd->{"pve2-node/$node"}) {
175
176 $entry->{uptime} = $d->[0] + 0;
177 $entry->{maxcpu} = $d->[3] + 0;
178 $entry->{cpu} = $d->[4] + 0;
179 $entry->{maxmem} = $d->[6] + 0;
180 $entry->{mem} = $d->[7] + 0;
181 $entry->{maxdisk} = $d->[10] + 0;
182 $entry->{disk} = $d->[11] + 0;
183 }
184
185 push @$res, $entry;
186 }
187
188 my $cfg = PVE::Storage::config();
189 my @sids = PVE::Storage::storage_ids ($cfg);
190
191 foreach my $storeid (@sids) {
192 my $scfg = PVE::Storage::storage_config($cfg, $storeid);
193 next if !$rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Audit' ]);
194 # we create a entry for each node
195 foreach my $node (@$nodes) {
196 next if !PVE::Storage::storage_check_enabled($cfg, $storeid, $node, 1);
197 my $entry = {
198 id => "storage/$node/$storeid",
199 storage => $storeid,
200 node => $node,
201 type => 'storage',
202 };
203
204 if (my $d = $rrd->{"pve2-storage/$node/$storeid"}) {
205 $entry->{maxdisk} = $d->[1] + 0;
206 $entry->{disk} = $d->[2] + 0;
207 }
208
209 push @$res, $entry;
210
211 }
212 }
213
214 return $res;
215 }});
216
217 __PACKAGE__->register_method({
218 name => 'tasks',
219 path => 'tasks',
220 method => 'GET',
221 description => "List recent tasks (cluster wide).",
222 permissions => { user => 'all' },
223 parameters => {
224 additionalProperties => 0,
225 properties => {},
226 },
227 returns => {
228 type => 'array',
229 items => {
230 type => "object",
231 properties => {
232 upid => { type => 'string' },
233 },
234 },
235 },
236 code => sub {
237 my ($param) = @_;
238
239 my $rpcenv = PVE::RPCEnvironment::get();
240 my $user = $rpcenv->get_user();
241
242 my $tlist = PVE::Cluster::get_tasklist();
243
244 my $res = [];
245
246 return $res if !$tlist;
247
248 my $all = $rpcenv->check($user, "/", [ 'Sys.Audit' ]);
249
250 foreach my $task (@$tlist) {
251 push @$res, $task if $all || ($task->{user} eq $user);
252 }
253
254 return $res;
255 }});
256
257 __PACKAGE__->register_method({
258 name => 'get_options',
259 path => 'options',
260 method => 'GET',
261 description => "Get datacenter options.",
262 permissions => {
263 path => '/',
264 privs => [ 'Sys.Audit' ],
265 },
266 parameters => {
267 additionalProperties => 0,
268 properties => {},
269 },
270 returns => {
271 type => "object",
272 properties => {},
273 },
274 code => sub {
275 my ($param) = @_;
276 return PVE::Cluster::cfs_read_file('datacenter.cfg');
277 }});
278
279 __PACKAGE__->register_method({
280 name => 'set_options',
281 path => 'options',
282 method => 'PUT',
283 description => "Set datacenter options.",
284 permissions => {
285 path => '/',
286 privs => [ 'Sys.Modify' ],
287 },
288 protected => 1,
289 parameters => {
290 additionalProperties => 0,
291 properties => $dc_properties,
292 },
293 returns => { type => "null" },
294 code => sub {
295 my ($param) = @_;
296
297 my $filename = 'datacenter.cfg';
298
299 my $delete = extract_param($param, 'delete');
300
301 my $code = sub {
302
303 my $conf = cfs_read_file($filename);
304
305 foreach my $opt (keys %$param) {
306 $conf->{$opt} = $param->{$opt};
307 }
308
309 foreach my $opt (PVE::Tools::split_list($delete)) {
310 delete $conf->{$opt};
311 };
312
313 cfs_write_file($filename, $conf);
314 };
315
316 cfs_lock_file($filename, undef, $code);
317 die $@ if $@;
318
319 return undef;
320 }});
321
322 1;