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