use HTTP::Status qw(:constants);
use Storable qw(dclone);
use PVE::JSONSchema qw(get_standard_option);
-
-use Data::Dumper; # fixme: remove
+use PVE::RPCEnvironment;
use PVE::RESTHandler;
path => '',
method => 'GET',
description => "Storage index.",
+ permissions => {
+ description => "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/<storage>'",
+ user => 'all',
+ },
parameters => {
additionalProperties => 0,
properties => {
code => sub {
my ($param) = @_;
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $authuser = $rpcenv->get_user();
+
my $cfg = cfs_read_file("storage.cfg");
- my @sids = PVE::Storage::storage_ids($cfg);
+ my @sids = PVE::Storage::storage_ids($cfg);
my $res = [];
foreach my $storeid (@sids) {
+ my $privs = [ 'Datastore.Audit', 'Datastore.AllocateSpace' ];
+ next if !$rpcenv->check_any($authuser, "/storage/$storeid", $privs, 1);
+
my $scfg = &$api_storage_config($cfg, $storeid);
next if $param->{type} && $param->{type} ne $scfg->{type};
push @$res, $scfg;
path => '{storage}',
method => 'GET',
description => "Read storage configuration.",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
path => '',
method => 'POST',
description => "Create a new storage.",
+ permissions => {
+ check => ['perm', '/storage', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
path => '{storage}',
method => 'PUT',
description => "Update storage configuration.",
+ permissions => {
+ check => ['perm', '/storage', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
path => '{storage}', # /storage/config/{storage}
method => 'DELETE',
description => "Delete storage configuration.",
+ permissions => {
+ check => ['perm', '/storage', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
path => '',
method => 'GET',
description => "List storage content.",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+ },
protected => 1,
proxyto => 'node',
parameters => {
path => '',
method => 'POST',
description => "Allocate disk images.",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']],
+ },
protected => 1,
proxyto => 'node',
parameters => {
path => '{volume}',
method => 'GET',
description => "Get volume attributes",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+ },
protected => 1,
proxyto => 'node',
parameters => {
path => '{volume}',
method => 'DELETE',
description => "Delete volume",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']],
+ },
protected => 1,
proxyto => 'node',
parameters => {
name => 'copy',
path => '{volume}',
method => 'POST',
- description => "Copy a volume.",
+ description => "Copy a volume. This is experimental code - do not use.",
protected => 1,
proxyto => 'node',
parameters => {
path => '',
method => 'GET',
description => "Index of available scan methods",
+ permissions => {
+ user => 'all',
+ },
parameters => {
additionalProperties => 0,
properties => {
description => "Scan remote NFS server.",
protected => 1,
proxyto => "node",
+ permissions => {
+ check => ['perm', '/storage', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
description => "Scan remote iSCSI server.",
protected => 1,
proxyto => "node",
+ permissions => {
+ check => ['perm', '/storage', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
description => "List local LVM volume groups.",
protected => 1,
proxyto => "node",
+ permissions => {
+ check => ['perm', '/storage', ['Datastore.Allocate']],
+ },
parameters => {
additionalProperties => 0,
properties => {
description => "List local USB devices.",
protected => 1,
proxyto => "node",
+ permissions => {
+ check => ['perm', '/', ['Sys.Modify']],
+ },
parameters => {
additionalProperties => 0,
properties => {
path => '',
method => 'GET',
description => "Get status for all datastores.",
+ permissions => {
+ description => "Only list entries where you have 'Datastore.Audit' or 'Datastore.AllocateSpace' permissions on '/storage/<storage>'",
+ user => 'all',
+ },
protected => 1,
proxyto => 'node',
parameters => {
code => sub {
my ($param) = @_;
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $authuser = $rpcenv->get_user();
+
my $cfg = cfs_read_file("storage.cfg");
my $info = PVE::Storage::storage_info($cfg, $param->{content});
- if ($param->{storage}) {
- my $data = $info->{$param->{storage}};
-
- raise_param_exc({ storage => "No such storage." })
- if !defined($data);
-
- $data->{storage} = $param->{storage};
-
- return [ $data ];
+ raise_param_exc({ storage => "No such storage." })
+ if $param->{storage} && !defined($info->{$param->{storage}});
+
+ my $res = {};
+ my @sids = PVE::Storage::storage_ids($cfg);
+ foreach my $storeid (@sids) {
+ my $privs = [ 'Datastore.Audit', 'Datastore.AllocateSpace' ];
+ next if !$rpcenv->check_any($authuser, "/storage/$storeid", $privs, 1);
+ next if $param->{storage} && $param->{storage} ne $storeid;
+ $res->{$storeid} = $info->{$storeid};
}
- return PVE::RESTHandler::hash_to_array($info, 'storage');
+
+ return PVE::RESTHandler::hash_to_array($res, 'storage');
}});
__PACKAGE__->register_method ({
path => '{storage}',
method => 'GET',
description => "",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+ },
parameters => {
additionalProperties => 0,
properties => {
path => '{storage}/status',
method => 'GET',
description => "Read storage status.",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+ },
protected => 1,
proxyto => 'node',
parameters => {
path => '{storage}/rrd',
method => 'GET',
description => "Read storage RRD statistics (returns PNG).",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+ },
protected => 1,
proxyto => 'node',
parameters => {
path => '{storage}/rrddata',
method => 'GET',
description => "Read storage RRD statistics.",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.Audit', 'Datastore.AllocateSpace'], any => 1],
+ },
protected => 1,
proxyto => 'node',
parameters => {
path => '{storage}/upload',
method => 'POST',
description => "Upload file.",
+ permissions => {
+ check => ['perm', '/storage/{storage}', ['Datastore.AllocateSpace']],
+ },
protected => 1,
parameters => {
additionalProperties => 0,