]> git.proxmox.com Git - pve-storage.git/blob - PVE/API2/Storage/Scan.pm
Add cifsscan to API
[pve-storage.git] / PVE / API2 / Storage / Scan.pm
1 package PVE::API2::Storage::Scan;
2
3 use strict;
4 use warnings;
5
6 use PVE::SafeSyslog;
7 use PVE::Storage;
8 use PVE::Storage::LVMPlugin;
9 use HTTP::Status qw(:constants);
10 use PVE::JSONSchema qw(get_standard_option);
11
12 use PVE::RESTHandler;
13
14 use base qw(PVE::RESTHandler);
15
16 __PACKAGE__->register_method ({
17 name => 'index',
18 path => '',
19 method => 'GET',
20 description => "Index of available scan methods",
21 permissions => {
22 user => 'all',
23 },
24 parameters => {
25 additionalProperties => 0,
26 properties => {
27 node => get_standard_option('pve-node'),
28 },
29 },
30 returns => {
31 type => 'array',
32 items => {
33 type => "object",
34 properties => { method => { type => 'string'} },
35 },
36 links => [ { rel => 'child', href => "{method}" } ],
37 },
38 code => sub {
39 my ($param) = @_;
40
41 my $res = [
42 { method => 'lvm' },
43 { method => 'iscsi' },
44 { method => 'nfs' },
45 { method => 'glusterfs' },
46 { method => 'usb' },
47 { method => 'zfs' },
48 { method => 'cifs' },
49 ];
50
51 return $res;
52 }});
53
54 __PACKAGE__->register_method ({
55 name => 'zfsscan',
56 path => 'zfs',
57 method => 'GET',
58 description => "Scan zfs pool list on local node.",
59 protected => 1,
60 proxyto => "node",
61 permissions => {
62 check => ['perm', '/storage', ['Datastore.Allocate']],
63 },
64 parameters => {
65 additionalProperties => 0,
66 properties => {
67 node => get_standard_option('pve-node'),
68 },
69 },
70 returns => {
71 type => 'array',
72 items => {
73 type => "object",
74 properties => {
75 pool => { type => 'string'},
76 },
77 },
78 },
79 code => sub {
80 my ($param) = @_;
81
82 return PVE::Storage::scan_zfs();
83 }});
84
85 __PACKAGE__->register_method ({
86 name => 'nfsscan',
87 path => 'nfs',
88 method => 'GET',
89 description => "Scan remote NFS server.",
90 protected => 1,
91 proxyto => "node",
92 permissions => {
93 check => ['perm', '/storage', ['Datastore.Allocate']],
94 },
95 parameters => {
96 additionalProperties => 0,
97 properties => {
98 node => get_standard_option('pve-node'),
99 server => { type => 'string', format => 'pve-storage-server' },
100 },
101 },
102 returns => {
103 type => 'array',
104 items => {
105 type => "object",
106 properties => {
107 path => { type => 'string'},
108 options => { type => 'string'},
109 },
110 },
111 },
112 code => sub {
113 my ($param) = @_;
114
115 my $server = $param->{server};
116 my $res = PVE::Storage::scan_nfs($server);
117
118 my $data = [];
119 foreach my $k (keys %$res) {
120 push @$data, { path => $k, options => $res->{$k} };
121 }
122 return $data;
123 }});
124
125 __PACKAGE__->register_method ({
126 name => 'cifsscan',
127 path => 'cifs',
128 method => 'GET',
129 description => "Scan remote CIFS server.",
130 protected => 1,
131 proxyto => "node",
132 permissions => {
133 check => ['perm', '/storage', ['Datastore.Allocate']],
134 },
135 parameters => {
136 additionalProperties => 0,
137 properties => {
138 node => get_standard_option('pve-node'),
139 server => { type => 'string', format => 'pve-storage-server' },
140 username => { type => 'string', optional => 1 },
141 password => { type => 'string', optional => 1 },
142 domain => { type => 'string', optional => 1 },
143 },
144 },
145 returns => {
146 type => 'array',
147 items => {
148 type => "object",
149 properties => {
150 share => { type => 'string'},
151 description => { type => 'string'},
152 },
153 },
154 },
155 code => sub {
156 my ($param) = @_;
157
158 my $server = $param->{server};
159
160 my $username = $param->{username};
161 my $password = $param->{password};
162 my $domain = $param->{domain};
163
164 my $res = PVE::Storage::scan_cifs($server, $username, $password, $domain);
165
166 my $data = [];
167 foreach my $k (keys %$res) {
168 next if $k =~ m/NT_STATUS_/;
169 push @$data, { share => $k, description => $res->{$k} };
170 }
171
172 return $data;
173 }});
174
175 # Note: GlusterFS currently does not have an equivalent of showmount.
176 # As workaround, we simply use nfs showmount.
177 # see http://www.gluster.org/category/volumes/
178
179 __PACKAGE__->register_method ({
180 name => 'glusterfsscan',
181 path => 'glusterfs',
182 method => 'GET',
183 description => "Scan remote GlusterFS server.",
184 protected => 1,
185 proxyto => "node",
186 permissions => {
187 check => ['perm', '/storage', ['Datastore.Allocate']],
188 },
189 parameters => {
190 additionalProperties => 0,
191 properties => {
192 node => get_standard_option('pve-node'),
193 server => { type => 'string', format => 'pve-storage-server' },
194 },
195 },
196 returns => {
197 type => 'array',
198 items => {
199 type => "object",
200 properties => {
201 volname => { type => 'string'},
202 },
203 },
204 },
205 code => sub {
206 my ($param) = @_;
207
208 my $server = $param->{server};
209 my $res = PVE::Storage::scan_nfs($server);
210
211 my $data = [];
212 foreach my $path (keys %$res) {
213 if ($path =~ m!^/([^\s/]+)$!) {
214 push @$data, { volname => $1 };
215 }
216 }
217 return $data;
218 }});
219
220 __PACKAGE__->register_method ({
221 name => 'iscsiscan',
222 path => 'iscsi',
223 method => 'GET',
224 description => "Scan remote iSCSI server.",
225 protected => 1,
226 proxyto => "node",
227 permissions => {
228 check => ['perm', '/storage', ['Datastore.Allocate']],
229 },
230 parameters => {
231 additionalProperties => 0,
232 properties => {
233 node => get_standard_option('pve-node'),
234 portal => { type => 'string', format => 'pve-storage-portal-dns' },
235 },
236 },
237 returns => {
238 type => 'array',
239 items => {
240 type => "object",
241 properties => {
242 target => { type => 'string'},
243 portal => { type => 'string'},
244 },
245 },
246 },
247 code => sub {
248 my ($param) = @_;
249
250 my $res = PVE::Storage::scan_iscsi($param->{portal});
251
252 my $data = [];
253 foreach my $k (keys %$res) {
254 push @$data, { target => $k, portal => join(',', @{$res->{$k}}) };
255 }
256
257 return $data;
258 }});
259
260 __PACKAGE__->register_method ({
261 name => 'lvmscan',
262 path => 'lvm',
263 method => 'GET',
264 description => "List local LVM volume groups.",
265 protected => 1,
266 proxyto => "node",
267 permissions => {
268 check => ['perm', '/storage', ['Datastore.Allocate']],
269 },
270 parameters => {
271 additionalProperties => 0,
272 properties => {
273 node => get_standard_option('pve-node'),
274 },
275 },
276 returns => {
277 type => 'array',
278 items => {
279 type => "object",
280 properties => {
281 vg => { type => 'string'},
282 },
283 },
284 },
285 code => sub {
286 my ($param) = @_;
287
288 my $res = PVE::Storage::LVMPlugin::lvm_vgs();
289 return PVE::RESTHandler::hash_to_array($res, 'vg');
290 }});
291
292 __PACKAGE__->register_method ({
293 name => 'lvmthinscan',
294 path => 'lvmthin',
295 method => 'GET',
296 description => "List local LVM Thin Pools.",
297 protected => 1,
298 proxyto => "node",
299 permissions => {
300 check => ['perm', '/storage', ['Datastore.Allocate']],
301 },
302 parameters => {
303 additionalProperties => 0,
304 properties => {
305 node => get_standard_option('pve-node'),
306 vg => {
307 type => 'string',
308 pattern => '[a-zA-Z0-9\.\+\_][a-zA-Z0-9\.\+\_\-]+', # see lvm(8) manpage
309 maxLength => 100,
310 },
311 },
312 },
313 returns => {
314 type => 'array',
315 items => {
316 type => "object",
317 properties => {
318 lv => { type => 'string'},
319 },
320 },
321 },
322 code => sub {
323 my ($param) = @_;
324
325 return PVE::Storage::LvmThinPlugin::list_thinpools($param->{vg});
326 }});
327
328 __PACKAGE__->register_method ({
329 name => 'usbscan',
330 path => 'usb',
331 method => 'GET',
332 description => "List local USB devices.",
333 protected => 1,
334 proxyto => "node",
335 permissions => {
336 check => ['perm', '/', ['Sys.Modify']],
337 },
338 parameters => {
339 additionalProperties => 0,
340 properties => {
341 node => get_standard_option('pve-node'),
342 },
343 },
344 returns => {
345 type => 'array',
346 items => {
347 type => "object",
348 properties => {
349 busnum => { type => 'integer'},
350 devnum => { type => 'integer'},
351 port => { type => 'integer'},
352 usbpath => { type => 'string', optional => 1},
353 level => { type => 'integer'},
354 class => { type => 'integer'},
355 vendid => { type => 'string'},
356 prodid => { type => 'string'},
357 speed => { type => 'string'},
358
359 product => { type => 'string', optional => 1 },
360 serial => { type => 'string', optional => 1 },
361 manufacturer => { type => 'string', optional => 1 },
362 },
363 },
364 },
365 code => sub {
366 my ($param) = @_;
367
368 return PVE::Storage::scan_usb();
369 }});
370
371 1;