]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/Parser.js
add Directory list/create gui
[pve-manager.git] / www / manager6 / Parser.js
CommitLineData
fcb64fe4
DM
1// Some configuration values are complex strings -
2// so we need parsers/generators for them.
3
4Ext.define('PVE.Parser', { statics: {
5
6 // this class only contains static functions
7
488be4c2
DC
8 parseACME: function(value) {
9 if (!value) {
10 return;
11 }
12
13 var res = {};
14 var errors = false;
15
16 Ext.Array.each(value.split(','), function(p) {
17 if (!p || p.match(/^\s*$/)) {
18 return; //continue
19 }
20
21 var match_res;
22 if ((match_res = p.match(/^(?:domains=)?((?:[a-zA-Z0-9\-\.]+[;, ]?)+)$/)) !== null) {
23 res.domains = match_res[1].split(/[;, ]/);
24 } else {
25 errors = true;
26 return false;
27 }
28 });
29
30 if (errors || !res) {
31 return;
32 }
33
34 return res;
35 },
36
4c1c0d5d 37 parseBoolean: function(value, default_value) {
84de645d 38 if (!Ext.isDefined(value)) {
4c1c0d5d 39 return default_value;
84de645d 40 }
4c1c0d5d 41 value = value.toLowerCase();
ec0bd652 42 return value === '1' ||
4c1c0d5d
EK
43 value === 'on' ||
44 value === 'yes' ||
45 value === 'true';
46 },
47
fcb64fe4
DM
48 parseQemuNetwork: function(key, value) {
49 if (!(key && value)) {
50 return;
51 }
52
53 var res = {};
54
55 var errors = false;
56 Ext.Array.each(value.split(','), function(p) {
57 if (!p || p.match(/^\s*$/)) {
58 return; // continue
59 }
60
61 var match_res;
62
63 if ((match_res = p.match(/^(ne2k_pci|e1000|e1000-82540em|e1000-82544gc|e1000-82545em|vmxnet3|rtl8139|pcnet|virtio|ne2k_isa|i82551|i82557b|i82559er)(=([0-9a-f]{2}(:[0-9a-f]{2}){5}))?$/i)) !== null) {
64 res.model = match_res[1].toLowerCase();
65 if (match_res[3]) {
66 res.macaddr = match_res[3];
67 }
68 } else if ((match_res = p.match(/^bridge=(\S+)$/)) !== null) {
69 res.bridge = match_res[1];
70 } else if ((match_res = p.match(/^rate=(\d+(\.\d+)?)$/)) !== null) {
71 res.rate = match_res[1];
72 } else if ((match_res = p.match(/^tag=(\d+(\.\d+)?)$/)) !== null) {
63e62a6f 73 res.tag = match_res[1];
fcb64fe4 74 } else if ((match_res = p.match(/^firewall=(\d+)$/)) !== null) {
63e62a6f 75 res.firewall = match_res[1];
fcb64fe4 76 } else if ((match_res = p.match(/^link_down=(\d+)$/)) !== null) {
63e62a6f 77 res.disconnect = match_res[1];
fcb64fe4 78 } else if ((match_res = p.match(/^queues=(\d+)$/)) !== null) {
63e62a6f 79 res.queues = match_res[1];
a2ed0697
WB
80 } else if ((match_res = p.match(/^trunks=(\d+(?:-\d+)?(?:;\d+(?:-\d+)?)*)$/)) !== null) {
81 res.trunks = match_res[1];
fcb64fe4
DM
82 } else {
83 errors = true;
84 return false; // break
85 }
86 });
87
88 if (errors || !res.model) {
89 return;
90 }
91
92 return res;
93 },
94
95 printQemuNetwork: function(net) {
96
97 var netstr = net.model;
98 if (net.macaddr) {
99 netstr += "=" + net.macaddr;
100 }
101 if (net.bridge) {
102 netstr += ",bridge=" + net.bridge;
103 if (net.tag) {
104 netstr += ",tag=" + net.tag;
105 }
106 if (net.firewall) {
107 netstr += ",firewall=" + net.firewall;
108 }
109 }
110 if (net.rate) {
111 netstr += ",rate=" + net.rate;
112 }
113 if (net.queues) {
114 netstr += ",queues=" + net.queues;
115 }
116 if (net.disconnect) {
117 netstr += ",link_down=" + net.disconnect;
118 }
a2ed0697
WB
119 if (net.trunks) {
120 netstr += ",trunks=" + net.trunks;
121 }
fcb64fe4
DM
122 return netstr;
123 },
124
125 parseQemuDrive: function(key, value) {
126 if (!(key && value)) {
127 return;
128 }
129
130 var res = {};
131
132 var match_res = key.match(/^([a-z]+)(\d+)$/);
133 if (!match_res) {
134 return;
135 }
136 res['interface'] = match_res[1];
137 res.index = match_res[2];
138
139 var errors = false;
140 Ext.Array.each(value.split(','), function(p) {
141 if (!p || p.match(/^\s*$/)) {
142 return; // continue
143 }
144 var match_res = p.match(/^([a-z_]+)=(\S+)$/);
145 if (!match_res) {
146 if (!p.match(/\=/)) {
147 res.file = p;
148 return; // continue
149 }
150 errors = true;
151 return false; // break
152 }
153 var k = match_res[1];
154 if (k === 'volume') {
155 k = 'file';
156 }
157
158 if (Ext.isDefined(res[k])) {
159 errors = true;
160 return false; // break
161 }
162
163 var v = match_res[2];
164
165 if (k === 'cache' && v === 'off') {
166 v = 'none';
167 }
168
169 res[k] = v;
170 });
171
172 if (errors || !res.file) {
173 return;
174 }
175
176 return res;
177 },
178
179 printQemuDrive: function(drive) {
180
181 var drivestr = drive.file;
182
183 Ext.Object.each(drive, function(key, value) {
184 if (!Ext.isDefined(value) || key === 'file' ||
185 key === 'index' || key === 'interface') {
186 return; // continue
187 }
188 drivestr += ',' + key + '=' + value;
189 });
190
191 return drivestr;
192 },
193
01e02121
DC
194 parseIPConfig: function(key, value) {
195 if (!(key && value)) {
196 return;
197 }
198
199 var res = {};
200
201 var errors = false;
202 Ext.Array.each(value.split(','), function(p) {
203 if (!p || p.match(/^\s*$/)) {
204 return; // continue
205 }
206
207 var match_res;
208 if ((match_res = p.match(/^ip=(\S+)$/)) !== null) {
209 res.ip = match_res[1];
210 } else if ((match_res = p.match(/^gw=(\S+)$/)) !== null) {
211 res.gw = match_res[1];
212 } else if ((match_res = p.match(/^ip6=(\S+)$/)) !== null) {
213 res.ip6 = match_res[1];
214 } else if ((match_res = p.match(/^gw6=(\S+)$/)) !== null) {
215 res.gw6 = match_res[1];
216 } else {
217 errors = true;
218 return false; // break
219 }
220 });
221
222 if (errors) {
223 return;
224 }
225
226 return res;
227 },
228
229 printIPConfig: function(cfg) {
230 var c = "";
231 var str = "";
232 if (cfg.ip) {
233 str += "ip=" + cfg.ip;
234 c = ",";
235 }
236 if (cfg.gw) {
237 str += c + "gw=" + cfg.gw;
238 c = ",";
239 }
240 if (cfg.ip6) {
241 str += c + "ip6=" + cfg.ip6;
242 c = ",";
243 }
244 if (cfg.gw6) {
245 str += c + "gw6=" + cfg.gw6;
246 c = ",";
247 }
248 return str;
249 },
250
fcb64fe4
DM
251 parseOpenVZNetIf: function(value) {
252 if (!value) {
253 return;
254 }
255
256 var res = {};
257
258 var errors = false;
259 Ext.Array.each(value.split(';'), function(item) {
260 if (!item || item.match(/^\s*$/)) {
261 return; // continue
262 }
263
264 var data = {};
265 Ext.Array.each(item.split(','), function(p) {
266 if (!p || p.match(/^\s*$/)) {
267 return; // continue
268 }
269 var match_res = p.match(/^(ifname|mac|bridge|host_ifname|host_mac|mac_filter)=(\S+)$/);
270 if (!match_res) {
271 errors = true;
272 return false; // break
273 }
274 if (match_res[1] === 'bridge'){
275 var bridgevlanf = match_res[2];
276 var bridge_res = bridgevlanf.match(/^(vmbr(\d+))(v(\d+))?(f)?$/);
277 if (!bridge_res) {
278 errors = true;
279 return false; // break
280 }
ec0bd652
DC
281 data.bridge = bridge_res[1];
282 data.tag = bridge_res[4];
283 /*jslint confusion: true*/
284 data.firewall = bridge_res[5] ? 1 : 0;
285 /*jslint confusion: false*/
fcb64fe4
DM
286 } else {
287 data[match_res[1]] = match_res[2];
288 }
289 });
290
291 if (errors || !data.ifname) {
292 errors = true;
293 return false; // break
294 }
295
296 data.raw = item;
297
298 res[data.ifname] = data;
299 });
300
301 return errors ? undefined: res;
302 },
303
304 printOpenVZNetIf: function(netif) {
305 var netarray = [];
306
307 Ext.Object.each(netif, function(iface, data) {
308 var tmparray = [];
309 Ext.Array.each(['ifname', 'mac', 'bridge', 'host_ifname' , 'host_mac', 'mac_filter', 'tag', 'firewall'], function(key) {
310 var value = data[key];
311 if (key === 'bridge'){
ec0bd652
DC
312 if(data.tag){
313 value = value + 'v' + data.tag;
fcb64fe4 314 }
ec0bd652 315 if (data.firewall){
fcb64fe4
DM
316 value = value + 'f';
317 }
318 }
319 if (value) {
320 tmparray.push(key + '=' + value);
321 }
322
323 });
324 netarray.push(tmparray.join(','));
325 });
326
327 return netarray.join(';');
328 },
329
330 parseLxcNetwork: function(value) {
331 if (!value) {
332 return;
333 }
334
335 var data = {};
336 Ext.Array.each(value.split(','), function(p) {
337 if (!p || p.match(/^\s*$/)) {
338 return; // continue
339 }
519ca7fa 340 var match_res = p.match(/^(bridge|hwaddr|mtu|name|ip|ip6|gw|gw6|firewall|tag|rate)=(\S+)$/);
fcb64fe4
DM
341 if (!match_res) {
342 // todo: simply ignore errors ?
343 return; // continue
344 }
345 data[match_res[1]] = match_res[2];
346 });
347
348 return data;
349 },
350
351 printLxcNetwork: function(data) {
352 var tmparray = [];
353 Ext.Array.each(['bridge', 'hwaddr', 'mtu', 'name', 'ip',
354 'gw', 'ip6', 'gw6', 'firewall', 'tag'], function(key) {
355 var value = data[key];
356 if (value) {
357 tmparray.push(key + '=' + value);
358 }
359 });
519ca7fa 360
ec0bd652 361 /*jslint confusion: true*/
6efbc4cb 362 if (data.rate > 0) {
519ca7fa
DM
363 tmparray.push('rate=' + data.rate);
364 }
ec0bd652 365 /*jslint confusion: false*/
fcb64fe4
DM
366 return tmparray.join(',');
367 },
368
4c1c0d5d
EK
369 parseLxcMountPoint: function(value) {
370 if (!value) {
371 return;
372 }
373
374 var res = {};
375
376 var errors = false;
377 Ext.Array.each(value.split(','), function(p) {
378 if (!p || p.match(/^\s*$/)) {
379 return; // continue
380 }
381 var match_res = p.match(/^([a-z_]+)=(\S+)$/);
382 if (!match_res) {
383 if (!p.match(/\=/)) {
384 res.file = p;
385 return; // continue
386 }
387 errors = true;
388 return false; // break
389 }
390 var k = match_res[1];
391 if (k === 'volume') {
392 k = 'file';
393 }
394
395 if (Ext.isDefined(res[k])) {
396 errors = true;
397 return false; // break
398 }
399
400 var v = match_res[2];
401
402 res[k] = v;
403 });
404
405 if (errors || !res.file) {
406 return;
407 }
408
283b450e 409 var m = res.file.match(/^([a-z][a-z0-9\-\_\.]*[a-z0-9]):/i);
4c1c0d5d
EK
410 if (m) {
411 res.storage = m[1];
412 res.type = 'volume';
413 } else if (res.file.match(/^\/dev\//)) {
414 res.type = 'device';
415 } else {
416 res.type = 'bind';
417 }
418
419 return res;
420 },
421
422 printLxcMountPoint: function(mp) {
423 var drivestr = mp.file;
424
425 Ext.Object.each(mp, function(key, value) {
426 if (!Ext.isDefined(value) || key === 'file' ||
427 key === 'type' || key === 'storage') {
428 return; // continue
429 }
430 drivestr += ',' + key + '=' + value;
431 });
432
433 return drivestr;
434 },
435
fcb64fe4
DM
436 parseStartup: function(value) {
437 if (value === undefined) {
438 return;
439 }
440
441 var res = {};
442
443 var errors = false;
444 Ext.Array.each(value.split(','), function(p) {
445 if (!p || p.match(/^\s*$/)) {
446 return; // continue
447 }
448
449 var match_res;
450
451 if ((match_res = p.match(/^(order)?=(\d+)$/)) !== null) {
452 res.order = match_res[2];
453 } else if ((match_res = p.match(/^up=(\d+)$/)) !== null) {
454 res.up = match_res[1];
455 } else if ((match_res = p.match(/^down=(\d+)$/)) !== null) {
456 res.down = match_res[1];
457 } else {
458 errors = true;
459 return false; // break
460 }
461 });
462
463 if (errors) {
464 return;
465 }
466
467 return res;
468 },
469
470 printStartup: function(startup) {
471 var arr = [];
472 if (startup.order !== undefined && startup.order !== '') {
473 arr.push('order=' + startup.order);
474 }
475 if (startup.up !== undefined && startup.up !== '') {
476 arr.push('up=' + startup.up);
477 }
478 if (startup.down !== undefined && startup.down !== '') {
479 arr.push('down=' + startup.down);
480 }
481
482 return arr.join(',');
483 },
484
485 parseQemuSmbios1: function(value) {
486 var res = {};
487
488 Ext.Array.each(value.split(','), function(p) {
ec0bd652 489 var kva = p.split('=', 2);
fcb64fe4
DM
490 res[kva[0]] = kva[1];
491 });
492
493 return res;
494 },
495
496 printQemuSmbios1: function(data) {
497
498 var datastr = '';
499
500 Ext.Object.each(data, function(key, value) {
84de645d 501 if (value === '') { return; }
fcb64fe4
DM
502 datastr += (datastr !== '' ? ',' : '') + key + '=' + value;
503 });
504
505 return datastr;
506 },
507
508 parseTfaConfig: function(value) {
509 var res = {};
510
511 Ext.Array.each(value.split(','), function(p) {
ec0bd652 512 var kva = p.split('=', 2);
fcb64fe4
DM
513 res[kva[0]] = kva[1];
514 });
515
516 return res;
4c1c0d5d
EK
517 },
518
519 parseQemuCpu: function(value) {
520 if (!value) {
521 return {};
522 }
523
524 var res = {};
525
526 var errors = false;
527 Ext.Array.each(value.split(','), function(p) {
528 if (!p || p.match(/^\s*$/)) {
529 return; // continue
530 }
fcb64fe4 531
ec0bd652
DC
532 if (!p.match(/\=/)) {
533 if (Ext.isDefined(res.cpu)) {
4c1c0d5d
EK
534 errors = true;
535 return false; // break
536 }
537 res.cputype = p;
538 return; // continue
539 }
540
541 var match_res = p.match(/^([a-z_]+)=(\S+)$/);
542 if (!match_res) {
543 errors = true;
544 return false; // break
545 }
546
547 var k = match_res[1];
548 if (Ext.isDefined(res[k])) {
549 errors = true;
550 return false; // break
551 }
552
553 res[k] = match_res[2];
554 });
555
556 if (errors || !res.cputype) {
557 return;
558 }
559
560 return res;
561 },
562
563 printQemuCpu: function(cpu) {
564 var cpustr = cpu.cputype;
565 var optstr = '';
566
567 Ext.Object.each(cpu, function(key, value) {
568 if (!Ext.isDefined(value) || key === 'cputype') {
569 return; // continue
570 }
571 optstr += ',' + key + '=' + value;
572 });
573
574 if (!cpustr) {
84de645d 575 if (optstr) {
4c1c0d5d 576 return 'kvm64' + optstr;
84de645d 577 }
4c1c0d5d
EK
578 return;
579 }
580
581 return cpustr + optstr;
b1339314
WB
582 },
583
584 parseSSHKey: function(key) {
585 // |--- options can have quotes--| type key comment
586 var keyre = /^(?:((?:[^\s"]|\"(?:\\.|[^"\\])*")+)\s+)?(\S+)\s+(\S+)(?:\s+(.*))?$/;
587 var typere = /^(?:ssh-(?:dss|rsa|ed25519)|ecdsa-sha2-nistp\d+)$/;
588
589 var m = key.match(keyre);
590 if (!m) {
591 return null;
592 }
593 if (m.length < 3 || !m[2]) { // [2] is always either type or key
594 return null;
595 }
596 if (m[1] && m[1].match(typere)) {
597 return {
598 type: m[1],
599 key: m[2],
600 comment: m[3]
601 };
602 }
603 if (m[2].match(typere)) {
604 return {
605 options: m[1],
606 type: m[2],
607 key: m[3],
608 comment: m[4]
609 };
610 }
611 return null;
22f2f9d6 612 }
fcb64fe4 613}});