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
25 puts = helpers.puts;
\r
26 putd = helpers.putd;
\r
28 vnf.go = function(lreq,lres,cb,dir){
\r
29 puts("Processing VNF workbook");
\r
38 indir=process.cwd() + "/uploads/";
\r
44 // READ WORKSHEET: GENERAL
\r
46 function doGeneral() {
\r
47 puts("Reading General worksheet");
\r
48 var csvFilename="General.csv";
\r
49 var newFileName = helpers.getFileName(req, csvFilename);
\r
50 if ( newFileName != null ) {
\r
51 helpers.readCsv(indir, newFileName, gotGeneral);
\r
54 callback(csvFilename + ' file is missing from upload.');
\r
58 function gotGeneral(err, jsonObj) {
\r
62 callback('General.csv file is missing from upload.');
\r
65 csvGeneral = jsonObj;
\r
66 puts("\nRead this: ");
\r
72 // READ WORKSHEET: AVAILABILITY ZONES
\r
74 function doAvailZones() {
\r
75 puts("Reading Availability-zones worksheet");
\r
76 var csvFilename="Availability-zones.csv";
\r
77 var newFileName = helpers.getFileName(req, csvFilename);
\r
78 if ( newFileName != null ) {
\r
79 helpers.readCsv(indir, newFileName, gotAvailZones);
\r
82 callback(csvFilename + ' file is missing from upload.');
\r
86 function gotAvailZones(err, jsonObj) {
\r
90 callback('Availability-zones.csv file is missing from upload.');
\r
94 csvZones = _.reject(csvZones, 'field2', 'Availability Zones');
\r
95 csvZones = _.reject(csvZones, 'field2', 'List the availability zones for this VNF');
\r
96 csvZones = _.reject(csvZones, 'field2', '');
\r
97 puts("\nRead this: ");
\r
103 // READ WORKSHEET: NETWORKS
\r
105 function doNetworks() {
\r
106 puts("Reading Networks worksheet");
\r
107 var csvFilename="Networks.csv";
\r
108 var newFileName = helpers.getFileName(req, csvFilename);
\r
109 if ( newFileName != null ) {
\r
110 helpers.readCsv(indir, newFileName, gotNetworks);
\r
113 callback(csvFilename + ' file is missing from upload.');
\r
117 function gotNetworks(err, jsonObj) {
\r
121 callback('Networks.csv file is missing from upload.');
\r
124 csvNetworks = jsonObj;
\r
125 csvNetworks = _.reject(csvNetworks, 'field2', 'Networks');
\r
126 csvNetworks = _.reject(csvNetworks, 'field2', 'List the VNF networks. (VM-networks are on a different worksheet.)');
\r
127 csvNetworks = _.reject(csvNetworks, 'field2', 'network-role');
\r
128 csvNetworks = _.reject(csvNetworks, 'field2', '');
\r
129 puts("\nRead this: ");
\r
135 // READ WORKSHEET: VMs
\r
138 puts("Reading VMs worksheet");
\r
139 var csvFilename="VMs.csv";
\r
140 var newFileName = helpers.getFileName(req, csvFilename);
\r
141 if ( newFileName != null ) {
\r
142 helpers.readCsv(indir, newFileName, gotVMs);
\r
145 callback(csvFilename + ' file is missing from upload.');
\r
149 function gotVMs(err, jsonObj) {
\r
153 callback('VMs.csv file is missing from upload.');
\r
157 csvVMs = _.reject(csvVMs, 'field2', 'VMs');
\r
158 csvVMs = _.reject(csvVMs, 'field2', 'List the VM types for this VNF');
\r
159 csvVMs = _.reject(csvVMs, 'field2', 'vm-type');
\r
160 csvVMs = _.reject(csvVMs, 'field2', '');
\r
161 puts("\nRead this: ");
\r
167 // READ WORKSHEET: VM-NETWORKS
\r
169 function doVMnetworks() {
\r
170 puts("Reading VM-networks worksheet");
\r
171 var csvFilename="VM-networks.csv";
\r
172 var newFileName = helpers.getFileName(req, csvFilename);
\r
173 if ( newFileName != null ) {
\r
174 helpers.readCsv(indir, newFileName, gotVMnetworks);
\r
177 callback(csvFilename + ' file is missing from upload.');
\r
181 function gotVMnetworks(err, jsonObj) {
\r
185 callback('VM-networks.csv file is missing from upload.');
\r
188 csvVMnetworks = jsonObj;
\r
189 csvVMnetworks = _.reject(csvVMnetworks, 'field2', 'VM-networks');
\r
190 csvVMnetworks = _.reject(csvVMnetworks, 'field2', 'List the VM-networks for each VM type');
\r
191 csvVMnetworks = _.reject(csvVMnetworks, 'field2', 'vm-type');
\r
192 csvVMnetworks = _.reject(csvVMnetworks, 'field2', '');
\r
193 puts("\nRead this: ");
\r
194 putd(csvVMnetworks);
\r
199 // READ WORKSHEET: VM-NETWORK-IPS
\r
201 function doVMnetworkIPs() {
\r
202 puts("Reading VM-network-IPs worksheet");
\r
203 var csvFilename="VM-network-IPs.csv";
\r
204 var newFileName = helpers.getFileName(req, csvFilename);
\r
205 if ( newFileName != null ) {
\r
206 helpers.readCsv(indir, newFileName, gotVMnetworkIPs);
\r
209 callback(csvFilename + ' file is missing from upload.');
\r
213 function gotVMnetworkIPs(err, jsonObj) {
\r
217 callback('VM-network-IPs.csv file is missing from upload.');
\r
220 csvVMnetworkIPs = jsonObj;
\r
221 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', 'VM-network-IPs');
\r
222 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', 'List the IPs assigned to each VM-network');
\r
223 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', 'vm-type');
\r
224 csvVMnetworkIPs = _.reject(csvVMnetworkIPs, 'field2', '');
\r
225 puts("\nRead this: ");
\r
226 putd(csvVMnetworkIPs);
\r
231 // READ WORKSHEET: VM-NETWORK-MACS
\r
233 function doVMnetworkMACs() {
\r
234 puts("Reading VM-network-MACs worksheet");
\r
235 var csvFilename="VM-network-MACs.csv";
\r
236 var newFileName = helpers.getFileName(req, csvFilename);
\r
237 if ( newFileName != null ) {
\r
238 helpers.readCsv(indir, newFileName, gotVMnetworkMACs);
\r
241 callback(csvFilename + ' file is missing from upload.');
\r
245 function gotVMnetworkMACs(err, jsonObj) {
\r
249 callback('VM-network-MACs.csv file is missing from upload.');
\r
252 csvVMnetworkMACs = jsonObj;
\r
253 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', 'VM-network-MACs');
\r
254 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', 'List the MACs assigned to each VM-network');
\r
255 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', 'vm-type');
\r
256 csvVMnetworkMACs = _.reject(csvVMnetworkMACs, 'field2', '');
\r
257 puts("\nRead this: ");
\r
258 putd(csvVMnetworkMACs);
\r
263 // READ WORKSHEET: TAG-VALUES
\r
265 function doTagValues() {
\r
266 puts("Reading Tag-values worksheet");
\r
267 var csvFilename="Tag-values.csv";
\r
268 var newFileName = helpers.getFileName(req, csvFilename);
\r
269 if ( newFileName != null ) {
\r
270 helpers.readCsv(indir, newFileName, gotTagValues);
\r
273 callback(csvFilename + ' file is missing from upload.');
\r
277 function gotTagValues(err, jsonObj) {
\r
281 callback('Tag-values.csv file is missing from upload.');
\r
284 csvTagValues = jsonObj;
\r
285 csvTagValues = _.reject(csvTagValues, 'field2', 'Tag-values');
\r
286 csvTagValues = _.reject(csvTagValues, 'field2', 'Extra data to be passed into the HEAT template for this VNF');
\r
287 csvTagValues = _.reject(csvTagValues, 'field2', 'vnf-parameter-name');
\r
288 csvTagValues = _.reject(csvTagValues, 'field2', 'vnf-parameter-value');
\r
289 csvTagValues = _.reject(csvTagValues, 'field2', '');
\r
290 puts("\nRead this: ");
\r
291 putd(csvTagValues);
\r
293 doneReadingFiles();
\r
299 function doneReadingFiles() {
\r
301 puts("DONE READING FILES!");
\r
307 // PROCESS THE CSV FILES INTO OBJECTS TO BE ASSEMBLED INTO FINAL OUTPUT
\r
308 function processJson() {
\r
310 processAvailZones();
\r
312 processVMnetworks();
\r
314 processVMnetmacs();
\r
316 processTagValues();
\r
320 // ASSEMBLE AND OUTPUT RESULTS
\r
322 function assembleJson() {
\r
324 puts("Using raw JSON and assembling final ouptut JSON.");
\r
327 vnfTopoID = { "service-type": "SDN-MOBILITY",
\r
328 "vnf-name": rawJson['vf-module-name'],
\r
329 "vnf-type": rawJson['vf-module-model-name'],
\r
330 "generic-vnf-name": rawJson['generic-vnf-name'],
\r
331 "generic-vnf-type": rawJson['generic-vnf-type'] };
\r
333 vnfZones = rawJson['availability-zones'];
\r
335 vnfNetworks = rawJson['networks'];
\r
337 vnfVMs = rawJson['vms'];
\r
339 vnfParams = rawJson['tag-values'];
\r
341 vnfAssignments = { "availability-zones": vnfZones,
\r
342 "vnf-networks": vnfNetworks,
\r
343 "vnf-vms": vnfVMs};
\r
345 vnfTopo = { "vnf-topology-identifier": vnfTopoID,
\r
346 "vnf-assignments": vnfAssignments,
\r
347 "vnf-parameters": vnfParams };
\r
349 vnfInput = {'vnf-topology-information': vnfTopo};
\r
351 finalJson = {"input": vnfInput};
\r
356 function outputJson() {
\r
359 puts(JSON.stringify(finalJson,null,2));
\r
362 var unixTime, fullpath_filename, filename;
\r
363 unixTime = moment().unix();
\r
364 if (platform=='portal') {
\r
365 fullpath_filename = process.cwd() + "/uploads/" + unixTime + ".vnf_worksheet.json";
\r
366 filename = unixTime + ".vnf_worksheet.json.";
\r
368 fullpath_filename = "./output.json."+unixTime;
\r
369 filename = "output.json." + unixTime;
\r
371 helpers.writeOutput(req, fullpath_filename, JSON.stringify(finalJson,null,2), callback);
\r
372 callback(null, finalJson, filename);
\r
376 // Gather functions that actually process data after it is all read
\r
378 function processGeneral() {
\r
380 preloadVersion = getParam(csvGeneral, 'field2', 'preload-version', 'field3');
\r
381 rawJson['preload-version'] = preloadVersion;
\r
382 puts("Preload version: " + preloadVersion);
\r
384 if ( (preloadVersion!='1607') && (preloadVersion!='1610') ) {
\r
385 puts("\nError - incorrect version of preload worksheet.");
\r
386 callback('Error - incorrect version of preload worksheet.');
\r
389 rawJson['vf-module-name'] = getParam(csvGeneral, 'field2', 'vf-module-name', 'field3');
\r
390 // rawJson['vf-module-type'] = getParam(csvGeneral, 'field2', 'vf-module-type', 'field3');
\r
392 rawJson['vf-module-model-name'] = getParam(csvGeneral, 'field2', 'vf-module-model-name', 'field3');
\r
395 puts("ERROR ERROR ERROR ERROR ERROR\n");
\r
396 puts("Failed to find data field 'vf-module-model-name'. Maybe this preload worksheet is older?")
\r
397 puts("If on the 'general' tab there is a field called 'vf-module-type' please rename it to 'vf-module-model-name'");
\r
401 rawJson['generic-vnf-name'] = getParam(csvGeneral, 'field2', 'vnf-name', 'field3');
\r
402 rawJson['generic-vnf-type'] = getParam(csvGeneral, 'field2', 'vnf-type', 'field3');
\r
403 rawJson['request-id'] = uuid.v1();
\r
404 rawJson['source'] = "ADMINPORTAL";
\r
405 rawJson['request-action'] = "PreloadVNFRequest";
\r
406 rawJson['svc-request-id'] = uuid.v1();
\r
407 rawJson['svc-action'] = "reserve";
\r
413 function processAvailZones() {
\r
414 var newZones = _.map(csvZones, function(x) { return {'availability-zone': x['field2']}; } );
\r
415 rawJson['availability-zones'] = newZones;
\r
416 puts("Availability zones read:");
\r
417 putd(rawJson['availability-zones']);
\r
421 function processNetworks() {
\r
422 var newNetworks = [];
\r
423 csvNetworks.forEach( function(network) {
\r
425 netJson["network-role"] = network.field2;
\r
426 netJson["network-name"] = network.field3;
\r
427 netJson["network-id"] = network.field4;
\r
428 netJson["contrail-network-fqdn"] = network.field5;
\r
429 netJson["subnet-name"] = network.field6;
\r
430 netJson["subnet-id"] = network.field7;
\r
431 netJson["ipv6-subnet-name"] = network.field8;
\r
432 netJson["ipv6-subnet-id"] = network.field9;
\r
433 newNetworks.push(netJson);
\r
438 rawJson["networks"] = newNetworks;
\r
441 function processVMs() {
\r
443 csvVMs.forEach( function(vm) {
\r
445 vmJson["vm-type"] = vm.field2;
\r
446 vmJson["vm-name"] = vm.field3;
\r
447 newVMs.push(vmJson);
\r
454 // OK, now for each type, get count and then build vm-names array of the names
\r
456 vmTypes = _.uniq(_.pluck(newVMs,'vm-type'));
\r
457 vmTypes.forEach( function(vmType) {
\r
464 vmThisType=_.select(newVMs, 'vm-type', vmType);
\r
465 vmCount=vmThisType.length;
\r
466 vmJson["vm-type"] = vmType;
\r
467 vmJson["vm-count"] = vmCount;
\r
468 tmpNames = _.pluck(vmThisType,'vm-name');
\r
469 vmJson["vm-names"] = _.map(tmpNames, function(nam) { return {"vm-name": nam}; } );
\r
470 netroles = _.select( rawJson["vm-networks"], "vm-type", vmType );
\r
472 netroles.forEach( function(netrole) {
\r
473 tmpNetDetails = {};
\r
474 tmpNetDetails["network-role"] = netrole["network-role"];
\r
475 tmpNetDetails["use-dhcp"] = netrole["use-dhcp"];
\r
477 var tmpipsThisVmType=[];
\r
478 tmpipsThisVmType = _.select( rawJson["vm-net-ips"], "vm-type", vmType);
\r
480 tmpips = _.select( tmpipsThisVmType, "network-role", netrole["network-role"]);
\r
481 tmpipsJson = _.map(tmpips, function(ip) { return {"ip-address": ip["ip-address"]} } );
\r
482 tmpipsJson = _.reject(tmpipsJson, function(o) { return (o["ip-address"]==undefined); } );
\r
483 tmpNetDetails["network-ips"] = tmpipsJson;
\r
485 var tmpipsv6ThisVmType=[];
\r
486 tmpipsv6ThisVmType = _.select( rawJson["vm-net-ips"], "vm-type", vmType);
\r
488 tmpipsv6 = _.select( tmpipsv6ThisVmType, "network-role", netrole["network-role"]);
\r
489 tmpipsv6Json = _.map(tmpipsv6, function(ip) { return {"ip-address-ipv6": ip["ipv6-address"]} } );
\r
490 tmpipsv6Json = _.reject(tmpipsv6Json, function(o) { return (o["ip-address-ipv6"]==undefined); } );
\r
491 tmpNetDetails["network-ips-v6"] = tmpipsv6Json;
\r
493 var tmpirpThisVmType=[];
\r
494 tmpirpThisVmType = _.select( rawJson["vm-net-ips"], "vm-type", vmType);
\r
496 tmpirp = _.select( tmpirpThisVmType, "network-role", netrole["network-role"]);
\r
497 tmpirpJson = _.map(tmpirp, function(irp) { return {"interface-route-prefix-cidr": irp["interface-route-prefix"]} } );
\r
498 tmpirpJson = _.reject(tmpirpJson, function(o) { return (o["interface-route-prefix-cidr"]==undefined); } );
\r
499 tmpNetDetails["interface-route-prefixes"] = tmpirpJson;
\r
501 var tmpmacsThisVmType=[];
\r
502 tmpmacsThisVmType = _.select( rawJson["vm-net-macs"], "vm-type", vmType);
\r
504 tmpmacs = _.select( tmpmacsThisVmType, "network-role", netrole["network-role"]);
\r
505 tmpmacsJson = _.map(tmpmacs, function(mac) { return {"mac-address": mac["mac-address"]} } );
\r
506 tmpNetDetails["network-macs"] = tmpmacsJson;
\r
509 fip = netrole["floating-ip"];
\r
512 tmpNetDetails["floating-ip"] = netrole["floating-ip"];
\r
516 fipv6 = netrole["floating-ip-v6"];
\r
517 fipv6 = _.trim(fipv6);
\r
519 tmpNetDetails["floating-ip-v6"] = netrole["floating-ip-v6"];
\r
522 newnetroles.push(tmpNetDetails);
\r
525 vmJson["vm-networks"] = newnetroles;
\r
527 vnfvms.push(vmJson);
\r
530 rawJson["vms"] = vnfvms;
\r
533 function processVMnetworks() {
\r
534 // For each VM type, for each Network role, get details like use-dhcp
\r
535 var newVMnetworks = [];
\r
536 csvVMnetworks.forEach( function(vm) {
\r
537 var newvmJson = {};
\r
538 newvmJson["vm-type"] = vm.field2;
\r
539 newvmJson["network-role"] = vm.field3;
\r
540 newvmJson["use-dhcp"] = vm.field4;
\r
541 newvmJson["floating-ip"] = vm.field5;
\r
542 newvmJson["floating-ip-v6"] = vm.field6;
\r
543 newVMnetworks.push(newvmJson);
\r
546 rawJson["vm-networks"] = newVMnetworks;
\r
547 puts("rawJson for vm-networks...");
\r
548 putd( rawJson["vm-networks"] );
\r
552 function processVMnetips() {
\r
553 // For each VM type, for each network role, get the set of network IPs
\r
554 puts("Processing VM-net-ips");
\r
555 var newVMnetips = [];
\r
556 csvVMnetworkIPs.forEach( function(vm) {
\r
557 var newvmnetipsJson = {};
\r
558 newvmnetipsJson["vm-type"] = vm.field2;
\r
559 newvmnetipsJson["network-role"] = vm.field3;
\r
560 if (_.trim(vm.field4)!="") {
\r
561 newvmnetipsJson["ip-address"] = vm.field4;
\r
563 if (_.trim(vm.field5)!="") {
\r
564 newvmnetipsJson["ipv6-address"] = vm.field5;
\r
566 if (_.trim(vm.field6)!="") {
\r
567 newvmnetipsJson["interface-route-prefix"] = vm.field6;
\r
569 newVMnetips.push(newvmnetipsJson);
\r
572 rawJson["vm-net-ips"] = newVMnetips;
\r
573 puts("rawJson for vm-net-ips");
\r
574 putd(rawJson["vm-net-ips"]);
\r
577 function processVMnetmacs() {
\r
578 // For each VM type, for each network role, get the set of MACs
\r
579 puts("Processing VM-net-macs");
\r
580 var newVMnetmacs = [];
\r
581 csvVMnetworkMACs.forEach( function(vm) {
\r
582 var newvmnetmacsJson = {};
\r
583 newvmnetmacsJson["vm-type"] = vm.field2;
\r
584 newvmnetmacsJson["network-role"] = vm.field3;
\r
585 newvmnetmacsJson["mac-address"] = vm.field4;
\r
586 newVMnetmacs.push(newvmnetmacsJson);
\r
589 rawJson["vm-net-macs"] = newVMnetmacs;
\r
590 puts("rawJson for vm-net-macs");
\r
591 putd(rawJson["vm-net-macs"]);
\r
594 function processTagValues() {
\r
595 var newTagValues = _.map(csvTagValues, function(x) { return {'vnf-parameter-name': x['field2'],
\r
596 'vnf-parameter-value': x['field3']}; } );
\r
597 rawJson['tag-values'] = newTagValues;
\r
598 puts("Tag-values read:");
\r
599 putd(rawJson['tag-values']);
\r