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