/*
*
* Copyright 2016 RIFT.IO Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
var request = require('request');
var Promise = require('bluebird');
var rp = require('request-promise');
var utils = require('../../../framework/core/api_utils/utils.js');
var constants = require('../../../framework/core/api_utils/constants.js');
var APIVersion = '/v1';
var _ = require('underscore');
var epa_aggregator = require('./epa_aggregator.js');
var transforms = require('./transforms.js');
var uuid = require('node-uuid');
// Revealing module pattern objects
var Catalog = {};
var Config = {};
var NSR = {};
var VNFR = {};
var VLR = {};
var RIFT = {};
var ComputeTopology = {};
var NetworkTopology = {};
var VDUR = {};
var CloudAccount = {};
var ConfigAgentAccount = {};
var RPC = {};
var SSHkey = {};
// API Configuration Info
var APIConfig = {}
APIConfig.NfviMetrics = ['vcpu', 'memory'];
RPC.executeNSServicePrimitive = function(req) {
var api_server = req.query['api_server'];
return new Promise(function(resolve, reject) {
var jsonData = {
"input": req.body
};
var headers = _.extend({},
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
}
);
request({
url: utils.confdPort(api_server) + APIVersion + '/api/operations/exec-ns-service-primitive',
method: 'POST',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData
}, function(error, response, body) {
if (utils.validateResponse('RPC.executeNSServicePrimitive', error, response, body, resolve, reject)) {
return resolve({
statusCode: response.statusCode,
data: JSON.stringify(response.body)
});
}
})
});
};
RPC.getNSServicePrimitiveValues = function(req) {
var api_server = req.query['api_server'];
// var nsr_id = req.body['nsr_id_ref'];
// var nsConfigPrimitiveName = req.body['name'];
return new Promise(function(resolve, reject) {
var jsonData = {
"input": req.body
};
var headers = _.extend({},
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
}
);
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/operations/get-ns-service-primitive-values',
method: 'POST',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData
}, function(error, response, body) {
if (utils.validateResponse('RPC.getNSServicePrimitiveValues', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: JSON.parse(body)
});
}
});
}).catch(function(error) {
console.log('error getting primitive values');
});
};
RPC.refreshAccountConnectionStatus = function(req) {
var api_server = req.query['api_server'];
var Name = req.params.name;
var Type = req.params.type;
var jsonData = {
input: {}
};
var rpcInfo = {
sdn: {
label: 'sdn-account',
rpc: 'update-sdn-status'
},
config: {
label: 'cfg-agent-account',
rpc: 'update-cfg-agent-status'
},
cloud: {
label: 'cloud-account',
rpc: 'update-cloud-status'
}
}
jsonData.input[rpcInfo[Type].label] = Name;
var headers = _.extend({},
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
}
);
return new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/operations/' + rpcInfo[Type].rpc,
method: 'POST',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData
}, function(error, response, body) {
if (utils.validateResponse('RPC.refreshAccountConnectionStatus', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: body
});
}
});
}).catch(function(error) {
console.log('Error refreshing account info');
});
};
var DataCenters = {};
// Catalog module methods
Catalog.get = function(req) {
var api_server = req.query['api_server'];
var results = {}
return new Promise(function(resolve, reject) {
Promise.all([
rp({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
resolveWithFullResponse: true
}),
rp({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
resolveWithFullResponse: true
}),
rp({
uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
resolveWithFullResponse: true
})
// Not enabled for now
// rp({
// uri: utils.confdPort(api_server) + APIVersion + '/api/config/pnfd-catalog/pnfd?deep',
// method: 'GET',
// headers: _.extend({},
// constants.HTTP_HEADERS.accept.collection,
// {
// 'Authorization': req.get('Authorization')
// }),
// forever: constants.FOREVER_ON,
// rejectUnauthorized: false,
// resolveWithFullResponse: true
// })
]).then(function(result) {
console.log('Resolved all request promises (NSD, VNFD) successfully');
var response = [{
"id": "GUID-1",
"name": "RIFT.ware™ NS Descriptors Catalog",
"short-name": "rift.ware-nsd-cat",
"description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
"vendor": "RIFT.io",
"version": "",
"created-on": "",
"type": "nsd",
"meta": {
"icon-svg": "data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22iso-8859-1%22%3F%3E%0A%3C!--%20Generator%3A%20Adobe%20Illustrator%2018.0.0%2C%20SVG%20Export%20Plug-In%20.%20SVG%20Version%3A%206.00%20Build%200)%20%20--%3E%0A%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%0A%3Csvg%20version%3D%221.1%22%20id%3D%22connection-icon-1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20x%3D%220px%22%20y%3D%220px%22%0A%09%20viewBox%3D%220%200%2050%2050%22%20style%3D%22enable-background%3Anew%200%200%2050%2050%3B%22%20xml%3Aspace%3D%22preserve%22%3E%0A%09%3Cpath%20d%3D%22M15%2030c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2020c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M35%2040c-2.8%200-5-2.2-5-5s2.2-5%205-5%205%202.2%205%205-2.2%205-5%205zm0-8c-1.7%200-3%201.3-3%203s1.3%203%203%203%203-1.3%203-3-1.3-3-3-3z%22%2F%3E%3Cpath%20d%3D%22M19.007%2025.885l12.88%206.44-.895%201.788-12.88-6.44z%22%2F%3E%3Cpath%20d%3D%22M30.993%2015.885l.894%201.79-12.88%206.438-.894-1.79z%22%2F%3E%3C%2Fsvg%3E"
},
"descriptors": []
}, {
"id": "GUID-2",
"name": "RIFT.ware™ VNF Descriptors Catalog",
"short-name": "rift.ware-vnfd-cat",
"description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
"vendor": "RIFT.io",
"version": "",
"created-on": "",
"type": "vnfd",
"meta": {
"icon-svg": "data:image/svg+xml, "
},
"descriptors": []
}, {
"id": "GUID-3",
"name": "RIFT.ware™ PNF Descriptors Catalog",
"short-name": "rift.ware-pnfd-cat",
"description": "RIFT.ware™, an open source NFV development and deployment software platform that makes it simple to create, deploy and manage hyper-scale Virtual network functions and applications.",
"vendor": "RIFT.io",
"version": "",
"created-on": "",
"type": "pnfd",
"meta": {
"icon-svg": "data:image/svg+xml, "
},
"descriptors": []
}];
var vnfdCatalog = null;
var vnfdDict = {};
if (result[1].body) {
vnfdCatalog = JSON.parse(result[1].body).collection['vnfd:vnfd'].map(function(v, i) {
vnfdDict[v.id] = v['short-name'] || v.name;
})
}
if (result[0].body) {
response[0].descriptors = JSON.parse(result[0].body).collection['nsd:nsd'];
if (result[2].body) {
var data = JSON.parse(result[2].body);
if (data && data["nsr:ns-instance-opdata"] && data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"]) {
var nsdRefCountCollection = data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"];
response[0].descriptors.map(function(nsd) {
if (!nsd["meta"]) {
nsd["meta"] = {};
}
if (typeof nsd['meta'] == 'string') {
nsd['meta'] = JSON.parse(nsd['meta']);
}
nsd["meta"]["instance-ref-count"] = _.findWhere(nsdRefCountCollection, {
"nsd-id-ref": nsd.id
})["instance-ref-count"];
nsd["constituent-vnfd"] && nsd["constituent-vnfd"].map(function(v) {
v.name = vnfdDict[v["vnfd-id-ref"]];
})
});
}
}
};
if (result[1].body) {
response[1].descriptors = JSON.parse(result[1].body).collection['vnfd:vnfd'];
};
// if (result[2].body) {
// response[2].descriptors = JSON.parse(result[2].body).collection['pnfd:pnfd'];
// };
resolve({
statusCode: response.statusCode || 200,
data: JSON.stringify(response)
});
}).catch(function(error) {
// Todo: Need better logic than all or nothing.
// Right now even if one of the southbound APIs fails - all fail
var res = {};
console.log('Problem with Catalog.get', error);
res.statusCode = error.statusCode || 500;
res.errorMessage = {
error: 'Failed to get catalogs' + error
};
reject(res);
});
});
};
Catalog.delete = function(req) {
var api_server = req.query['api_server'];
var catalogType = req.params.catalogType;
var id = req.params.id;
console.log('Deleting', catalogType, id, 'from', api_server);
return new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog/' + catalogType + '/' + id,
method: 'DELETE',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('Catalog.delete', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode
});
}
});
});
};
Catalog.getVNFD = function(req) {
var api_server = req.query['api_server'];
var vnfdID = req.body.data;
var authorization = req.get('Authorization');
var VNFDs = [];
if (typeof(vnfdID) == "object" && vnfdID.constructor.name == "Array") {
vnfdID.map(function(id) {
VNFDs.push(requestVNFD(id));
});
} else {
VNFDs.push(requestVNFD(vnfdID));
}
return new Promise(function(resolve, reject) {
Promise.all(VNFDs).then(function(data) {
resolve(data)
}).catch(function(error) {
// Todo: Need better logic than all or nothing.
// Right now even if one of the southbound APIs fails - all fail
var res = {};
console.log('Problem with Catalog.getVNFD', error);
res.statusCode = 404;
res.errorMessage = {
error: 'Failed to get VNFDs' + error
};
reject(res);
});
});
function requestVNFD(id) {
return new Promise(function(resolve, reject) {
var url = utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd' + (id ? '/' + id : '') + '?deep';
request({
uri: url,
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': authorization
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('Catalog.getVNFD', error, response, body, resolve, reject)) {
var data;
//Is this still needed?
try {
data = JSON.parse(response.body)
} catch (e) {
reject({
statusCode: response ? response.statusCode : 400,
errorMessage: 'Issue parsing VNFD ' + id + 'from ' + utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd/' + id + '?deep'
});
}
resolve(data);
}
});
});
}
};
Catalog.create = function(req) {
var api_server = req.query['api_server'];
var catalogType = req.params.catalogType;
var data = req.body;
console.log('Creating', catalogType, 'on', api_server);
var jsonData = {};
jsonData[catalogType] = [];
jsonData[catalogType].push(data);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog',
method: 'POST',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData
}, function(error, response, body) {
if (utils.validateResponse('Catalog.create', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode
});
}
});
});
};
Catalog.update = function(req) {
var api_server = req.query['api_server'];
var catalogType = req.params.catalogType;
var id = req.params.id;
var data = req.body;
console.log('Updating', catalogType, 'id', id, 'on', api_server);
var jsonData = {};
jsonData[catalogType] = {};
jsonData[catalogType] = data;
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog' + '/' + catalogType + '/' + id,
method: 'PUT',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData
}, function(error, response, body) {
if (utils.validateResponse('Catalog.update', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode
});
}
});
});
};
Catalog.decorateNsdCatalogWithPlacementGroups = function decorateNsdCatalogWithPlacementGroups(catalog) {
var newData = catalog;
var parsedCatalog = JSON.parse(catalog.data);
var nsds = parsedCatalog[0].descriptors;
var vnfds = parsedCatalog[1].descriptors;
var vnfdDict = (function(){
var dict = {};
vnfds.map(function(v, i) {
dict[v.id] = v;
})
return dict;
})(vnfds);
nsds.map(function(c, i) {
//Rename and decorate NSD placement groups
c['ns-placement-groups'] = c['placement-groups'] && c['placement-groups'].map(function(p, i) {
//Adds vnfd name to member-vnfd entry
p['member-vnfd'] = p['member-vnfd'].map(function(v) {
v.name = vnfdDict[v['vnfd-id-ref']].name;
return v;
});
p['host-aggregate'] = [];
return p;
});
//Adds vnf placement groups to nsd object for UI
c['vnf-placement-groups'] = [];
c['constituent-vnfd'] && c['constituent-vnfd'].map(function(v) {
var vnf = vnfdDict[v['vnfd-id-ref']];
// var vnfPg = {
// name: vnf.name,
// 'placement-groups': vnf['placement-groups'].map(function(vp){
// vp['host-aggregate'] = [{}];
// return vp;
// })
// };
v['vnf-name'] = vnf.name;
vnf['placement-groups'] && vnf['placement-groups'].map(function(vp) {
vp['host-aggregate'] = [];
vp['vnf-name'] = vnf.name;
vp['vnfd-id-ref'] = v['vnfd-id-ref'];
vp['member-vnf-index'] = v['member-vnf-index'];
c['vnf-placement-groups'].push(vp);
})
})
return c;
})
// parsedCatalog[0].descriptors = nsds;
newData.data = JSON.stringify(parsedCatalog);
return newData;
}
// NSR module methods
// Spend some time refactoring this
// refactor to accept only request object
NSR.get = function(req) {
var self = this;
var nsrPromises = [];
var api_server = req.query["api_server"];
var id = req.params.id;
var nsdInfo = new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('NSR.get nsd-catalog', error, response, body, resolve, reject)) {
var data;
var isString = typeof(response.body) == "string";
if (isString && response.body == '') return resolve('empty');
data = isString ? JSON.parse(response.body) : response.body;
var nsdData = data.collection["nsd:nsd"];
if (nsdData.constructor.name == "Object") {
nsdData = [nsdData];
}
resolve(nsdData);
};
})
})
var config = new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-config/nsr' + (id ? '/' + id : '') + '?deep',
method: 'GET',
headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('NSR.get ns-instance-config', error, response, body, resolve, reject)) {
var data;
var isString = typeof(response.body) == "string";
if (isString && response.body == '') return resolve();
data = isString ? JSON.parse(response.body) : response.body;
data = id ? data : data.collection;
var nsrData = data["nsr:nsr"];
if (nsrData.constructor.name == "Object") {
nsrData = [nsrData];
}
resolve(nsrData);
};
});
});
var opData = new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr' + (id ? '/' + id : '') + '?deep',
method: 'GET',
headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('NSR.get ns-instance-opdata', error, response, body, resolve, reject)) {
var data;
var isString = typeof(response.body) == "string";
if (isString && response.body == '') return resolve();
data = isString ? JSON.parse(response.body) : response.body;
data = id ? data : data.collection;
var nsrData = data["nsr:nsr"];
if (nsrData.constructor.name == "Object") {
nsrData = [nsrData];
}
nsrData.forEach(self.decorateWithScalingGroupDict);
nsrData.forEach(self.decorateAndTransformNFVI);
nsrData.forEach(self.decorateAndTransformWithControls);
Promise.all(self.addVnfrDataPromise(req, nsrData)).then(function() {
Promise.all(self.addVlrDataPromise(req, nsrData)).then(function() {
resolve(nsrData);
});
});
};
});
}).catch(function(error) {
console.log('error getting aggregated NS opdata', error)
//note this will actually trigger the success callback
});
return new Promise(function(resolve, reject) {
//Need smarter error handling here
Promise.all([config, opData]).then(function(resolves) {
var aggregate = {};
// resolves[0] ==> ns-instance-config
// resolves[1] ==> ns-instance-opdata
var nsInstanceConfig = resolves[0] && resolves[0];
var nsInstanceOpdata = resolves[1] && resolves[1];
if (!nsInstanceConfig && !nsInstanceOpdata) {
return resolve({
nsrs: []
});
}
nsInstanceConfig.forEach(function(v, k) {
v.nsd_name = v['nsd'] && v['nsd']['name'];
var scaling_group_descriptor = null;
scaling_group_descriptor = v['nsd'] && v['nsd']['scaling-group-descriptor'];
if (scaling_group_descriptor) {
scaling_group_descriptor.map(function(sgd, sgdi) {
sgd['vnfd-member'] && sgd['vnfd-member'].map(function(vnfd, vnfdi) {
var vnfrObj = _.findWhere(_.findWhere(nsInstanceOpdata, {
'ns-instance-config-ref': v.id
}).vnfrs, {
'member-vnf-index-ref': vnfd['member-vnf-index-ref']
});
if (vnfrObj) {
vnfd['short-name'] = vnfrObj['short-name'];
}
})
})
v['scaling-group-descriptor'] = scaling_group_descriptor;
}
if (nsInstanceOpdata && nsInstanceOpdata.constructor.name == "Array") {
nsInstanceOpdata.forEach(function(w, l) {
if (v.id == w["ns-instance-config-ref"]) {
for (prop in w) {
if (prop != "ns-instance-config-ref" && !v.hasOwnProperty(prop)) {
v[prop] = w[prop];
}
}
}
});
}
v['scaling-group-record'] && v['scaling-group-record'].map(function(sgr) {
var scalingGroupName = sgr['scaling-group-name-ref'];
sgr['instance'] && sgr['instance'].map(function(instance) {
var scalingGroupInstanceId = instance['instance-id'];
instance['vnfrs'] && instance['vnfrs'].map(function(vnfr) {
var vnfrObj = _.findWhere(v['vnfrs'], {id: vnfr});
if (vnfrObj) {
vnfrObj['scaling-group-name'] = scalingGroupName;
vnfrObj['scaling-group-instance-id'] = scalingGroupInstanceId;
}
});
});
})
});
var nsrsData = nsInstanceConfig;
nsrsData.sort(function(a, b) {
return a["create-time"] - b["create-time"];
});
resolve({
nsrs: nsrsData
});
}).catch(function(error) {
reject({
statusCode: 404,
errorMessage: error
})
})
});
};
// Static VNFR Cache bu VNFR ID
var staticVNFRCache = {};
/**
* [decorateWithScalingGroupDict description]
* @param {[type]} nsr [description]
* @return {[type]}
{vnfr-id} : {
"scaling-group-name-ref": "sg1",
"instance-id": 0,
"op-status": "running",
"is-default": "true",
"create-time": 1463593760,
"config-status": "configuring",
"vnfrs": [
"432154e3-164e-4c05-83ee-3b56e4c898e7"
]
}
*/
NSR.decorateWithScalingGroupDict = function(nsr) {
var sg = nsr["scaling-group-record"];
var dict = {};
if(sg) {
sg.map(function(s) {
var sgRef = s['scaling-group-name-ref'];
s.instance && s.instance.map(function(si) {
si.vnfrs && si.vnfrs.map(function(v) {
dict[v] = si;
dict[v]["scaling-group-name-ref"] = sgRef;
})
})
})
}
return nsr['vnfr-scaling-groups'] = dict;
}
NSR.addVlrDataPromise = function(req, nsrs) {
var api_server = req.query['api_server'];
var promises = [];
nsrs.map(function(nsr) {
var vlrPromises = [];
var vlr = nsr['vlr'];
nsr['decorated-vlrs'] = [];
if (!vlr) {
console.log('No VL\'s found in NS');
}
vlr && vlr.map(function(vlrObject) {
req.params.id = vlrObject['vlr-ref'];
var vlrPromise = VLR.get(req).then(function(vlr) {
try {
var vlrItem = vlr['data'][0];
decorateNSRWithVLR(nsr, vlrObject, vlrItem);
} catch (e) {
console.log('Expection caught getting VLRs and adding to NSR:', e);
}
})
vlrPromises.push(vlrPromise);
});
var NSR_Promise = new Promise(function(resolve, reject) {
Promise.all(vlrPromises).then(function() {
resolve();
})
});
promises.push(NSR_Promise);
});
return promises;
function decorateNSRWithVLR(nsr, nsrVLRObject, vlr) {
var vlrObject = _.extend(nsrVLRObject, vlr);
vlrObject['vnfr-connection-point-ref'] && vlrObject['vnfr-connection-point-ref'].map(function(vnfrCP) {
var vnfrName = nsr['vnfrs'] && _.find(nsr['vnfrs'], {id: vnfrCP['vnfr-id']})['name'];
vnfrName && (vnfrCP['vnfr-name'] = vnfrName);
});
nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'name'), 0, vlrObject);
// nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'create-time'), 0, vlrObject);
}
}
NSR.addVnfrDataPromise = function(req, nsrs) {
var api_server = req.query['api_server'];
var promises = [];
nsrs.map(function(nsr) {
var epa_params = {};
var constituent_vnfr_ref = nsr["constituent-vnfr-ref"];
var vnfrPromises = [];
nsr["vnfrs"] = [];
nsr["dashboard-urls"] = [];
nsr['nfvi-metrics'] = [];
if (!constituent_vnfr_ref) {
console.log('Something is wrong, there are no constituent-vnfr-refs');
constituent_vnfr_ref = [];
}
//Get VNFR Static Data
constituent_vnfr_ref && constituent_vnfr_ref.map(function(constituentVnfrObj) {
req.params.id = constituentVnfrObj['vnfr-id'];
var vnfrPromise;
vnfrPromise = VNFR.get(req).then(function(vnfr) {
try {
var vnfrItem = vnfr[0];
decorateNSRWithVNFR(nsr, vnfrItem)
staticVNFRCache[vnfrItem.id] = vnfrItem;
} catch (e) {
console.log('Exception caught:', e);
}
});
vnfrPromises.push(vnfrPromise);
});
var NSR_Promise = new Promise(function(resolve, reject) {
Promise.all(vnfrPromises).then(function() {
var vnfrs = staticVNFRCache;
//Aggregate EPA Params
constituent_vnfr_ref && constituent_vnfr_ref.map(function(k) {
if (vnfrs[k['vnfr-id']]) {
epa_params = epa_aggregator(vnfrs[k['vnfr-id']].vdur, epa_params);
}
})
//Add VNFR Name to monitoring params
try {
if (nsr["monitoring-param"]) {
nsr["monitoring-param"].map(function(m) {
var vnfr = vnfrs[m["vnfr-id"]] || {};
m["vnfr-name"] = vnfr['name'] ? vnfr['name'] : (vnfr['short-name'] ? vnfr['short-name'] : 'VNFR');
});
}
} catch (e) {
console.log('Exception caught:', e);
}
resolve();
})
})
nsr["epa-params"] = epa_params;
promises.push(NSR_Promise);
})
return promises;
function decorateNSRWithVDURConsoleUrls(nsr, vnfr) {
nsr['console-urls'] = nsr['console-urls'] ? nsr['console-urls'] : [];
vnfr && vnfr['vdur'] && vnfr['vdur'].map(function(vdur) {
// This console-url is what front-end will hit to generate a real console-url
vdur['console-url'] = 'api/vnfr/' + vnfr.id + '/vdur/' + vdur.id + '/console-url';
nsr['console-urls'].push({
id: vdur.id,
name: vnfr.name,
'console-url': vdur['console-url']
});
});
}
function decorateNSRWithVNFR(nsr, vnfr) {
var vnfrObj = {
id: vnfr.id,
"member-vnf-index-ref": vnfr["member-vnf-index-ref"],
"short-name": vnfr["short-name"],
"vnf-configuration": vnfr["vnf-configuration"],
"nsr-id": nsr['ns-instance-config-ref'],
"name": vnfr['name'],
"vdur": vnfr["vdur"],
"cloud-account": vnfr["cloud-account"]
};
var vnfrSg = nsr['vnfr-scaling-groups'];
var vnfrName = vnfr["name"];
if(vnfrSg) {
if(vnfrSg[vnfr.id]) {
vnfrName = vnfrSg[vnfr.id]["scaling-group-name-ref"] + ':' + vnfrSg[vnfr.id][ "instance-id"] + ':' + vnfrName;
}
}
var vnfrNfviMetrics = buildNfviGraphs(vnfr.vdur, vnfrName);
if (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) {
vnfrObj['service-primitives-present'] = true;
} else {
vnfrObj['service-primitives-present'] = false;
}
transforms.mergeVnfrNfviMetrics(vnfrNfviMetrics, nsr["nfvi-metrics"]);
//TODO: Should be sorted by create-time when it becomes available instead of id
// nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'create-time'), 0, vnfrObj);
nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'id'), 0, vnfrObj);
vnfrObj["dashboard-url"] = vnfr["dashboard-url"];
nsr["dashboard-urls"].push(vnfrObj);
decorateNSRWithVDURConsoleUrls(nsr, vnfr);
}
}
NSR.create = function(req) {
var api_server = req.query['api_server'];
var data = req.body.data;
console.log('Instantiating NSR on ', api_server);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config',
method: 'POST',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: data
}, function(error, response, body) {
if (utils.validateResponse('NSR.create', error, response, body, resolve, reject)) {
var nsr_id = null;
try {
nsr_id = data.nsr[0].id;
} catch (e) {
console.log("NSR.create unable to get nsr_id. Error: %s",
e.toString());
}
resolve({
statusCode: response.statusCode,
data: { nsr_id: nsr_id }
});
};
});
});
};
NSR.delete = function(req) {
var api_server = req.query["api_server"];
var id = req.params.id;
if (!id || !api_server) {
return new Promise(function(resolve, reject) {
console.log('Must specifiy api_server and id to delete NSR');
return reject({
statusCode: 500,
errorMessage: {
error: 'Must specifiy api_server and id to delete NSR'
}
});
});
};
console.log('Deleting NSR with id: ' + id + 'on server: ' + api_server);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id,
method: 'DELETE',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('NSR.delete', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: JSON.stringify(response.body)
});
};
});
});
};
NSR.decorateAndTransformNFVI = function(nsr) {
var toDecorate = [];
// var metricsToUse = ["vcpu", "memory", "storage", "network"];
var metricsToUse = ["vcpu", "memory"];
try {
var nfviMetrics = nsr["rw-nsr:nfvi-metrics"];
if (nfviMetrics) {
metricsToUse.map(function(name) {
toDecorate.push(nfviMetrics[name])
});
}
nsr["nfvi-metrics"] = toDecorate;
delete nsr["rw-nsr:nfvi-metrics"];
} catch (e) {}
return nsr;
}
//Not a great pattern, Need a better way of handling logging;
//Refactor and move to the logging/logging.js
var logCache = {
decorateAndTransformWithControls: {}
}
NSR.decorateAndTransformWithControls = function(nsr) {
var controlTypes = ["action-param", "control-param"];
var nsControls = [];
var Groups = {};
controlTypes.map(function(control) {
try {
var controls = nsr["rw-nsr:" + control];
// nsControls.push(controls);
controls.map(function(item) {
if (!Groups[item["group-tag"]]) {
Groups[item["group-tag"]] = {};
Groups[item["group-tag"]]["action-param"] = []
Groups[item["group-tag"]]["control-param"] = []
}
Groups[item["group-tag"]][control].push(item);
});
delete nsr["rw-nsr:" + control];
} catch (e) {
var id = nsr["ns-instance-config-ref"];
if (!logCache.decorateAndTransformWithControls[id]) {
logCache.decorateAndTransformWithControls[id] = {};
}
var log = logCache.decorateAndTransformWithControls[id];
if (!log[control]) {
log[control] = true;
console.log('No controls exist for ' + control + ' at ' + nsr["ns-instance-config-ref"]);
}
}
});
for (k in Groups) {
var obj = {}
obj[k] = Groups[k];
nsControls.push(obj)
}
nsr.nsControls = nsControls;
return nsr;
};
NSR.setStatus = function(req) {
var api_server = req.query['api_server'];
var id = req.params.id;
var status = req.body.status;
console.log('Setting NSR (id: ' + id + ') status, on ' + api_server + ', to be: ' + status);
return new Promise(function(resolve, reject) {
var command;
if (typeof(status) != "string") {
reject({
'ERROR': 'NSR.setStatus Error: status is not a string type'
});
}
command = status.toUpperCase();
if (command != "ENABLED" && command != "DISABLED") {
reject({
'ERROR': 'NSR.setStatus Error: status is: ' + command + '. It should be ENABLED or DISABLED'
});
}
var requestHeaders = {};
_.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/admin-status/',
method: 'PUT',
headers: requestHeaders,
json: {
"nsr:admin-status": command
},
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('NSR.setStatus', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode
});
};
});
});
};
NSR.createScalingGroupInstance = function(req) {
var api_server = req.query['api_server'];
var id = req.params.id;
var scaling_group_id = req.params.scaling_group_id;
if (!api_server || !id || !scaling_group_id) {
return new Promise(function(resolve, reject) {
return reject({
statusCode: 500,
errorMessage: {
error: 'API server/NSR id/Scaling group not provided'
}
});
});
}
var instance_id = Math.floor(Math.random() * 65535);
var jsonData = {
instance: [{
// id: uuid.v1()
id: instance_id
}]
};
console.log('Creating scaling group instance for NSR ', id, ', scaling group ', scaling_group_id, ' with instance id ', instance_id);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data,
{
'Authorization': req.get('Authorization')
}
);
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/scaling-group/' + scaling_group_id + '/instance',
method: 'POST',
headers: requestHeaders,
json: jsonData,
forever: constants.FOREVER_ON,
rejectUnauthorized: false
}, function (error, response, body) {
if (utils.validateResponse('NSR.createScalingGroupInstance', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
})
}
});
});
};
NSR.deleteScalingGroupInstance = function(req) {
var api_server=req.query['api_server'];
var id = req.params.id;
var scaling_group_id = req.params.scaling_group_id;
var scaling_instance_id = req.params.scaling_instance_id;
if (!api_server || !id || !scaling_group_id || !scaling_instance_id) {
return new Promise(function(resolve, reject) {
return reject({
statusCode: 500,
errorMessage: {
error: 'API server/NSR id/Scaling group/Scaling instance id not provided'
}
});
});
}
console.log('Deleting scaling group instance id ', scaling_instance_id,
' for scaling group ', scaling_group_id,
', under NSR ', id);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data,
{
'Authorization': req.get('Authorization')
}
);
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/scaling-group/' + scaling_group_id + '/instance/' + scaling_instance_id,
method: 'DELETE',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false
}, function (error, response, body) {
if (utils.validateResponse('NSR.deleteScalingGroupInstance', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
})
}
});
});
};
NSR.nsd = {};
NSR.nsd.vld = {};
NSR.nsd.vld.get = function(req) {
var api_server = req.query['api_server'];
var nsr_id = req.params.nsr_id;
var vld_id = req.params.vld_id;
if (!api_server || !nsr_id) {
return new Promise(function(resolve, reject) {
return reject({
statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
errorMessage: 'API server/NSR id not provided'
});
})
}
console.log('Getting VLD', vld_id ? (' ' + vld_id) : ('\'s'), ' for NSR id', nsr_id);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
vld_id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection,
{
'Authorization': req.get('Authorization')
}
);
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld' + (vld_id ? '/' + vld_id : '') +'?deep',
method: 'GET',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false
}, function (error, response, body) {
if (utils.validateResponse('NSR.nsd.vld.get', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
});
}
});
});
};
NSR.nsd.vld.create = function(req) {
var api_server = req.query['api_server'];
var nsr_id = req.params.nsr_id;
var vld_id = req.params.vld_id;
var data = req.body;
if (!api_server || !nsr_id) {
return new Promise(function(resolve, reject) {
return reject({
statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
errorMessage: 'API server/NSR id not provided'
});
});
}
console.log((vld_id ? 'Updating VLD ' + vld_id : 'Creating VLD') + ' under NSR', nsr_id);
var jsonData = {
vld: typeof(data) == 'string' ? JSON.parse(data) : data
};
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
uri: utils.confdPort(api_server) + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld' + (vld_id ? '/' + vld_id : ''),
method: vld_id ? 'PUT' : 'POST',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData
}, function(error, response, body) {
if (utils.validateResponse('NSR.nsd.vld.create/update', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: (typeof(response.body) == 'string') ? JSON.parse(response.body) : response.body
});
}
});
});
};
NSR.nsd.vld.update = NSR.nsd.vld.create;
NSR.nsd.vld.delete = function(req) {
var api_server = req.query['api_server'];
var nsr_id = req.params.nsr_id;
var vld_id = req.params.vld_id;
if (!api_server || !nsr_id || !vld_id) {
return new Promise(function(resolve, reject) {
return reject({
statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
errorMessage: 'API server/NSR id/VLD id not provided'
});
})
}
console.log('Deleting VLD', vld_id, 'for NSR id', nsr_id);
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data,
{
'Authorization': req.get('Authorization')
}
);
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld/' + vld_id,
method: 'DELETE',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false
}, function (error, response, body) {
if (utils.validateResponse('NSR.nsd.vld.delete', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode,
data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
});
}
});
});
}
VNFR.get = function(req) {
var api_server = req.query["api_server"];
var id = req.params.id;
var uri = utils.confdPort(api_server);
uri += APIVersion + '/api/operational/vnfr-catalog/vnfr' + (id ? '/' + id : '') + '?deep';
var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('VNFR.get', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
var returnData = id ? [data["vnfr:vnfr"]] : data.collection["vnfr:vnfr"];
returnData.forEach(function(vnfr) {
vnfr['nfvi-metrics'] = buildNfviGraphs(vnfr.vdur);
vnfr['epa-params'] = epa_aggregator(vnfr.vdur);
vnfr['service-primitives-present'] = (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) ? true : false;
vnfr['vdur'] && vnfr['vdur'].map(function(vdur, vdurIndex) {
// This console-url is what front-end will hit to generate a real console-url
vdur['console-url'] = 'api/vnfr/' + vnfr.id + '/vdur/' + vdur.id + '/console-url';
});
});
return resolve(returnData);
};
});
});
}
function buildNfviGraphs(VDURs, vnfrName){
var temp = {};
var toReturn = [];
APIConfig.NfviMetrics.map(function(k) {
VDURs && VDURs.map(function(v,i) {
//Check for RIFT-12699: VDUR NFVI Metrics not fully populated
if (v["rw-vnfr:nfvi-metrics"] && v["rw-vnfr:nfvi-metrics"][k] && v["rw-vnfr:nfvi-metrics"][k].hasOwnProperty('utilization')) {
if(!temp[k]) {
temp[k] = {
title: '',
data: []
};
};
try {
var data = v["rw-vnfr:nfvi-metrics"][k];
var newData = {};
newData.name = v.name ? v.name : v.id.substring(0,6);
newData.name = vnfrName ? vnfrName + ': ' + newData.name : newData.name;
newData.id = v.id;
//converts to perentage
newData.utilization = data.utilization * 0.01;
temp[k].data.push(newData);
temp[k].title = v["rw-vnfr:nfvi-metrics"][k].label;
} catch (e) {
console.log('Something went wrong with the VNFR NFVI Metrics. Check that the data is being properly returned. ERROR: ', e);
}
}
});
if(temp[k]) {
toReturn.push(temp[k]);
}
});
return toReturn;
}
//Cache NSR reference for VNFR
VNFR.cachedNSR = {};
VNFR.getByNSR = function(req) {
var api_server = req.query["api_server"];
var id = req.params.nsr_id;
var uri = utils.confdPort(api_server);
var reqClone = _.clone(req);
delete reqClone.params.id;
uri += APIVersion + '/api/operational/ns-instance-opdata/nsr/' + id + '?deep';
var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
if (VNFR.cachedNSR[id]) {
var data = VNFR.cachedNSR[id];
var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
VNFR.get(reqClone).then(function(vnfrData) {
resolve(filterVnfrByList(vnfrList, vnfrData));
});
} else {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('VNFR.getByNSR', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
data = data["nsr:nsr"];
//Cache NSR data with NSR-ID as
VNFR.cachedNSR[id] = data;
var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
var returnData = [];
VNFR.get(reqClone).then(function(vnfrData) {
resolve(filterVnfrByList(vnfrList, vnfrData));
});
};
});
}
});
};
function filterVnfrByList(vnfrList, vnfrData) {
return vnfrData.map(function(vnfr) {
if (vnfrList.indexOf(vnfr.id) > -1) {
return vnfr;
}
})
};
VLR.get = function(req) {
var api_server = req.query["api_server"];
var id = req.params.id;
var uri = utils.confdPort(api_server);
uri += APIVersion + '/api/operational/vlr-catalog/vlr' + (id ? '/' + id : '') + '?deep';
var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('VLR.get', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
var returnData = id ? [data["vlr:vlr"]] : data.collection["vlr:vlr"];
return resolve({
data: returnData,
statusCode: response.statusCode
});
};
});
});
}
RIFT.api = function(req) {
var api_server = req.query["api_server"];
var uri = utils.confdPort(api_server);
var url = req.path;
return new Promise(function(resolve, reject) {
request({
url: uri + url + '?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('RIFT.api', error, response, body, resolve, reject)) {
resolve(JSON.parse(response.body))
};
})
})
};
ComputeTopology.get = function(req) {
var api_server = req.query['api_server'];
var nsr_id = req.params.id;
var result = {
id: nsr_id, // node id
name: nsr_id, // node name to display
parameters: {}, // the parameters that can be used to determine size/color, etc. for the node
type: 'nsr',
children: [] // children for the node
};
return new Promise(function(resolve, reject) {
var nsrPromise = new Promise(function(success, failure) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr/' + nsr_id + '?deep',
method: 'GET',
headers: _.extend({},
constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('ComputeTopology.get ns-instance-opdata/nsr/:id', error, response, body, success, failure)) {
var data;
var isString = typeof(response.body) == "string";
if (isString && response.body == '') {
return success({});
}
try {
data = isString ? JSON.parse(response.body) : response.body;
var nsrNFVIMetricData = data["nsr:nsr"]["rw-nsr:nfvi-metrics"];
result.parameters = nsrNFVIMetricData;
result.name = data["nsr:nsr"]["name-ref"];
var nsrData = data["nsr:nsr"]["constituent-vnfr-ref"];
success(nsrData);
} catch (e) {
console.log('Error parsing ns-instance-opdata for NSR ID', nsr_id, 'Exception:', e);
return failure()
}
};
});
}).then(function(data) {
try {
// got NSR data
// now get VNFR data and populate the structure
var vnfrPromises = [];
// Run separately to confirm that primary structure is populated before promise resolution takes over
// and starts modifying the data
data.forEach(function(vnfrObj) {
var vnfrId = vnfrObj['vnfr-id'];
// If anything needs to be added to result for each vnfrId, do it here
vnfrPromises.push(
new Promise(function(success, failure) {
rp({
uri: utils.confdPort(api_server) + APIVersion + '/api/operational/vnfr-catalog/vnfr/' + vnfrId + '?deep',
method: 'GET',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
resolveWithFullResponse: true
}, function(error, response, body) {
if (utils.validateResponse('ComputeTopology.get vnfr-catalaog/vnfr/:id', error, response, body, success, failure)) {
try {
var data = JSON.parse(response.body);
var returnData = data["vnfr:vnfr"];
// Push VNFRs in result
result.children.push({
id: vnfrId,
name: returnData.name,
parameters: {}, // nfvi metrics here
children: [],
type: 'vnfr'
});
// Push VDURs in result
returnData.vdur.forEach(function(vdur) {
result.children[result.children.length - 1].children.push({
id: vdur.id,
name: vdur.id,
parameters: {},
type: 'vdur'
// children: []
});
});
return success(returnData.vdur);
} catch (e) {
console.log('Error parsing vnfr-catalog for VNFR ID', vnfrId, 'Exception:', e);
return failure();
}
};
});
})
);
});
Promise.all(vnfrPromises).then(function(output) {
console.log('Resolved all VNFR requests successfully');
// By now result must be completely populated. output is moot
// Sort the results as there's no order to them from RIFT-REST
result.children.sort(sortByName);
result.children.forEach(function(vnfr) {
vnfr.children.sort(sortByName);
});
resolve({
statusCode: 200,
data: result
});
}).catch(function(error) {
// Todo: Can this be made better?
// Right now if one of the southbound APIs fails - we just return what's populated so far in result
console.log('Problem with ComputeTopology.get vnfr-catalog/vnfr/:id', error, 'Resolving with partial data', result);
resolve({
statusCode: 200,
data: result
});
});
} catch (e) {
// API came back with empty ns-instance-opdata response for NSR ID
// bail
console.log('Error iterating through ns-instance-opdata response for NSR ID', nsr_id, 'Exception:', e);
resolve({
statusCode: 200,
data: result
})
}
}, function(error) {
// failed to get NSR data.
// bail
resolve({
statusCode: 200,
data: result
});
});
});
};
NetworkTopology.get = function(req) {
var api_server = req.query["api_server"];
var uri = utils.confdPort(api_server);
uri += APIVersion + '/api/operational/network?deep';
var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false
}, function(error, response, body) {
if (utils.validateResponse('NetworkTopology.get', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
var returnData = transforms.transformNetworkTopology(
data["ietf-network:network"]
);
resolve({
statusCode: 200,
data: returnData
});
};
});
})
}
VDUR.get = function(req) {
var api_server = req.query["api_server"];
var vnfrID = req.params.vnfr_id;
var vdurID = req.params.vdur_id;
var uri = utils.confdPort(api_server);
uri += APIVersion + '/api/operational/vnfr-catalog/vnfr/' + vnfrID + '/vdur/' + vdurID + '?deep';
var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('VDUR.get', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
var returnData = data["vdur:vdur"];
return resolve(returnData);
};
});
})
}
VDUR.consoleUrl = {};
VDUR.consoleUrl.get = function(req) {
var api_server = req.query["api_server"];
var vnfrID = req.params.vnfr_id;
var vdurID = req.params.vdur_id;
var uri = utils.confdPort(api_server);
uri += APIVersion + '/api/operational/vnfr-console/vnfr/' + vnfrID + '/vdur/' + vdurID + '/console-url' + '?deep';
var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('VDUR.consoleUrl.get', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
var returnData = data;
return resolve({
data: returnData,
statusCode: response.statusCode
});
};
});
})
}
CloudAccount.get = function(req) {
var api_server = req.query["api_server"];
var uri = utils.confdPort(api_server);
uri += APIVersion + '/api/operational/cloud/account?deep';
var headers = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
});
return new Promise(function(resolve, reject) {
request({
url: uri,
method: 'GET',
headers: headers,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('CloudAccount.get', error, response, body, resolve, reject)) {
var data = JSON.parse(response.body);
var returnData = data["collection"]["rw-cloud:account"];
resolve({
statusCode: 200,
data: returnData
});
};
});
});
}
// Config-Agent Account APIs
ConfigAgentAccount.get = function(req) {
var self = this;
var api_server = req.query["api_server"];
var id = req.params.id;
if (!id) {
// Get all config accounts
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.collection, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account',
type: 'GET',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
},
function(error, response, body) {
var data;
var statusCode;
if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
try {
data = JSON.parse(response.body).collection['rw-config-agent:account'];
statusCode = response.statusCode;
} catch (e) {
console.log('Problem with "ConfigAgentAccount.get"', e);
var err = {};
err.statusCode = 500;
err.errorMessage = {
error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
}
return reject(err);
}
return resolve({
statusCode: statusCode,
data: data
});
};
});
});
} else {
//Get a specific config account
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account/' + id,
type: 'GET',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
},
function(error, response, body) {
var data;
var statusCode;
if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
try {
data = JSON.parse(response.body)['rw-config-agent:account'];
statusCode = response.statusCode;
} catch (e) {
console.log('Problem with "ConfigAgentAccount.get"', e);
var err = {};
err.statusCode = 500;
err.errorMessage = {
error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
}
return reject(err);
}
return resolve({
statusCode: statusCode,
data: data
});
}
});
});
}
};
ConfigAgentAccount.create = function(req) {
var api_server = req.query["api_server"];
var data = req.body;
return new Promise(function(resolve, reject) {
var jsonData = {
"account": Array.isArray(data) ? data : [data]
};
console.log('Creating with', JSON.stringify(jsonData));
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/config/config-agent',
method: 'POST',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData,
}, function(error, response, body) {
if (utils.validateResponse('ConfigAgentAccount.create', error, response, body, resolve, reject)) {
return resolve({
statusCode: response.statusCode,
data: JSON.stringify(response.body),
body:response.body.body
});
};
});
});
};
ConfigAgentAccount.update = function(req) {
var api_server = req.query["api_server"];
var id = req.params.id;
var data = req.body;
return new Promise(function(resolve, reject) {
var jsonData = {
"rw-config-agent:account": data
};
console.log('Updating config-agent', id, ' with', JSON.stringify(jsonData));
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data,
constants.HTTP_HEADERS.content_type.data, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + id,
method: 'PUT',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
json: jsonData,
}, function(error, response, body) {
if (utils.validateResponse('ConfigAgentAccount.update', error, response, body, resolve, reject)) {
return resolve({
statusCode: response.statusCode,
data: JSON.stringify(response.body)
});
};
});
});
};
ConfigAgentAccount.delete = function(req) {
var api_server = req.query["api_server"];
var id = req.params.id;
if (!id || !api_server) {
return new Promise(function(resolve, reject) {
console.log('Must specifiy api_server and id to delete config-agent account');
return reject({
statusCode: 500,
errorMessage: {
error: 'Must specifiy api_server and id to delete config agent account'
}
});
});
};
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + id,
method: 'DELETE',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('ConfigAgentAccount.delete', error, response, body, resolve, reject)) {
return resolve({
statusCode: response.statusCode,
data: JSON.stringify(response.body)
});
};
});
});
};
DataCenters.get = function(req) {
var api_server = req.query["api_server"];
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/operational/datacenters?deep',
method: 'GET',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('DataCenters.get', error, response, body, resolve, reject)) {
var returnData = {};
try {
data = JSON.parse(response.body)["rw-launchpad:datacenters"]["ro-accounts"];
data.map(function(c) {
returnData[c.name] = c.datacenters;
})
statusCode = response.statusCode;
} catch (e) {
console.log('Problem with "DataCenters.get"', e);
var err = {};
err.statusCode = 500;
err.errorMessage = {
error: 'Problem with "DataCenters.get": ' + e.toString()
}
return reject(err);
}
return resolve({
statusCode: response.statusCode,
data: returnData
});
};
});
});
}
SSHkey.get = function(req) {
var api_server = req.query["api_server"];
return new Promise(function(resolve, reject) {
var requestHeaders = {};
_.extend(requestHeaders,
constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
});
request({
url: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair?deep',
method: 'GET',
headers: requestHeaders,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('SSHkey.get', error, response, body, resolve, reject)) {
var returnData = {};
try {
returnData = JSON.parse(response.body)['nsr:key-pair'];
statusCode = response.statusCode;
} catch (e) {
console.log('Problem with "SSHkey.get"', e);
var err = {};
err.statusCode = 500;
err.errorMessage = {
error: 'Problem with "SSHkey.get": ' + e.toString()
}
return reject(err);
}
return resolve({
statusCode: response.statusCode,
data: returnData
});
};
});
});
}
SSHkey.delete = function(req) {
var api_server = req.query['api_server'];
var id = decodeURI(req.params.name);
console.log('Deleting ssk-key', id);
return new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/' + id,
method: 'DELETE',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('SSHkey.delete', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode
});
}
});
});
};
SSHkey.post = function(req) {
var api_server = req.query['api_server'];
var data = req.body;
return new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/',
method: 'POST',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
json: data,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('SSHkey.post', error, response, body, resolve, reject)) {
resolve({
data: 'success',
statusCode: response.statusCode
});
}
});
});
};
SSHkey.put = function(req) {
var api_server = req.query['api_server'];
var data = req.body;
return new Promise(function(resolve, reject) {
request({
uri: utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/',
method: 'PUT',
headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
'Authorization': req.get('Authorization')
}),
json: data,
forever: constants.FOREVER_ON,
rejectUnauthorized: false,
}, function(error, response, body) {
if (utils.validateResponse('SSHkey.put', error, response, body, resolve, reject)) {
resolve({
statusCode: response.statusCode
});
}
});
});
};
function sortByName(a, b) {
return a.name > b.name;
}
module.exports.catalog = Catalog;
module.exports.nsr = NSR;
module.exports.vnfr = VNFR;
module.exports.vlr = VLR;
module.exports.vdur = VDUR;
module.exports.rift = RIFT;
module.exports.computeTopology = ComputeTopology;
module.exports.networkTopology = NetworkTopology;
module.exports.config = Config;
module.exports.cloud_account = CloudAccount;
module.exports['config-agent-account'] = ConfigAgentAccount;
module.exports.rpc = RPC;
module.exports.data_centers = DataCenters;
module.exports.SSHkey = SSHkey;