2 // Helper functions for processing a VNF worksheet
\r
4 var helpers = require('./helpers.js');
\r
5 var _ = require('lodash');
\r
6 var csvtojson = require('csvtojson');
\r
7 var async = require('async');
\r
8 var uuid = require('node-uuid'); // generate a uuid with "uuid.v1()"
\r
9 var path = require('path');
\r
10 var fs = require("fs");
\r
11 var moment = require("moment");
\r
13 var vnf = module.exports;
\r
14 var getParam = helpers.getParam;
\r
18 var csvGeneral, csvZones, csvNetworks, csvVMs, csvVMnetworks, csvVMnetworkIPs, csvVMnetworkMACs, csvTagValues;
\r
23 var preloadVersion; // 1607, 1610, etc...
\r
24 var proc_error=false;
\r
27 puts = helpers.puts;
\r
28 putd = helpers.putd;
\r
30 vnf.go = function(lreq,lres,cb,dir){
\r
31 puts("Processing VNF workbook");
\r
41 indir=process.cwd() + "/uploads/";
\r
47 // READ WORKSHEET: GENERAL
\r
49 function doGeneral() {
\r
50 puts("Reading General worksheet");
\r
51 var csvFilename="General.csv";
\r
52 var newFileName = helpers.getFileName(req, csvFilename);
\r
53 if ( newFileName != null ) {
\r
54 helpers.readCsv(indir, newFileName, gotGeneral);
\r
57 puts('General.csv file is missing from upload.');
\r
62 function gotGeneral(err, jsonObj) {
\r
67 callback('General.csv file is missing from upload.');
\r
70 csvGeneral = jsonObj;
\r
71 puts("\nRead this: ");
\r
77 // READ WORKSHEET: AVAILABILITY ZONES
\r
79 function doAvailZones() {
\r
80 puts("Reading Availability-zones worksheet");
\r
81 var csvFilename="Availability-zones.csv";
\r
82 var newFileName = helpers.getFileName(req, csvFilename);
\r
83 if ( newFileName != null ) {
\r
84 helpers.readCsv(indir, newFileName, gotAvailZones);
\r
88 callback(csvFilename + ' file is missing from upload.');
\r
93 function gotAvailZones(err, jsonObj) {
\r
98 callback('Availability-zones.csv file is missing from upload.');
\r
101 csvZones = jsonObj;
\r
102 csvZones = _.reject(csvZones, 'field2', 'Availability Zones');
\r
103 csvZones = _.reject(csvZones, 'field2', 'List the availability zones for this VNF');
\r
104 csvZones = _.reject(csvZones, 'field2', '');
\r
105 puts("\nRead this: ");
\r
111 // READ WORKSHEET: NETWORKS
\r
113 function doNetworks() {
\r
114 puts("Reading Networks worksheet");
\r
115 var csvFilename="Networks.csv";
\r
116 var newFileName = helpers.getFileName(req, csvFilename);
\r
117 if ( newFileName != null ) {
\r
118 helpers.readCsv(indir, newFileName, gotNetworks);
\r
122 callback(csvFilename + ' file is missing from upload.');
\r
127 function gotNetworks(err, jsonObj) {
\r
132 callback('Networks.csv file is missing from upload.');
\r
135 csvNetworks = jsonObj;
\r
136 csvNetworks = _.reject(csvNetworks, 'field2', 'Networks');
\r
137 csvNetworks = _.reject(csvNetworks, 'field2', 'List the VNF networks. (VM-networks are on a different worksheet.)');
\r
138 csvNetworks = _.reject(csvNetworks, 'field2', 'network-role');
\r
139 csvNetworks = _.reject(csvNetworks, 'field2', '');
\r
140 puts("\nRead this: ");
\r
146 // READ WORKSHEET: VMs
\r
149 puts("Reading VMs worksheet");
\r
150 var csvFilename="VMs.csv";
\r
151 var newFileName = helpers.getFileName(req, csvFilename);
\r
152 if ( newFileName != null ) {
\r
153 helpers.readCsv(indir, newFileName, gotVMs);
\r
157 callback(csvFilename + ' file is missing from upload.');
\r
162 function gotVMs(err, jsonObj) {
\r
167 callback('VMs.csv file is missing from upload.');
\r
171 csvVMs = _.reject(csvVMs, 'field2', 'VMs');
\r
172 csvVMs = _.reject(csvVMs, 'field2', 'List the VM types for this VNF');
\r
173 csvVMs = _.reject(csvVMs, 'field2', 'vm-type');
\r
174 csvVMs = _.reject(csvVMs, 'field2', '');
\r
175 puts("\nRead this: ");
\r
181 // READ WORKSHEET: VM-NETWORKS
\r
183 function doVMnetworks() {
\r
184 puts("Reading VM-networks worksheet");
\r
185 var csvFilename="VM-networks.csv";
\r
186 var newFileName = helpers.getFileName(req, csvFilename);
\r
187 if ( newFileName != null ) {
\r
188 helpers.readCsv(indir, newFileName, gotVMnetworks);
\r
192 callback(csvFilename + ' file is missing from upload.');
\r
197 function gotVMnetworks(err, jsonObj) {
\r
202 callback('VM-networks.csv file is missing from upload.');
\r
205 csvVMnetworks = jsonObj;
\r
206 csvVMnetworks = _.reject(csvVMnetworks, 'field2', 'VM-networks');
\r
207 csvVMnetworks = _.reject(csvVMnetworks, 'field2', 'List the VM-networks for each VM type');
\r
208 csvVMnetworks = _.reject(csvVMnetworks, 'field2', 'vm-type');
\r
209 csvVMnetworks = _.reject(csvVMnetworks, 'field2', '');
\r
210 puts("\nRead this: ");
\r
211 putd(csvVMnetworks);
\r
216 // READ WORKSHEET: VM-NETWORK-IPS
\r
218 function doVMnetworkIPs() {
\r
219 puts("Reading VM-network-IPs worksheet");
\r
220 var csvFilename="VM-network-IPs.csv";
\r
221 var newFileName = helpers.getFileName(req, csvFilename);
\r
222 if ( newFileName != null ) {
\r
223 helpers.readCsv(indir, newFileName, gotVMnetworkIPs);
\r
227 callback(csvFilename + ' file is missing from upload.');
\r
232 function gotVMnetworkIPs(err, jsonObj) {
\r
237 callback('VM-network-IPs.csv file is missing from upload.');
\r
240 csvVMnetworkIPs = jsonObj;
\r
241 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', 'VM-network-IPs');
\r
242 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', 'List the IPs assigned to each VM-network');
\r
243 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', 'vm-type');
\r
244 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', '');
\r
245 puts("\nRead this: ");
\r
246 putd(csvVMnetworkIPs);
\r
251 // READ WORKSHEET: VM-NETWORK-MACS
\r
253 function doVMnetworkMACs() {
\r
254 puts("Reading VM-network-MACs worksheet");
\r
255 var csvFilename="VM-network-MACs.csv";
\r
256 var newFileName = helpers.getFileName(req, csvFilename);
\r
257 if ( newFileName != null ) {
\r
258 helpers.readCsv(indir, newFileName, gotVMnetworkMACs);
\r
262 callback(csvFilename + ' file is missing from upload.');
\r
267 function gotVMnetworkMACs(err, jsonObj) {
\r
272 callback('VM-network-MACs.csv file is missing from upload.');
\r
275 csvVMnetworkMACs = jsonObj;
\r
276 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', 'VM-network-MACs');
\r
277 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', 'List the MACs assigned to each VM-network');
\r
278 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', 'vm-type');
\r
279 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', '');
\r
280 puts("\nRead this: ");
\r
281 putd(csvVMnetworkMACs);
\r
286 // READ WORKSHEET: TAG-VALUES
\r
288 function doTagValues() {
\r
289 puts("Reading Tag-values worksheet");
\r
290 var csvFilename="Tag-values.csv";
\r
291 var newFileName = helpers.getFileName(req, csvFilename);
\r
292 if ( newFileName != null ) {
\r
293 helpers.readCsv(indir, newFileName, gotTagValues);
\r
297 callback(csvFilename + ' file is missing from upload.');
\r
302 function gotTagValues(err, jsonObj) {
\r
307 callback('Tag-values.csv file is missing from upload.');
\r
310 csvTagValues = jsonObj;
\r
311 csvTagValues = _.reject(csvTagValues, 'field2', 'Tag-values');
\r
312 csvTagValues = _.reject(csvTagValues, 'field2', 'Extra data to be passed into the HEAT template for this VNF');
\r
313 csvTagValues = _.reject(csvTagValues, 'field2', 'vnf-parameter-name');
\r
314 csvTagValues = _.reject(csvTagValues, 'field2', 'vnf-parameter-value');
\r
315 csvTagValues = _.reject(csvTagValues, 'field2', '');
\r
316 puts("\nRead this: ");
\r
317 putd(csvTagValues);
\r
319 doneReadingFiles();
\r
325 function doneReadingFiles() {
\r
327 puts("DONE READING FILES!");
\r
333 // PROCESS THE CSV FILES INTO OBJECTS TO BE ASSEMBLED INTO FINAL OUTPUT
\r
334 function processJson() {
\r
336 processAvailZones();
\r
338 processVMnetworks();
\r
340 processVMnetmacs();
\r
342 processTagValues();
\r
346 puts('proc_error=');
\r
349 puts('callback with failure');
\r
350 callback('Error was encountered processing upload.');
\r
355 puts('callback with success');
\r
356 callback(null, finalJson, filename);
\r
361 // ASSEMBLE AND OUTPUT RESULTS
\r
363 function assembleJson() {
\r
365 puts("Using raw JSON and assembling final ouptut JSON.");
\r
368 vnfTopoID = { "service-type": "SDN-MOBILITY",
\r
369 "vnf-name": rawJson['vf-module-name'],
\r
370 "vnf-type": rawJson['vf-module-model-name'],
\r
371 "generic-vnf-name": rawJson['generic-vnf-name'],
\r
372 "generic-vnf-type": rawJson['generic-vnf-type'] };
\r
374 vnfZones = rawJson['availability-zones'];
\r
376 vnfNetworks = rawJson['networks'];
\r
378 vnfVMs = rawJson['vms'];
\r
380 vnfParams = rawJson['tag-values'];
\r
382 vnfAssignments = { "availability-zones": vnfZones,
\r
383 "vnf-networks": vnfNetworks,
\r
384 "vnf-vms": vnfVMs};
\r
386 vnfTopo = { "vnf-topology-identifier": vnfTopoID,
\r
387 "vnf-assignments": vnfAssignments,
\r
388 "vnf-parameters": vnfParams };
\r
390 vnfInput = {'vnf-topology-information': vnfTopo};
\r
392 finalJson = {"input": vnfInput};
\r
397 function outputJson() {
\r
400 puts(JSON.stringify(finalJson,null,2));
\r
403 var unixTime, fullpath_filename;
\r
404 unixTime = moment().unix();
\r
405 if (platform=='portal') {
\r
406 fullpath_filename = process.cwd() + "/uploads/" + unixTime + ".vnf_worksheet.json";
\r
407 filename = unixTime + ".vnf_worksheet.json.";
\r
409 fullpath_filename = "./output.json."+unixTime;
\r
410 filename = "output.json." + unixTime;
\r
412 //helpers.writeOutput(req, fullpath_filename, JSON.stringify(finalJson,null,2), callback);
\r
413 //callback(null, finalJson, filename);
\r
417 // Gather functions that actually process data after it is all read
\r
419 function processGeneral() {
\r
421 preloadVersion = getParam(csvGeneral, 'field2', 'preload-version', 'field3');
\r
422 rawJson['preload-version'] = preloadVersion;
\r
423 puts("Preload version: " + preloadVersion);
\r
425 if ( (preloadVersion!='1607') && (preloadVersion!='1610') ) {
\r
426 puts("\nError - incorrect version of preload worksheet.");
\r
427 callback('Error - incorrect version of preload worksheet.');
\r
430 rawJson['vf-module-name'] = getParam(csvGeneral, 'field2', 'vf-module-name', 'field3');
\r
431 // rawJson['vf-module-type'] = getParam(csvGeneral, 'field2', 'vf-module-type', 'field3');
\r
433 rawJson['vf-module-model-name'] = getParam(csvGeneral, 'field2', 'vf-module-model-name', 'field3');
\r
436 puts("ERROR ERROR ERROR ERROR ERROR\n");
\r
437 puts("Failed to find data field 'vf-module-model-name'. Maybe this preload worksheet is older?")
\r
438 puts("If on the 'general' tab there is a field called 'vf-module-type' please rename it to 'vf-module-model-name'");
\r
442 rawJson['generic-vnf-name'] = getParam(csvGeneral, 'field2', 'vnf-name', 'field3');
\r
443 rawJson['generic-vnf-type'] = getParam(csvGeneral, 'field2', 'vnf-type', 'field3');
\r
444 rawJson['request-id'] = uuid.v1();
\r
445 rawJson['source'] = "ADMINPORTAL";
\r
446 rawJson['request-action'] = "PreloadVNFRequest";
\r
447 rawJson['svc-request-id'] = uuid.v1();
\r
448 rawJson['svc-action'] = "reserve";
\r
454 function processAvailZones() {
\r
455 var newZones = _.map(csvZones, function(x) { return {'availability-zone': x['field2']}; } );
\r
456 rawJson['availability-zones'] = newZones;
\r
457 puts("Availability zones read:");
\r
458 putd(rawJson['availability-zones']);
\r
462 function processNetworks() {
\r
463 var newNetworks = [];
\r
464 csvNetworks.forEach( function(network) {
\r
466 netJson["network-role"] = network.field2;
\r
467 netJson["network-name"] = network.field3;
\r
468 netJson["network-id"] = network.field4;
\r
469 netJson["contrail-network-fqdn"] = network.field5;
\r
470 netJson["subnet-name"] = network.field6;
\r
471 netJson["subnet-id"] = network.field7;
\r
472 netJson["ipv6-subnet-name"] = network.field8;
\r
473 netJson["ipv6-subnet-id"] = network.field9;
\r
474 newNetworks.push(netJson);
\r
479 rawJson["networks"] = newNetworks;
\r
482 function processVMs() {
\r
484 csvVMs.forEach( function(vm) {
\r
486 vmJson["vm-type"] = vm.field2;
\r
487 vmJson["vm-name"] = vm.field3;
\r
488 newVMs.push(vmJson);
\r
495 // OK, now for each type, get count and then build vm-names array of the names
\r
497 vmTypes = _.uniq(_.pluck(newVMs,'vm-type'));
\r
498 vmTypes.forEach( function(vmType) {
\r
505 vmThisType=_.select(newVMs, 'vm-type', vmType);
\r
506 vmCount=vmThisType.length;
\r
507 vmJson["vm-type"] = vmType;
\r
508 vmJson["vm-count"] = vmCount;
\r
509 tmpNames = _.pluck(vmThisType,'vm-name');
\r
510 vmJson["vm-names"] = _.map(tmpNames, function(nam) { return {"vm-name": nam}; } );
\r
511 netroles = _.select( rawJson["vm-networks"], "vm-type", vmType );
\r
513 netroles.forEach( function(netrole) {
\r
514 tmpNetDetails = {};
\r
515 tmpNetDetails["network-role"] = netrole["network-role"];
\r
516 tmpNetDetails["use-dhcp"] = netrole["use-dhcp"];
\r
518 var tmpipsThisVmType=[];
\r
519 tmpipsThisVmType = _.select( rawJson["vm-net-ips"], "vm-type", vmType);
\r
521 tmpips = _.select( tmpipsThisVmType, "network-role", netrole["network-role"]);
\r
522 tmpipsJson = _.map(tmpips, function(ip) { return {"ip-address": ip["ip-address"]} } );
\r
523 tmpipsJson = _.reject(tmpipsJson, function(o) { return (o["ip-address"]==undefined); } );
\r
524 tmpNetDetails["network-ips"] = tmpipsJson;
\r
526 var tmpipsv6ThisVmType=[];
\r
527 tmpipsv6ThisVmType = _.select( rawJson["vm-net-ips"], "vm-type", vmType);
\r
529 tmpipsv6 = _.select( tmpipsv6ThisVmType, "network-role", netrole["network-role"]);
\r
530 tmpipsv6Json = _.map(tmpipsv6, function(ip) { return {"ip-address-ipv6": ip["ipv6-address"]} } );
\r
531 tmpipsv6Json = _.reject(tmpipsv6Json, function(o) { return (o["ip-address-ipv6"]==undefined); } );
\r
532 tmpNetDetails["network-ips-v6"] = tmpipsv6Json;
\r
534 var tmpirpThisVmType=[];
\r
535 tmpirpThisVmType = _.select( rawJson["vm-net-ips"], "vm-type", vmType);
\r
537 tmpirp = _.select( tmpirpThisVmType, "network-role", netrole["network-role"]);
\r
538 tmpirpJson = _.map(tmpirp, function(irp) { return {"interface-route-prefix-cidr": irp["interface-route-prefix"]} } );
\r
539 tmpirpJson = _.reject(tmpirpJson, function(o) { return (o["interface-route-prefix-cidr"]==undefined); } );
\r
540 tmpNetDetails["interface-route-prefixes"] = tmpirpJson;
\r
542 var tmpmacsThisVmType=[];
\r
543 tmpmacsThisVmType = _.select( rawJson["vm-net-macs"], "vm-type", vmType);
\r
545 tmpmacs = _.select( tmpmacsThisVmType, "network-role", netrole["network-role"]);
\r
546 tmpmacsJson = _.map(tmpmacs, function(mac) { return {"mac-address": mac["mac-address"]} } );
\r
547 tmpNetDetails["network-macs"] = tmpmacsJson;
\r
550 fip = netrole["floating-ip"];
\r
553 tmpNetDetails["floating-ip"] = netrole["floating-ip"];
\r
557 fipv6 = netrole["floating-ip-v6"];
\r
558 fipv6 = _.trim(fipv6);
\r
560 tmpNetDetails["floating-ip-v6"] = netrole["floating-ip-v6"];
\r
563 newnetroles.push(tmpNetDetails);
\r
566 vmJson["vm-networks"] = newnetroles;
\r
568 vnfvms.push(vmJson);
\r
571 rawJson["vms"] = vnfvms;
\r
574 function processVMnetworks() {
\r
575 // For each VM type, for each Network role, get details like use-dhcp
\r
576 var newVMnetworks = [];
\r
577 csvVMnetworks.forEach( function(vm) {
\r
578 var newvmJson = {};
\r
579 newvmJson["vm-type"] = vm.field2;
\r
580 newvmJson["network-role"] = vm.field3;
\r
581 newvmJson["use-dhcp"] = vm.field4;
\r
582 newvmJson["floating-ip"] = vm.field5;
\r
583 newvmJson["floating-ip-v6"] = vm.field6;
\r
584 newVMnetworks.push(newvmJson);
\r
587 rawJson["vm-networks"] = newVMnetworks;
\r
588 puts("rawJson for vm-networks...");
\r
589 putd( rawJson["vm-networks"] );
\r
593 function processVMnetips() {
\r
594 // For each VM type, for each network role, get the set of network IPs
\r
595 puts("Processing VM-net-ips");
\r
596 var newVMnetips = [];
\r
597 csvVMnetworkIPs.forEach( function(vm) {
\r
598 var newvmnetipsJson = {};
\r
599 newvmnetipsJson["vm-type"] = vm.field2;
\r
600 newvmnetipsJson["network-role"] = vm.field3;
\r
601 if (_.trim(vm.field4)!="") {
\r
602 newvmnetipsJson["ip-address"] = vm.field4;
\r
604 if (_.trim(vm.field5)!="") {
\r
605 newvmnetipsJson["ipv6-address"] = vm.field5;
\r
607 if (_.trim(vm.field6)!="") {
\r
608 newvmnetipsJson["interface-route-prefix"] = vm.field6;
\r
610 newVMnetips.push(newvmnetipsJson);
\r
613 rawJson["vm-net-ips"] = newVMnetips;
\r
614 puts("rawJson for vm-net-ips");
\r
615 putd(rawJson["vm-net-ips"]);
\r
618 function processVMnetmacs() {
\r
619 // For each VM type, for each network role, get the set of MACs
\r
620 puts("Processing VM-net-macs");
\r
621 var newVMnetmacs = [];
\r
622 csvVMnetworkMACs.forEach( function(vm) {
\r
623 var newvmnetmacsJson = {};
\r
624 newvmnetmacsJson["vm-type"] = vm.field2;
\r
625 newvmnetmacsJson["network-role"] = vm.field3;
\r
626 newvmnetmacsJson["mac-address"] = vm.field4;
\r
627 newVMnetmacs.push(newvmnetmacsJson);
\r
630 rawJson["vm-net-macs"] = newVMnetmacs;
\r
631 puts("rawJson for vm-net-macs");
\r
632 putd(rawJson["vm-net-macs"]);
\r
635 function processTagValues() {
\r
636 var newTagValues = _.map(csvTagValues, function(x) { return {'vnf-parameter-name': x['field2'],
\r
637 'vnf-parameter-value': x['field3']}; } );
\r
638 rawJson['tag-values'] = newTagValues;
\r
639 puts("Tag-values read:");
\r
640 putd(rawJson['tag-values']);
\r