fixing security issues found in onap admportal
[sdnc/oam.git] / admportal / server / router / routes / mobility.js
1 var express = require('express');
2 var router = express.Router();
3 var exec = require('child_process').exec;
4 var util = require('util');
5 var fs = require('fs.extra');
6 var dbRoutes = require('./dbRoutes');
7 var csp = require('./csp');
8 var multer = require('multer');
9 var cookieParser = require('cookie-parser');
10 var bodyParser = require('body-parser');
11 var sax = require('sax'),strict=true,parser = sax.parser(strict);
12 var async = require('async');
13 var l_ = require('lodash');
14 var dateFormat = require('dateformat');
15 var properties = require(process.env.SDNC_CONFIG_DIR + '/admportal.json');
16 var crypto = require('crypto');
17 var csrf = require('csurf');
18
19 var csrfProtection = csrf({cookie: true});
20 router.use(cookieParser())
21
22 // pass host, username and password to ODL
23 // target host for ODL request
24 var username = properties.odlUser;
25 var password = properties.odlPasswd;
26 var auth = 'Basic ' + new Buffer(username + ':' + password).toString('base64');
27 var host = properties.odlHost;
28 var port = properties.odlPort;
29
30 var header = {'Host': host, 'Authorization': auth, 'Content-Type': 'application/json'};
31 var options = {
32         host    : host,
33         headers : header,
34         port    : port,
35         rejectUnauthorized:false,
36         strictSSL: false
37 };
38
39 // Connection to OpenDaylight
40 OdlInterface = require('./OdlInterface');
41
42 // used for file upload button, retain original file name
43 //router.use(bodyParser());
44 //router.use(bodyParser.urlencoded({
45   //extended: true
46 //}));
47
48 //var upload = multer({ dest: process.cwd() + '/uploads/', rename: function(fieldname,filename){ return filename; } });
49
50 // multer 1.1
51 var storage = multer.diskStorage({
52   destination: function (req, file, cb) {
53     cb(null, process.cwd() + '/uploads/')
54   },
55   filename: function (req, file, cb) {
56     cb(null, file.originalname )
57   }
58 });
59
60 var upload = multer({
61     storage: storage
62 });
63
64
65 // GET
66 router.get('/getVnfData', csp.checkAuth, csrfProtection, function(req,res) {
67         dbRoutes.getVnfData(req,res, {code:'', msg:''}, req.session.loggedInAdmin);
68 });
69 router.get('/getVnfNetworkData', csp.checkAuth, csrfProtection, function(req,res) {
70         dbRoutes.getVnfNetworkData(req,res, {code:'', msg:''}, req.session.loggedInAdmin);
71 });
72 router.get('/getVnfProfile', csp.checkAuth, csrfProtection, function(req,res) {
73         dbRoutes.getVnfProfile(req,res, {code:'', msg:''}, req.session.loggedInAdmin);
74 });
75 //router.get('/getVmNetworks', csp.checkAuth, function(req,res) {
76 //      dbRoutes.getVmNetworks(req,res, {code:'', msg:''}, req.session.loggedInAdmin);
77 //});
78 //router.get('/getVnfNetworks', csp.checkAuth, function(req,res) {
79 //      dbRoutes.getVnfNetworks(req,res, {code:'', msg:''}, req.session.loggedInAdmin);
80 //});
81 //router.get('/getVmProfile', csp.checkAuth, function(req,res) {
82 //      dbRoutes.getVmProfile(req,res, {code:'', msg:''}, req.session.loggedInAdmin);
83 //});
84 ////////
85
86 router.get('/viewVnfNetworkData', csp.checkAuth, csrfProtection, function(req,res)
87 {
88     var privilegeObj = req.session.loggedInAdmin;
89     var resp_msg = '';
90     var network_name = req.query.network_name;
91     var network_type = req.query.network_type;
92     var tasks = [];
93
94     tasks.push(function(callback){
95                 OdlInterface.GetPreloadVnfData('/restconf/config/VNF-API:preload-vnfs/vnf-preload-list/'
96             + encodeURIComponent(network_name) + '/' + encodeURIComponent(network_type) + '/', options,res,callback);
97
98     });
99     async.series(tasks, function(err,result)
100     {
101         var msgArray = new Array();
102         if(err){
103             resp_msg = err;
104             res.render('mobility/displayVnfNetworkData', {result:{code:'failure', msg:resp_msg}, header:process.env.MAIN_MENU});
105             return;
106         }
107         else{
108             resp_msg = JSON.stringify(JSON.parse(result[0],null,4));
109             res.render('mobility/displayVnfNetworkData', {result:{code:'success', msg:JSON.parse(result[0])}, header:process.env.MAIN_MENU});
110             return;
111         }
112     });
113
114 });
115
116 router.get('/viewVnfData', csp.checkAuth, csrfProtection, function(req,res) 
117 {
118     var privilegeObj = req.session.loggedInAdmin;
119     var resp_msg = '';
120         var vnf_name = req.query.vnf_name;
121         var vnf_type = req.query.vnf_type;
122         var tasks = [];
123
124         tasks.push(function(callback){
125                 OdlInterface.GetPreloadVnfData('/restconf/config/VNF-API:preload-vnfs/vnf-preload-list/'
126                         + encodeURIComponent(vnf_name) + '/' + encodeURIComponent(vnf_type) + '/', options,res,callback);
127
128         });
129         async.series(tasks, function(err,result)
130     {
131         var msgArray = new Array();
132         if(err){
133             resp_msg = err;
134                         res.render('mobility/displayVnfData', {result:{code:'failure', msg:resp_msg}, header:process.env.MAIN_MENU});
135             return;
136         }
137         else{
138                         resp_msg = JSON.stringify(JSON.parse(result[0],null,4));
139                         res.render('mobility/displayVnfData', {result:{code:'success', msg:JSON.parse(result[0])}, header:process.env.MAIN_MENU});
140             return;
141         }
142     });
143
144 });
145
146 router.get('/loadVnfNetworkData', csp.checkAuth, csp.checkPriv, function(req,res)
147 {
148         var privilegeObj = req.session.loggedInAdmin;
149         var msgArray = new Array();
150
151         if ( req.query.status != 'pending' )
152         {
153                 msgArray.push("Upload Status must be in 'pending' state.");
154                 dbRoutes.getVnfNetworkData(req,res, {code:'failure', msg:msgArray}, privilegeObj);
155                 return;
156         }
157
158         // build request-id
159         var now = new Date();
160         var df = dateFormat(now,"isoDateTime");
161         const rnum = crypto.randomBytes(4);
162         var svc_req_id = req.query.id + "-" + df + "-" + rnum.toString('hex');;
163         var tasks = [];
164
165         // first get the contents of the file from the db
166         tasks.push(function(callback){
167                 dbRoutes.getVnfPreloadData(req,res,"PRE_LOAD_VNF_NETWORK_DATA",callback);
168         });
169
170         // then format the request and send it using the arg1 parameter
171         // which is the contents of the file returned from the previous function
172         // call in the tasks array
173         tasks.push(function(arg1,callback){
174
175                 var s_file = JSON.stringify(arg1);
176
177                 // remove the last two braces, going to add the headers there
178                 // will add them back later.
179                 s_file = s_file.substring(0, (s_file.length-2));
180
181                 // add the request-information header
182                 s_file = s_file.concat(',"request-information": {"request-action": "PreloadNetworkRequest"}');
183
184                 // add the sdnc-request-header
185                 s_file = s_file.concat(',"sdnc-request-header": {"svc-request-id":"');
186                 s_file = s_file.concat(svc_req_id);
187                 s_file = s_file.concat('","svc-action": "reserve"}');
188
189                 // add the two curly braces at the end that we stripped off
190                 s_file = s_file.concat('}}');
191
192                 OdlInterface.Post('/restconf/operations/VNF-API:preload-network-topology-operation', 
193                         options,s_file,res,callback);
194         });
195
196         // if successful then update the status
197         tasks.push(function(arg1,callback){
198                 dbRoutes.updatePreloadStatus("UPDATE PRE_LOAD_VNF_NETWORK_DATA SET status='uploaded',svc_request_id='" + svc_req_id + "',svc_action='reserve'",req,res,callback);
199         });
200
201         // use the waterfall method of making calls
202         async.waterfall(tasks, function(err,result)
203         {
204                 var msgArray = new Array();
205                 if(err){
206                         msgArray.push("Error posting pre-load data to ODL: "+err);
207                         dbRoutes.getVnfNetworkData(req,res, {code:'failure', msg:msgArray}, privilegeObj);
208                         return;
209                 }
210                 else{
211                         msgArray.push('Successfully loaded VNF pre-loaded data.');
212                         dbRoutes.getVnfNetworkData(req,res,{code:'success', msg:msgArray},privilegeObj);
213                         return;
214                 }
215         });
216 });
217
218
219 router.get('/loadVnfData', csp.checkAuth, csp.checkPriv, function(req,res) 
220 {
221         var privilegeObj = req.session.loggedInAdmin;
222         var full_path_file_name = process.cwd() + "/uploads/" + req.sanitize(req.query.filename)
223   var msgArray = new Array();
224
225         if ( req.query.status != 'pending' )
226         {
227                 msgArray.push("Upload Status must be in 'pending' state.");
228                 dbRoutes.getVnfData(req,res, {code:'failure', msg:msgArray}, privilegeObj);
229                 return;
230         }
231
232         // build request-id
233         var now = new Date();
234         var df = dateFormat(now,"isoDateTime");
235         const rnum = crypto.randomBytes(4);
236         var svc_req_id = req.sanitize(req.query.id) + "-" + df + "-" + rnum.toString('hex');
237         var tasks = [];
238
239         // first get the contents of the file from the db
240         tasks.push(function(callback){
241                 dbRoutes.getVnfPreloadData(req,res,"PRE_LOAD_VNF_DATA",callback);
242   });
243
244         // then format the request and send it using the arg1 parameter
245         // which is the contents of the file returned from the previous function
246         // call in the tasks array
247         tasks.push(function(arg1,callback){
248
249                 var s1_file = JSON.stringify(arg1);
250                 var s_file = decodeURI(s1_file);
251
252
253                 // remove the last two braces, going to add the headers there
254         // will add them back later.
255     s_file = s_file.substring(0, (s_file.length-2));
256
257                 // add the request-information header
258                 s_file = s_file.concat(',"request-information": {"request-action": "PreloadVNFRequest"}');
259
260                 // add the sdnc-request-header
261                 s_file = s_file.concat(',"sdnc-request-header": {"svc-request-id":"');
262                 s_file = s_file.concat(svc_req_id);
263                 s_file = s_file.concat('","svc-action": "reserve"}');
264
265                 // add the two curly braces at the end that we stripped off
266                 s_file = s_file.concat('}}');
267
268                 OdlInterface.Post('/restconf/operations/VNF-API:preload-vnf-topology-operation',
269                         options,s_file,res,callback);
270         });
271
272         // if successful then update the status
273         tasks.push(function(arg1,callback){
274                 dbRoutes.executeSQL("UPDATE PRE_LOAD_VNF_DATA SET status='uploaded',svc_request_id='" + svc_req_id + "',svc_action='reserve'",req,res,callback);
275         });
276
277         // use the waterfall method of making calls
278         async.waterfall(tasks, function(err,result)
279         {
280                 var msgArray = new Array();
281                 if(err){
282                         msgArray.push("Error posting pre-load data to ODL: "+err);
283       dbRoutes.getVnfData(req,res, {code:'failure', msg:msgArray}, privilegeObj);
284       return;
285                 }
286                 else{
287                         msgArray.push('Successfully loaded VNF pre-loaded data.');
288       dbRoutes.getVnfData(req,res,{code:'success', msg:msgArray},privilegeObj);
289       return;
290     }
291         });
292 });
293
294
295 router.get('/deleteVnfNetworkData', csp.checkAuth, csp.checkPriv, csrfProtection,  function(req,res) {
296
297     var privilegeObj = req.session.loggedInAdmin;
298     var tasks = [];
299
300     // if status is pending, then we do not have to call
301     // ODL, just remove from db
302     if (req.query.status == 'pending'){
303         tasks.push(function(callback) {
304             dbRoutes.deleteVnfNetworkData(req,res,callback);
305         });
306     } else {
307                 // format the request to ODL
308         var inputString = '{"input":{"network-topology-information":{"network-topology-identifier":{"service-type":"SDN-MOBILITY","network-name": "';
309         inputString = inputString.concat(req.query.network_name);
310         inputString = inputString.concat('","network-type":"');
311         inputString = inputString.concat(req.query.network_type);
312         inputString = inputString.concat('"}},');
313
314         // add the request-information header
315         inputString = inputString.concat('"request-information": {"request-action": "DeletePreloadNetworkRequest"},');
316
317                 // add the sdnc-request-header
318                 inputString = inputString.concat('"sdnc-request-header": {"svc-request-id":"');
319                 inputString = inputString.concat(req.query.svc_request_id);
320                 inputString = inputString.concat('","svc-action": "delete"}}}');
321         
322         tasks.push(function(callback) {
323             OdlInterface.Post('/restconf/operations/VNF-API:preload-network-topology-operation',
324                     options,inputString,res,callback);
325         });
326         tasks.push(function(callback) {
327             dbRoutes.executeSQL(sql,req,res,callback);
328         });
329     }
330     async.series(tasks, function(err,result){
331
332         var msgArray = new Array();
333         if(err){
334             msgArray.push(err);
335             dbRoutes.getVnfNetworkData(req,res,{code:'failure', msg:msgArray},privilegeObj);
336             return;
337         }
338         else {
339             msgArray.push('Row successfully deleted from PRE_LOAD_VNF_NETWORK_DATA table and ODL.');
340             dbRoutes.getVnfNetworkData(req,res,{code:'success', msg:msgArray},privilegeObj);
341             return;
342         }
343     });
344 });
345
346
347 router.get('/deleteVnfData', csp.checkAuth, csp.checkPriv, csrfProtection, function(req,res) {
348
349     var privilegeObj = req.session.loggedInAdmin;
350     var tasks = [];
351
352     // if status is pending, then we do not have to call
353     // ODL, just remove from db
354     if (req.query.status == 'pending'){
355         tasks.push(function(callback) {
356             dbRoutes.deleteVnfData(req,res,callback);
357         });
358     } else {
359                         var inputString = '{"input":{"vnf-topology-information":{"vnf-topology-identifier":{"service-type":"SDN-MOBILITY","vnf-name": "';
360                         inputString = inputString.concat(req.query.vnf_name);
361                         inputString = inputString.concat('","vnf-type":"');
362                         inputString = inputString.concat(req.query.vnf_type);
363                         inputString = inputString.concat('"}},');
364                 
365       // add the request-information header
366       inputString = inputString.concat('"request-information": {"request-action": "DeletePreloadVNFRequest"},');
367
368         // add the request-information header
369         //inputString = inputString.concat('"request-information": {"request-id": "259c0f93-23cf-46ad-84dc-162ea234fff1",');
370                 //inputString = inputString.concat('"source": "ADMINPORTAL",');
371                 //inputString = inputString.concat('"order-version": "1",');
372                 //inputString = inputString.concat('"notification-url": "notused-this would be infrastructure portal",');
373                 //inputString = inputString.concat('"order-number": "1",');
374                 //inputString = inputString.concat('"request-action": "DeletePreloadVNFRequest"},');
375
376                 // add the sdnc-request-header
377                 inputString = inputString.concat('"sdnc-request-header": {"svc-request-id":"');
378                 inputString = inputString.concat(req.query.svc_request_id);
379                 inputString = inputString.concat('","svc-action": "delete"}}}');
380
381                 //inputString = inputString.concat('"sdnc-request-header":{');
382                 //inputString = inputString.concat('"svc-request-id": "2015-01-15T14:34:54.st1101a",');
383                 //inputString = inputString.concat('"svc-notification-url": "not used",');
384                 //inputString = inputString.concat('"svc-action": "delete"}}}');
385                 
386         tasks.push(function(callback) {
387                 OdlInterface.Post('/restconf/operations/VNF-API:preload-vnf-topology-operation',
388                     options,inputString,res,callback);
389         });
390         tasks.push(function(callback) {
391             dbRoutes.executeSQL(sql,req,res,callback);
392         });
393     }
394     async.series(tasks, function(err,result){
395
396         var msgArray = new Array();
397         if(err){
398             msgArray.push(err);
399             dbRoutes.getVnfData(req,res,{code:'failure', msg:msgArray},privilegeObj);
400             return;
401         }
402         else {
403             msgArray.push('Row successfully deleted from PRE_LOAD_VNF_DATA table and ODL.');
404             dbRoutes.getVnfData(req,res,{code:'success', msg:msgArray},privilegeObj);
405             return;
406         }
407     });
408 });
409
410
411 router.get('/deleteVnfNetwork', csp.checkAuth, csp.checkPriv, csrfProtection, function(req,res) {
412
413     var privilegeObj = req.session.loggedInAdmin;
414     var tasks = [];
415     var sql = '';
416
417     sql = "DELETE FROM VNF_NETWORKS WHERE vnf_type='" + req.query.vnf_type + "'"
418                 + " AND network_role='" + req.query.network_role + "'";
419
420     tasks.push(function(callback) {
421         dbRoutes.executeSQL(sql,req,res,callback);
422     });
423     async.series(tasks, function(err,result)
424     {
425         var msgArray = new Array();
426         if(err){
427             msgArray.push(err);
428             dbRoutes.getVnfNetwork(req,res,{code:'failure', msg:msgArray},privilegeObj);
429             return;
430         }
431         else {
432             msgArray.push('Row successfully deleted from VNF_NETWORKS table.');
433             dbRoutes.getVnfNetworks(req,res,{code:'success', msg:msgArray},privilegeObj);
434             return;
435         }
436     });
437 });
438
439 router.get('/deleteVnfProfile', csp.checkAuth, csp.checkPriv, csrfProtection, function(req,res) {
440
441     var privilegeObj = req.session.loggedInAdmin;
442     var tasks = [];
443     var sql = '';
444
445
446     tasks.push(function(callback) {
447         dbRoutes.deleteVnfProfile(req,res,callback);
448     });
449     async.series(tasks, function(err,result)
450     {
451         var msgArray = new Array();
452         if(err){
453             msgArray.push(err);
454             dbRoutes.getVnfProfile(req,res,{code:'failure', msg:msgArray},privilegeObj);
455             return;
456         }
457         else {
458             msgArray.push('Row successfully deleted from VNF_PROFILE table.');
459             dbRoutes.getVnfProfile(req,res,{code:'success', msg:msgArray},privilegeObj);
460             return;
461         }
462     });
463 });
464
465 // POST
466 router.post('/addVnfProfile', csp.checkAuth, csp.checkPriv, csrfProtection, function(req,res){
467
468   var privilegeObj = req.session.loggedInAdmin;
469         var vnf_type = req.sanitize(req.body.nf_vnf_type);
470         var availability_zone_count = req.sanitize(req.body.nf_availability_zone_count);
471   var equipment_role = req.sanitize(req.body.nf_equipment_role);
472   var tasks = [];
473         var sql;
474
475   sql = "INSERT INTO VNF_PROFILE (vnf_type,availability_zone_count,equipment_role) VALUES ("
476         + "'" + vnf_type + "'," + availability_zone_count + ",'" + equipment_role + "')"; 
477
478 console.log(sql);
479
480         tasks.push( function(callback) { dbRoutes.executeSQL(sql,req,res,callback); } );
481         async.series(tasks, function(err,result){
482                 var msgArray = new Array();
483                 if(err){
484                         msgArray.push(err);
485                         dbRoutes.getVnfProfile(req,res,{code:'failure', msg:msgArray},privilegeObj);
486                         return;
487                 }
488                 else {
489                         msgArray.push('Successfully added VNF Profile');
490                         dbRoutes.getVnfProfile(req,res,{code:'success', msg:msgArray},privilegeObj);
491                         return;
492                 }
493         });
494 });
495
496 // POST
497 router.post('/uploadVnfData', csp.checkAuth, csp.checkPriv, upload.single('filename'), function(req, res)
498 {
499 console.log('filename:'+ JSON.stringify(req.file.originalname));
500     var msgArray = new Array();
501     var privilegeObj = req.session.loggedInAdmin;
502
503     if(req.file.originalname)
504         {
505         if (req.file.originalname.size == 0) {
506                         msgArray.push('There was an error uploading the file.');
507             dbRoutes.getVnfData(req,res,{code:'failure', msg:msgArray},privilegeObj);
508             return;
509         }
510         fs.exists(req.file.path, function(exists) 
511                 {
512             if(exists) 
513                         {
514                 var str = req.file.originalname;
515                                 var content;
516                 var enc_content;
517                         
518                                 try{
519                     content = fs.readFileSync(req.file.path);
520                     enc_content = encodeURI(content);
521
522
523                     var sql = "INSERT INTO PRE_LOAD_VNF_DATA "
524                         + "(filename,preload_data) VALUES ("
525                         + "'"+ str + "'," + "'" + enc_content + "')";
526
527                         var privilegeObj = req.session.loggedInAdmin;
528                         var tasks = [];
529                         tasks.push( function(callback) { dbRoutes.addRow(sql,req,res,callback); } );
530                         async.series(tasks, function(err,result)
531                         {
532                         if(err){
533                                 msgArray.push(err);
534                                 dbRoutes.getVnfData(req,res,{code:'failure', msg:msgArray},privilegeObj);
535                                 return;
536                         }
537                         else {
538                                 msgArray.push('Successfully uploaded ' + str);
539                                 dbRoutes.getVnfData(req,res,{code:'success', msg:msgArray},privilegeObj);
540                                 return;
541                         }
542                         });
543                                 }
544                                 catch(error){
545                                                 fs.removeSync(req.file.path); // remove bad file that was uploaded
546                                                 console.error("There was an error reading the file '"+str+"'. Error: " + error);
547                                                 msgArray.push("There was an error reading the file '"+str+"'. Error: " + error);
548                                 dbRoutes.getVnfData(req,res,{code:'failure', msg:msgArray},privilegeObj);
549                                 return;
550                                 }
551             } else {
552                 msgArray.length = 0;
553                 msgArray.push('There was an error uploading the file.');
554                 dbRoutes.getVnfData(req,res,{code:'danger', msg:msgArray},privilegeObj);
555                 return;
556             }
557         });
558         }
559     else 
560         {
561         msgArray.length = 0;
562         msgArray.push('There was an error uploading the file.');
563         dbRoutes.getVnfData(req,res,{code:'danger', msg:msgArray},privilegeObj);
564         return;
565     }
566
567 } );
568
569 router.post('/uploadVnfNetworkData', csp.checkAuth, csp.checkPriv, upload.single('filename'), function(req, res)
570 {
571     var msgArray = new Array();
572     var privilegeObj = req.session.loggedInAdmin;
573
574     if(req.file.originalname)
575     {
576         if (req.file.originalname.size == 0) {
577             msgArray.push('There was an error uploading the file.');
578             dbRoutes.getVnfData(req,res,{code:'failure', msg:msgArray},privilegeObj);
579             return;
580         }
581         fs.exists(req.file.path, function(exists)
582         {
583             if(exists)
584             {
585                 var str = req.file.originalname;
586                 var content;
587                 var enc_content;
588
589                 try{
590                     content = fs.readFileSync(req.file.path);
591                     enc_content = encodeURI(content);
592
593                     var sql = "INSERT INTO PRE_LOAD_VNF_NETWORK_DATA "
594                         + "(filename,preload_data) VALUES ("
595                         + "'"+ str + "'," + "'" + enc_content + "')";
596
597                     var privilegeObj = req.session.loggedInAdmin;
598                     var tasks = [];
599                     tasks.push( function(callback) { dbRoutes.addRow(sql,req,res,callback); } );
600                     async.series(tasks, function(err,result)
601                     {
602                         if(err){
603                             msgArray.push(err);
604                             dbRoutes.getVnfNetworkData(req,res,{code:'failure', msg:msgArray},privilegeObj);
605                             return;
606                         }
607                         else {
608                             msgArray.push('Successfully uploaded ' + str);
609                             dbRoutes.getVnfNetworkData(req,res,{code:'success', msg:msgArray},privilegeObj);
610                             return;
611                         }
612                     });
613                 }
614                 catch(error){
615                         fs.removeSync(req.file.path); // remove bad file that was uploaded
616                         msgArray.push("There was an error reading the file '"+str+"'. Error: " + error);
617                         dbRoutes.getVnfNetworkData(req,res,{code:'failure', msg:msgArray},privilegeObj);
618                         return;
619                 }
620             } else {
621                 msgArray.length = 0;
622                 msgArray.push('There was an error uploading the file.');
623                 dbRoutes.getVnfNetworkData(req,res,{code:'danger', msg:msgArray},privilegeObj);
624                 return;
625             }
626         });
627     }
628         else
629     {
630         msgArray.length = 0;
631         msgArray.push('There was an error uploading the file.');
632         dbRoutes.getVnfNetworkData(req,res,{code:'danger', msg:msgArray},privilegeObj);
633         return;
634     }
635
636 } );
637
638
639 router.post('/uploadVnfProfile', csp.checkAuth, csp.checkPriv, upload.single('filename'), function(req, res){
640
641     var msgArray = new Array();
642     var privilegeObj = req.session.loggedInAdmin;
643
644     if(req.file.originalname)
645         {
646         if (req.file.originalname.size == 0) {
647             dbRoutes.getVnfProfile(req,res,{code:'failure', msg:'There was an error uploading the file, please try again.'},privilegeObj);
648             return;
649         }
650         fs.exists(req.file.path, function(exists) {
651
652             if(exists) {
653
654                 var str = req.file.originalname;
655
656                 try {
657                     var csv = require('csv');
658
659                     // the job of the parser is to convert a CSV file
660                     // to a list of rows (array of rows)
661                     var parser = csv.parse({
662                         columns: function(line) {
663                             // By defining this callback, we get handed the
664                             // first line of the spreadsheet. Which we'll
665                             // ignore and effectively skip this line from processing
666                         },
667                         skip_empty_lines: true
668                     });
669
670                     var row = 0;
671                     var f = new Array();
672                     var transformer = csv.transform(function(data){
673                         // this will get row by row data, so for example,
674                         //logger.debug(data[0]+','+data[1]+','+data[2]);
675
676                         // build an array of rows
677                         f[row] = new Array();
678                         for ( col=0; col<data.length; col++ )
679                         {
680                             f[row][col] = data[col];
681                         }
682                         row++;
683                     });
684
685                     // called when done with processing the CSV
686                     transformer.on("finish", function() {
687
688                         var funcArray = new Array();
689
690                         function createFunction(lrow,res)
691                         {
692                             return function(callback) { dbRoutes.addVnfProfile(lrow,res,callback); }
693                         }
694                         // loop for each row and create an array of callbacks for async.parallelLimit
695                         // had to create a function above 'createFunction' to get
696                         for (var x=0; x<f.length; x++)
697                         {
698                             funcArray.push( createFunction(f[x],res) );
699                         }
700
701                         // make db calls in parrallel
702                         async.series(funcArray, function(err,result){
703
704                             if ( err ) {
705                                 dbRoutes.getVnfProfile(req,res,result,privilegeObj);
706                                 return;
707                             }
708                             else {
709                                 // result array has an entry in it, success entries are blank, figure out
710                                 // how many are not blank, aka errors.
711                                 var rowError = 0;
712                                 for(var i=0;i<result.length;i++){
713                                     if ( result[i].length > 0 )
714                                     {
715                                         rowError++;
716                                     }
717                                 }
718 console.log('rowError='+rowError);
719                                 var rowsProcessed = f.length - rowError;
720 console.log('rowsProcessed='+rowsProcessed);
721                                 result.push(rowsProcessed + ' of ' + f.length + ' rows processed.');
722                                 if ( rowError > 0 )
723                                 {
724                                     result = {code:'failure', msg:result};
725                                 }
726                                 else
727                                 {
728                                     result = {code:'success', msg:result};
729                                 }
730 console.log('result='+JSON.stringify(result));
731                                 dbRoutes.getVnfProfile(req,res,result,privilegeObj);
732                                 return;
733                             }
734                         });
735                     });
736
737                     var stream = fs.createReadStream(req.file.path, "utf8");
738                     stream.pipe(parser).pipe(transformer);
739
740                 } catch(ex) {
741                     msgArray.length = 0;
742                     msgArray.push('There was an error uploading the file. '+ex);
743                     console.error('There was an error uploading the file. '+ex);
744                     dbRoutes.getVnfProfile(req,res,{code:'danger', msg:msgArray},privilegeObj);
745                     return;
746                 }
747             } else {
748                 msgArray.length = 0;
749                 msgArray.push('There was an error uploading the file.');
750                 dbRoutes.getVnfProfile(req,res,{code:'danger', msg:msgArray},privilegeObj);
751                 return;
752             }
753         });
754         }
755     else {
756         msgArray.length = 0;
757         msgArray.push('There was an error uploading the file.');
758         dbRoutes.getVnfProfile(req,res,{code:'danger', msg:msgArray},privilegeObj);
759         return;
760     }
761 } );
762
763 module.exports = router;