NOTICKET: Merging OSM/master to OSM/projects
[osm/UI.git] / skyquake / plugins / launchpad / api / launchpad.js
1 /*
2 *
3 * Copyright 2016 RIFT.IO Inc
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 var request = require('request');
20 var Promise = require('bluebird');
21 var rp = require('request-promise');
22 var utils = require('../../../framework/core/api_utils/utils.js');
23 var constants = require('../../../framework/core/api_utils/constants.js');
24 var APIVersion = '/v1';
25 var _ = require('underscore');
26 var epa_aggregator = require('./epa_aggregator.js');
27 var transforms = require('./transforms.js');
28 var uuid = require('node-uuid');
29
30 // Revealing module pattern objects
31 var Catalog = {};
32 var Config = {};
33 var NSR = {};
34 var VNFR = {};
35 var VLR = {};
36 var RIFT = {};
37 var ComputeTopology = {};
38 var NetworkTopology = {};
39 var VDUR = {};
40 var CloudAccount = {};
41 var ConfigAgentAccount = {};
42 var RPC = {};
43 var SSHkey = {};
44 // API Configuration Info
45 var APIConfig = {}
46 APIConfig.NfviMetrics = ['vcpu', 'memory'];
47
48 RPC.executeNSServicePrimitive = function(req) {
49 var api_server = req.query['api_server'];
50 return new Promise(function(resolve, reject) {
51 var uri = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operations/exec-ns-service-primitive');
52 var jsonData = {
53 "input": utils.addProjectContextToRPCPayload(req, uri, req.body)
54 };
55
56 var headers = _.extend({},
57 constants.HTTP_HEADERS.accept.data,
58 constants.HTTP_HEADERS.content_type.data, {
59 'Authorization': req.session && req.session.authorization
60 }
61 );
62 request({
63 url: uri,
64 method: 'POST',
65 headers: headers,
66 forever: constants.FOREVER_ON,
67 rejectUnauthorized: false,
68 json: jsonData
69 }, function(error, response, body) {
70 if (utils.validateResponse('RPC.executeNSServicePrimitive', error, response, body, resolve, reject)) {
71 return resolve({
72 statusCode: response.statusCode,
73 data: JSON.stringify(response.body)
74 });
75 }
76 })
77 });
78 };
79
80 RPC.getNSServicePrimitiveValues = function(req) {
81 var api_server = req.query['api_server'];
82 // var nsr_id = req.body['nsr_id_ref'];
83 // var nsConfigPrimitiveName = req.body['name'];
84 return new Promise(function(resolve, reject) {
85 var uri = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operations/get-ns-service-primitive-values');
86
87 var jsonData = {
88 "input": utils.addProjectContextToRPCPayload(req, uri, req.body)
89 };
90
91 var headers = _.extend({},
92 constants.HTTP_HEADERS.accept.data,
93 constants.HTTP_HEADERS.content_type.data, {
94 'Authorization': req.session && req.session.authorization
95 }
96 );
97 request({
98 uri: uri,
99 method: 'POST',
100 headers: headers,
101 forever: constants.FOREVER_ON,
102 rejectUnauthorized: false,
103 json: jsonData
104 }, function(error, response, body) {
105 if (utils.validateResponse('RPC.getNSServicePrimitiveValues', error, response, body, resolve, reject)) {
106
107 resolve({
108 statusCode: response.statusCode,
109 data: JSON.parse(body)
110 });
111 }
112 });
113 }).catch(function(error) {
114 console.log('error getting primitive values');
115 });
116 };
117 RPC.refreshAccountConnectionStatus = function(req) {
118 var api_server = req.query['api_server'];
119 var Name = req.params.name;
120 var Type = req.params.type;
121 var jsonData = {
122 input: {}
123 };
124 var rpcInfo = {
125 sdn: {
126 label: 'sdn-account',
127 rpc: 'update-sdn-status'
128 },
129 config: {
130 label: 'cfg-agent-account',
131 rpc: 'update-cfg-agent-status'
132 },
133 cloud: {
134 label: 'cloud-account',
135 rpc: 'update-cloud-status'
136 }
137 }
138 jsonData.input[rpcInfo[Type].label] = Name;
139
140 var uri = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operations/' + rpcInfo[Type].rpc);
141
142 jsonData.input = utils.addProjectContextToRPCPayload(req, uri, jsonData.input);
143
144 var headers = _.extend({},
145 constants.HTTP_HEADERS.accept.data,
146 constants.HTTP_HEADERS.content_type.data, {
147 'Authorization': req.session && req.session.authorization
148 }
149 );
150 return new Promise(function(resolve, reject) {
151 request({
152 uri: uri,
153 method: 'POST',
154 headers: headers,
155 forever: constants.FOREVER_ON,
156 rejectUnauthorized: false,
157 json: jsonData
158 }, function(error, response, body) {
159 if (utils.validateResponse('RPC.refreshAccountConnectionStatus', error, response, body, resolve, reject)) {
160
161 resolve({
162 statusCode: response.statusCode,
163 data: body
164 });
165 }
166 });
167 }).catch(function(error) {
168 console.log('Error refreshing account info');
169 });
170 };
171
172
173 var DataCenters = {};
174 // Catalog module methods
175 Catalog.get = function(req) {
176 var api_server = req.query['api_server'];
177 var results = {}
178 var projectPrefix = req.session.projectId ? "project-" : "";
179 return new Promise(function(resolve, reject) {
180 Promise.all([
181 rp({
182 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep'),
183 method: 'GET',
184 headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
185 'Authorization': req.session && req.session.authorization
186 }),
187 forever: constants.FOREVER_ON,
188 rejectUnauthorized: false,
189 resolveWithFullResponse: true
190 }),
191 rp({
192 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd?deep'),
193 method: 'GET',
194 headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
195 'Authorization': req.session && req.session.authorization
196 }),
197 forever: constants.FOREVER_ON,
198 rejectUnauthorized: false,
199 resolveWithFullResponse: true
200 }),
201 rp({
202 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata?deep'),
203 method: 'GET',
204 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
205 'Authorization': req.session && req.session.authorization
206 }),
207 forever: constants.FOREVER_ON,
208 rejectUnauthorized: false,
209 resolveWithFullResponse: true
210 })
211 // Not enabled for now
212 // rp({
213 // uri: utils.confdPort(api_server) + APIVersion + '/api/config/pnfd-catalog/pnfd?deep',
214 // method: 'GET',
215 // headers: _.extend({},
216 // constants.HTTP_HEADERS.accept.collection,
217 // {
218 // 'Authorization': req.session && req.session.authorization
219 // }),
220 // forever: constants.FOREVER_ON,
221 // rejectUnauthorized: false,
222 // resolveWithFullResponse: true
223 // })
224 ]).then(function(result) {
225 console.log('Resolved all request promises (NSD, VNFD) successfully');
226 var response = [{
227 "id": "GUID-1",
228 "name": "RIFT.wareâ„¢ NS Descriptors Catalog",
229 "short-name": "rift.ware-nsd-cat",
230 "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.",
231 "vendor": "RIFT.io",
232 "version": "",
233 "created-on": "",
234 "type": "nsd",
235 "meta": {
236 "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"
237 },
238 "descriptors": []
239 }, {
240 "id": "GUID-2",
241 "name": "RIFT.wareâ„¢ VNF Descriptors Catalog",
242 "short-name": "rift.ware-vnfd-cat",
243 "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.",
244 "vendor": "RIFT.io",
245 "version": "",
246 "created-on": "",
247 "type": "vnfd",
248 "meta": {
249 "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_3\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <g> <path d=\"M58.852,62.447l-4.662-1.033c-0.047-3.138-0.719-6.168-1.996-9.007l3.606-2.92c0.858-0.695,0.99-1.954,0.296-2.813 l-4.521-5.584c-0.334-0.413-0.818-0.675-1.346-0.731c-0.525-0.057-1.056,0.102-1.468,0.435L45.25,43.64v0 c-2.486-1.907-5.277-3.259-8.297-4.019v-4.458c0-1.104-0.896-2-2-2H27.77c-1.104,0-2,0.896-2,2v4.461 c-3.08,0.777-5.922,2.171-8.447,4.144l-3.545-2.82c-0.415-0.33-0.94-0.479-1.472-0.422c-0.527,0.06-1.009,0.327-1.339,0.743 l-4.472,5.623c-0.688,0.864-0.544,2.123,0.32,2.81l3.642,2.896v0c-1.25,2.848-1.895,5.88-1.916,9.011l-4.666,1.078 c-1.076,0.249-1.747,1.322-1.499,2.398l1.616,7.001c0.249,1.077,1.325,1.747,2.399,1.499l4.813-1.111v0 c1.429,2.681,3.344,5.017,5.691,6.943l-2.17,4.55c-0.476,0.997-0.054,2.19,0.943,2.666l6.484,3.094 c0.271,0.129,0.566,0.195,0.861,0.195c0.226,0,0.451-0.038,0.668-0.115c0.5-0.177,0.909-0.545,1.138-1.024l2.198-4.611 c2.923,0.563,5.966,0.554,8.879-0.033l2.236,4.585c0.484,0.994,1.685,1.403,2.675,0.921l6.456-3.148 c0.992-0.484,1.405-1.682,0.921-2.674l-2.206-4.524c2.335-1.946,4.231-4.301,5.639-6.999l4.812,1.067 c1.076,0.237,2.146-0.441,2.385-1.52l1.556-7.014c0.115-0.518,0.02-1.06-0.266-1.508C59.82,62.878,59.369,62.562,58.852,62.447z M40.18,61.761c0,4.859-3.953,8.812-8.813,8.812c-4.858,0-8.811-3.953-8.811-8.812s3.952-8.812,8.811-8.812 C36.227,52.949,40.18,56.902,40.18,61.761z\"/> <path d=\"M64.268,45.324c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.826,0.353,3.736,0.345,5.551-0.021l1.07,2.195 c0.484,0.992,1.682,1.405,2.675,0.921l2.691-1.313c0.477-0.233,0.842-0.646,1.015-1.147c0.172-0.501,0.139-1.051-0.095-1.528 l-1.052-2.155c1.458-1.214,2.645-2.686,3.527-4.377l2.278,0.504c1.075,0.238,2.146-0.442,2.386-1.52l0.647-2.923 c0.238-1.078-0.442-2.146-1.521-2.385l-2.184-0.484c-0.028-1.962-0.449-3.857-1.248-5.632l1.673-1.355 c0.412-0.334,0.675-0.818,0.73-1.345s-0.102-1.056-0.436-1.468l-1.884-2.327c-0.697-0.859-1.957-0.99-2.813-0.295l-1.614,1.307 c-1.554-1.193-3.299-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.04 c-1.927,0.486-3.703,1.358-5.28,2.592l-1.634-1.298c-0.862-0.687-2.12-0.543-2.81,0.32l-1.864,2.344 c-0.33,0.416-0.481,0.945-0.422,1.472c0.061,0.527,0.327,1.009,0.743,1.339l1.69,1.345c-0.78,1.779-1.184,3.676-1.197,5.636 l-2.189,0.505c-0.517,0.119-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51l0.675,2.918 c0.249,1.076,1.323,1.747,2.398,1.498l2.28-0.527c0.892,1.676,2.089,3.137,3.559,4.343l-1.035,2.17 c-0.228,0.479-0.257,1.028-0.08,1.528c0.178,0.5,0.546,0.91,1.024,1.138l2.703,1.289C63.686,45.261,63.979,45.324,64.268,45.324z M64.334,27.961c0-3.039,2.473-5.51,5.512-5.51c3.038,0,5.51,2.472,5.51,5.51c0,3.039-2.472,5.511-5.51,5.511 C66.807,33.472,64.334,31,64.334,27.961z\"/> <path d=\"M96.107,66.441l-2.182-0.484c-0.028-1.961-0.449-3.856-1.25-5.632l1.675-1.355c0.412-0.334,0.675-0.818,0.73-1.346 c0.056-0.527-0.102-1.056-0.436-1.468l-1.885-2.327c-0.695-0.859-1.956-0.99-2.813-0.295l-1.614,1.307 c-1.555-1.193-3.3-2.038-5.188-2.513v-2.039c0-1.104-0.896-2-2-2h-2.994c-1.104,0-2,0.896-2,2v2.041 c-1.929,0.486-3.706,1.358-5.282,2.592l-0.001,0l-1.631-1.298c-0.415-0.331-0.938-0.482-1.472-0.422 c-0.527,0.06-1.009,0.327-1.339,0.742l-1.863,2.343c-0.688,0.865-0.544,2.123,0.32,2.811l1.691,1.345 c-0.782,1.784-1.186,3.68-1.199,5.636l-2.188,0.505c-0.517,0.12-0.965,0.439-1.246,0.889c-0.281,0.45-0.372,0.993-0.252,1.51 l0.675,2.918c0.249,1.076,1.327,1.744,2.397,1.498l2.281-0.526c0.893,1.677,2.09,3.138,3.558,4.343h0.001l-1.035,2.168 c-0.229,0.479-0.258,1.029-0.081,1.529c0.178,0.5,0.546,0.909,1.024,1.138l2.702,1.289c0.278,0.132,0.571,0.195,0.86,0.195 c0.746,0,1.463-0.42,1.806-1.139l1.054-2.208c1.828,0.353,3.739,0.347,5.552-0.021l1.071,2.194 c0.484,0.992,1.682,1.405,2.675,0.921l2.69-1.312c0.477-0.233,0.842-0.645,1.014-1.147c0.173-0.501,0.14-1.051-0.093-1.528 l-1.052-2.155c1.459-1.215,2.645-2.688,3.525-4.377l2.278,0.505c0.52,0.116,1.061,0.02,1.508-0.266 c0.447-0.285,0.763-0.736,0.878-1.254l0.647-2.923C97.866,67.748,97.186,66.681,96.107,66.441z M85.162,66.174 c0,3.039-2.471,5.511-5.508,5.511c-3.039,0-5.512-2.472-5.512-5.511c0-3.039,2.473-5.511,5.512-5.511 C82.691,60.664,85.162,63.136,85.162,66.174z\"/> </g> </svg> "
250 },
251 "descriptors": []
252 }, {
253 "id": "GUID-3",
254 "name": "RIFT.wareâ„¢ PNF Descriptors Catalog",
255 "short-name": "rift.ware-pnfd-cat",
256 "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.",
257 "vendor": "RIFT.io",
258 "version": "",
259 "created-on": "",
260 "type": "pnfd",
261 "meta": {
262 "icon-svg": "data:image/svg+xml,<?xml version=\"1.0\" encoding=\"utf-8\"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\"> <svg version=\"1.1\" id=\"Layer_4\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\" width=\"100px\" height=\"100px\" viewBox=\"0 0 100 100\" enable-background=\"new 0 0 100 100\" xml:space=\"preserve\"> <path d=\"M86.334,47.444V35.759H13.666v11.686h3.561v5.111h-3.561v11.686h72.668V52.556h-4.108v-5.111H86.334z M26.628,59.454h-5.051 v-4.941h5.051V59.454z M26.628,52.404h-5.051v-4.941h5.051V52.404z M26.628,45.486h-5.051v-4.941h5.051V45.486z M34.094,59.454 h-5.051v-4.941h5.051V59.454z M34.094,52.404h-5.051v-4.941h5.051V52.404z M34.094,45.486h-5.051v-4.941h5.051V45.486z M41.452,59.454h-5.051v-4.941h5.051V59.454z M41.452,52.404h-5.051v-4.941h5.051V52.404z M41.452,45.486h-5.051v-4.941h5.051 V45.486z M48.733,59.454h-5.051v-4.941h5.051V59.454z M48.733,52.404h-5.051v-4.941h5.051V52.404z M48.733,45.486h-5.051v-4.941 h5.051V45.486z M56.2,59.454h-5.051v-4.941H56.2V59.454z M56.2,52.404h-5.051v-4.941H56.2V52.404z M56.2,45.486h-5.051v-4.941H56.2 V45.486z M63.558,59.454h-5.05v-4.941h5.05V59.454z M63.558,52.404h-5.05v-4.941h5.05V52.404z M63.558,45.486h-5.05v-4.941h5.05 V45.486z M74.858,59.312h-6.521v-3.013h6.521V59.312z M71.572,50.854c-2.875,0-5.204-2.33-5.204-5.203s2.329-5.203,5.204-5.203 s5.204,2.33,5.204,5.203S74.446,50.854,71.572,50.854z M74.858,45.618c0,1.801-1.46,3.261-3.261,3.261 c-1.8,0-3.261-1.46-3.261-3.261s1.46-3.26,3.261-3.26C73.398,42.358,74.858,43.817,74.858,45.618z\"/> </svg>"
263 },
264 "descriptors": []
265 }];
266 var vnfdCatalog = null;
267 var vnfdDict = {};
268 if (result[1].body) {
269 vnfdCatalog = JSON.parse(result[1].body).collection[projectPrefix + 'vnfd:vnfd'].map(function(v, i) {
270 vnfdDict[v.id] = v['short-name'] || v.name;
271 })
272 }
273 if (result[0].body) {
274 response[0].descriptors = JSON.parse(result[0].body).collection[projectPrefix + 'nsd:nsd'];
275 if (result[2].body) {
276 var data = JSON.parse(result[2].body);
277 if (data && data["nsr:ns-instance-opdata"] && data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"]) {
278 var nsdRefCountCollection = data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"];
279 response[0].descriptors.map(function(nsd) {
280 if (!nsd["meta"]) {
281 nsd["meta"] = {};
282 }
283 if (typeof nsd['meta'] == 'string') {
284 nsd['meta'] = JSON.parse(nsd['meta']);
285 }
286 nsd["meta"]["instance-ref-count"] = _.findWhere(nsdRefCountCollection, {
287 "nsd-id-ref": nsd.id
288 })["instance-ref-count"];
289 nsd["constituent-vnfd"] && nsd["constituent-vnfd"].map(function(v) {
290 v.name = vnfdDict[v["vnfd-id-ref"]];
291 })
292 });
293 }
294 }
295 };
296 if (result[1].body) {
297 response[1].descriptors = JSON.parse(result[1].body).collection[projectPrefix + 'vnfd:vnfd'];
298 };
299 // if (result[2].body) {
300 // response[2].descriptors = JSON.parse(result[2].body).collection[projectPrefix + 'pnfd:pnfd'];
301 // };
302 resolve({
303 statusCode: response.statusCode || 200,
304 data: JSON.stringify(response)
305 });
306 }).catch(function(error) {
307 // Todo: Need better logic than all or nothing.
308 // Right now even if one of the southbound APIs fails - all fail
309 var res = {};
310 console.log('Problem with Catalog.get', error);
311 res.statusCode = error.statusCode || 500;
312 res.errorMessage = {
313 error: 'Failed to get catalogs' + error
314 };
315 reject(res);
316 });
317 });
318 };
319 Catalog.delete = function(req) {
320 var api_server = req.query['api_server'];
321 var catalogType = req.params.catalogType;
322 var id = req.params.id;
323 console.log('Deleting', catalogType, id, 'from', api_server);
324 return new Promise(function(resolve, reject) {
325 request({
326 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog/' + catalogType + '/' + id),
327 method: 'DELETE',
328 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
329 'Authorization': req.session && req.session.authorization
330 }),
331 forever: constants.FOREVER_ON,
332 rejectUnauthorized: false,
333 }, function(error, response, body) {
334 if (utils.validateResponse('Catalog.delete', error, response, body, resolve, reject)) {
335 resolve({
336 statusCode: response.statusCode
337 });
338 }
339 });
340 });
341 };
342 Catalog.getVNFD = function(req) {
343 var api_server = req.query['api_server'];
344 var vnfdID = req.body.data;
345 var authorization = req.session && req.session.authorization;
346 var VNFDs = [];
347 if (typeof(vnfdID) == "object" && vnfdID.constructor.name == "Array") {
348 vnfdID.map(function(id) {
349 VNFDs.push(requestVNFD(id));
350 });
351 } else {
352 VNFDs.push(requestVNFD(vnfdID));
353 }
354 return new Promise(function(resolve, reject) {
355 Promise.all(VNFDs).then(function(data) {
356 resolve(data)
357 }).catch(function(error) {
358 // Todo: Need better logic than all or nothing.
359 // Right now even if one of the southbound APIs fails - all fail
360 var res = {};
361 console.log('Problem with Catalog.getVNFD', error);
362 res.statusCode = 404;
363 res.errorMessage = {
364 error: 'Failed to get VNFDs' + error
365 };
366 reject(res);
367 });
368 });
369
370 function requestVNFD(id) {
371 return new Promise(function(resolve, reject) {
372 var url = utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd' + (id ? '/' + id : '') + '?deep';
373 request({
374 uri: utils.projectContextUrl(req, url),
375 method: 'GET',
376 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
377 'Authorization': authorization
378 }),
379 forever: constants.FOREVER_ON,
380 rejectUnauthorized: false,
381 }, function(error, response, body) {
382 if (utils.validateResponse('Catalog.getVNFD', error, response, body, resolve, reject)) {
383 var data;
384 //Is this still needed?
385 try {
386 data = JSON.parse(response.body)
387 } catch (e) {
388 reject({
389 statusCode: response ? response.statusCode : 400,
390 errorMessage: 'Issue parsing VNFD ' + id + 'from ' + utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd/' + id + '?deep'
391 });
392 }
393 resolve(data);
394 }
395 });
396 });
397 }
398 };
399 Catalog.create = function(req) {
400 var api_server = req.query['api_server'];
401 var catalogType = req.params.catalogType;
402 var data = req.body;
403 console.log('Creating', catalogType, 'on', api_server);
404 var jsonData = {};
405 jsonData[catalogType] = [];
406 jsonData[catalogType].push(data);
407 return new Promise(function(resolve, reject) {
408 var requestHeaders = {};
409 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
410 'Authorization': req.session && req.session.authorization
411 });
412 request({
413 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog'),
414 method: 'POST',
415 headers: requestHeaders,
416 forever: constants.FOREVER_ON,
417 rejectUnauthorized: false,
418 json: jsonData
419 }, function(error, response, body) {
420 if (utils.validateResponse('Catalog.create', error, response, body, resolve, reject)) {
421 resolve({
422 statusCode: response.statusCode
423 });
424 }
425 });
426 });
427 };
428 Catalog.update = function(req) {
429 var api_server = req.query['api_server'];
430 var catalogType = req.params.catalogType;
431 var id = req.params.id;
432 var data = req.body;
433 console.log('Updating', catalogType, 'id', id, 'on', api_server);
434 var jsonData = {};
435 jsonData[catalogType] = {};
436 jsonData[catalogType] = data;
437 return new Promise(function(resolve, reject) {
438 var requestHeaders = {};
439 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
440 'Authorization': req.session && req.session.authorization
441 });
442 request({
443 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog' + '/' + catalogType + '/' + id),
444 method: 'PUT',
445 headers: requestHeaders,
446 forever: constants.FOREVER_ON,
447 rejectUnauthorized: false,
448 json: jsonData
449 }, function(error, response, body) {
450 if (utils.validateResponse('Catalog.update', error, response, body, resolve, reject)) {
451 resolve({
452 statusCode: response.statusCode
453 });
454 }
455 });
456 });
457 };
458
459 Catalog.decorateNsdCatalogWithPlacementGroups = function decorateNsdCatalogWithPlacementGroups(catalog) {
460 var newData = catalog;
461 var parsedCatalog = JSON.parse(catalog.data);
462 var nsds = parsedCatalog[0].descriptors;
463 var vnfds = parsedCatalog[1].descriptors;
464 var vnfdDict = (function(){
465 var dict = {};
466 vnfds.map(function(v, i) {
467 dict[v.id] = v;
468 })
469 return dict;
470 })(vnfds);
471
472 nsds.map(function(c, i) {
473 //Rename and decorate NSD placement groups
474 c['ns-placement-groups'] = c['placement-groups'] && c['placement-groups'].map(function(p, i) {
475 //Adds vnfd name to member-vnfd entry
476 p['member-vnfd'] = p['member-vnfd'].map(function(v) {
477 v.name = vnfdDict[v['vnfd-id-ref']].name;
478 return v;
479 });
480 p['host-aggregate'] = [];
481 return p;
482 });
483
484 //Adds vnf placement groups to nsd object for UI
485 c['vnf-placement-groups'] = [];
486 c['constituent-vnfd'] && c['constituent-vnfd'].map(function(v) {
487 var vnf = vnfdDict[v['vnfd-id-ref']];
488 // var vnfPg = {
489 // name: vnf.name,
490 // 'placement-groups': vnf['placement-groups'].map(function(vp){
491 // vp['host-aggregate'] = [{}];
492 // return vp;
493 // })
494 // };
495 v['vnf-name'] = vnf.name;
496 vnf['placement-groups'] && vnf['placement-groups'].map(function(vp) {
497 vp['host-aggregate'] = [];
498 vp['vnf-name'] = vnf.name;
499 vp['vnfd-id-ref'] = v['vnfd-id-ref'];
500 vp['member-vnf-index'] = v['member-vnf-index'];
501 c['vnf-placement-groups'].push(vp);
502 })
503 })
504 return c;
505 })
506 // parsedCatalog[0].descriptors = nsds;
507 newData.data = JSON.stringify(parsedCatalog);
508 return newData;
509 }
510
511 // NSR module methods
512 // Spend some time refactoring this
513 // refactor to accept only request object
514 NSR.get = function(req) {
515 var self = this;
516 var nsrPromises = [];
517 var api_server = req.query["api_server"];
518 var id = req.params.id;
519 var projectPrefix = req.session.projectId ? "project-" : "";
520 var nsdInfo = new Promise(function(resolve, reject) {
521 request({
522 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep'),
523 method: 'GET',
524 headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
525 'Authorization': req.session && req.session.authorization
526 }),
527 forever: constants.FOREVER_ON,
528 rejectUnauthorized: false,
529 }, function(error, response, body) {
530 if (utils.validateResponse('NSR.get nsd-catalog', error, response, body, resolve, reject)) {
531 var data;
532 var isString = typeof(response.body) == "string";
533 if (isString && response.body == '') return resolve('empty');
534 data = isString ? JSON.parse(response.body) : response.body;
535 var nsdData = data.collection[projectPrefix + "nsd:nsd"];
536 if (nsdData.constructor.name == "Object") {
537 nsdData = [nsdData];
538 }
539 resolve(nsdData);
540 };
541 })
542 })
543 var config = new Promise(function(resolve, reject) {
544 request({
545 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-config/nsr' + (id ? '/' + id : '') + '?deep'),
546 method: 'GET',
547 headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
548 'Authorization': req.session && req.session.authorization
549 }),
550 forever: constants.FOREVER_ON,
551 rejectUnauthorized: false,
552 }, function(error, response, body) {
553 if (utils.validateResponse('NSR.get ns-instance-config', error, response, body, resolve, reject)) {
554 var data;
555 var isString = typeof(response.body) == "string";
556 if (isString && response.body == '') return resolve();
557 data = isString ? JSON.parse(response.body) : response.body;
558 data = id ? data : data.collection;
559 var nsrData = data["nsr:nsr"];
560 if (nsrData.constructor.name == "Object") {
561 nsrData = [nsrData];
562 }
563 resolve(nsrData);
564 };
565 });
566 });
567 var opData = new Promise(function(resolve, reject) {
568 request({
569 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr' + (id ? '/' + id : '') + '?deep'),
570 method: 'GET',
571 headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
572 'Authorization': req.session && req.session.authorization
573 }),
574 forever: constants.FOREVER_ON,
575 rejectUnauthorized: false,
576 }, function(error, response, body) {
577 if (utils.validateResponse('NSR.get ns-instance-opdata', error, response, body, resolve, reject)) {
578 var data;
579 var isString = typeof(response.body) == "string";
580 if (isString && response.body == '') return resolve();
581 data = isString ? JSON.parse(response.body) : response.body;
582 data = id ? data : data.collection;
583 var nsrData = data["nsr:nsr"];
584 if (nsrData.constructor.name == "Object") {
585 nsrData = [nsrData];
586 }
587 nsrData.forEach(self.decorateWithScalingGroupDict);
588 nsrData.forEach(self.decorateAndTransformNFVI);
589 nsrData.forEach(self.decorateAndTransformWithControls);
590 Promise.all(self.addVnfrDataPromise(req, nsrData)).then(function() {
591 Promise.all(self.addVlrDataPromise(req, nsrData)).then(function() {
592 resolve(nsrData);
593 });
594 });
595 };
596 });
597 }).catch(function(error) {
598 console.log('error getting aggregated NS opdata', error)
599 //note this will actually trigger the success callback
600 });
601 return new Promise(function(resolve, reject) {
602 //Need smarter error handling here
603 Promise.all([config, opData]).then(function(resolves) {
604 var aggregate = {};
605 // resolves[0] ==> ns-instance-config
606 // resolves[1] ==> ns-instance-opdata
607
608 var nsInstanceConfig = resolves[0] && resolves[0];
609 var nsInstanceOpdata = resolves[1] && resolves[1];
610
611 if (!nsInstanceConfig && !nsInstanceOpdata) {
612 return resolve({
613 nsrs: []
614 });
615 }
616
617 nsInstanceConfig.forEach(function(v, k) {
618 v.nsd_name = v['nsd'] && v['nsd']['name'];
619 var scaling_group_descriptor = null;
620
621 scaling_group_descriptor = v['nsd'] && v['nsd']['scaling-group-descriptor'];
622
623 if (scaling_group_descriptor) {
624 scaling_group_descriptor.map(function(sgd, sgdi) {
625 sgd['vnfd-member'] && sgd['vnfd-member'].map(function(vnfd, vnfdi) {
626 var vnfrObj = _.findWhere(_.findWhere(nsInstanceOpdata, {
627 'ns-instance-config-ref': v.id
628 }).vnfrs, {
629 'member-vnf-index-ref': vnfd['member-vnf-index-ref']
630 });
631 if (vnfrObj) {
632 vnfd['short-name'] = vnfrObj['short-name'];
633 }
634 })
635 })
636 v['scaling-group-descriptor'] = scaling_group_descriptor;
637 }
638
639 if (nsInstanceOpdata && nsInstanceOpdata.constructor.name == "Array") {
640 nsInstanceOpdata.forEach(function(w, l) {
641 if (v.id == w["ns-instance-config-ref"]) {
642 for (prop in w) {
643 if (prop != "ns-instance-config-ref" && !v.hasOwnProperty(prop)) {
644 v[prop] = w[prop];
645 }
646 }
647 }
648 });
649 }
650
651 v['scaling-group-record'] && v['scaling-group-record'].map(function(sgr) {
652 var scalingGroupName = sgr['scaling-group-name-ref'];
653 sgr['instance'] && sgr['instance'].map(function(instance) {
654 var scalingGroupInstanceId = instance['instance-id'];
655 instance['vnfrs'] && instance['vnfrs'].map(function(vnfr) {
656 var vnfrObj = _.findWhere(v['vnfrs'], {id: vnfr});
657 if (vnfrObj) {
658 vnfrObj['scaling-group-name'] = scalingGroupName;
659 vnfrObj['scaling-group-instance-id'] = scalingGroupInstanceId;
660 }
661 });
662 });
663 })
664 });
665 var nsrsData = nsInstanceConfig;
666 nsrsData.sort(function(a, b) {
667 return a["create-time"] - b["create-time"];
668 });
669 resolve({
670 nsrs: nsrsData
671 });
672 }).catch(function(error) {
673 reject({
674 statusCode: 404,
675 errorMessage: error
676 })
677 })
678 });
679 };
680 // Static VNFR Cache bu VNFR ID
681 var staticVNFRCache = {};
682
683 /**
684 * [decorateWithScalingGroupDict description]
685 * @param {[type]} nsr [description]
686 * @return {[type]}
687 {vnfr-id} : {
688 "scaling-group-name-ref": "sg1",
689 "instance-id": 0,
690 "op-status": "running",
691 "is-default": "true",
692 "create-time": 1463593760,
693 "config-status": "configuring",
694 "vnfrs": [
695 "432154e3-164e-4c05-83ee-3b56e4c898e7"
696 ]
697 }
698 */
699 NSR.decorateWithScalingGroupDict = function(nsr) {
700 var sg = nsr["scaling-group-record"];
701 var dict = {};
702 if(sg) {
703 sg.map(function(s) {
704 var sgRef = s['scaling-group-name-ref'];
705 s.instance && s.instance.map(function(si) {
706 si.vnfrs && si.vnfrs.map(function(v) {
707 dict[v] = si;
708 dict[v]["scaling-group-name-ref"] = sgRef;
709 })
710 })
711 })
712 }
713 return nsr['vnfr-scaling-groups'] = dict;
714 }
715
716
717 NSR.addVlrDataPromise = function(req, nsrs) {
718 var api_server = req.query['api_server'];
719 var promises = [];
720 nsrs.map(function(nsr) {
721 var vlrPromises = [];
722 var vlr = nsr['vlr'];
723 nsr['decorated-vlrs'] = [];
724 if (!vlr) {
725 console.log('No VL\'s found in NS');
726 }
727 vlr && vlr.map(function(vlrObject) {
728 req.params.id = vlrObject['vlr-ref'];
729 var vlrPromise = VLR.get(req).then(function(vlr) {
730 try {
731 var vlrItem = vlr['data'][0];
732 decorateNSRWithVLR(nsr, vlrObject, vlrItem);
733 } catch (e) {
734 console.log('Expection caught getting VLRs and adding to NSR:', e);
735 }
736 })
737 vlrPromises.push(vlrPromise);
738 });
739 var NSR_Promise = new Promise(function(resolve, reject) {
740 Promise.all(vlrPromises).then(function() {
741 resolve();
742 })
743 });
744 promises.push(NSR_Promise);
745 });
746 return promises;
747
748 function decorateNSRWithVLR(nsr, nsrVLRObject, vlr) {
749 var vlrObject = _.extend(nsrVLRObject, vlr);
750 vlrObject['vnfr-connection-point-ref'] && vlrObject['vnfr-connection-point-ref'].map(function(vnfrCP) {
751 var vnfrName = nsr['vnfrs'] && _.find(nsr['vnfrs'], {id: vnfrCP['vnfr-id']})['name'];
752 vnfrName && (vnfrCP['vnfr-name'] = vnfrName);
753 });
754 nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'name'), 0, vlrObject);
755 // nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'create-time'), 0, vlrObject);
756 }
757 }
758
759
760 NSR.addVnfrDataPromise = function(req, nsrs) {
761 var api_server = req.query['api_server'];
762 var promises = [];
763 nsrs.map(function(nsr) {
764 var epa_params = {};
765 var constituent_vnfr_ref = nsr["constituent-vnfr-ref"];
766 var vnfrPromises = [];
767 nsr["vnfrs"] = [];
768 nsr["dashboard-urls"] = [];
769 nsr['nfvi-metrics'] = [];
770 if (!constituent_vnfr_ref) {
771 console.log('Something is wrong, there are no constituent-vnfr-refs');
772 constituent_vnfr_ref = [];
773 }
774 //Get VNFR Static Data
775 constituent_vnfr_ref && constituent_vnfr_ref.map(function(constituentVnfrObj) {
776 req.params.id = constituentVnfrObj['vnfr-id'];
777 var vnfrPromise;
778 vnfrPromise = VNFR.get(req).then(function(vnfr) {
779 try {
780 var vnfrItem = vnfr[0];
781 decorateNSRWithVNFR(nsr, vnfrItem)
782 staticVNFRCache[vnfrItem.id] = vnfrItem;
783 } catch (e) {
784 console.log('Exception caught:', e);
785 }
786 });
787 vnfrPromises.push(vnfrPromise);
788 });
789 var NSR_Promise = new Promise(function(resolve, reject) {
790 Promise.all(vnfrPromises).then(function() {
791 var vnfrs = staticVNFRCache;
792 //Aggregate EPA Params
793 constituent_vnfr_ref && constituent_vnfr_ref.map(function(k) {
794 if (vnfrs[k['vnfr-id']]) {
795 epa_params = epa_aggregator(vnfrs[k['vnfr-id']].vdur, epa_params);
796 }
797 })
798 //Add VNFR Name to monitoring params
799 try {
800 if (nsr["monitoring-param"]) {
801 nsr["monitoring-param"].map(function(m) {
802 // var vnfr = vnfrs[m["vnfr-id"]] || {};
803 // m["vnfr-name"] = vnfr['name'] ? vnfr['name'] : (vnfr['short-name'] ? vnfr['short-name'] : 'VNFR');
804 var groupTag = m['group-tag'];
805 var vnfrId = m['vnfr-mon-param-ref'] && m['vnfr-mon-param-ref'][0] && m['vnfr-mon-param-ref'][0]['vnfr-id-ref'];
806 var vnfr = vnfrs[vnfrId] || {};
807 m["vnfr-name"] = vnfr['name'] ? vnfr['name'] : (vnfr['short-name'] ? vnfr['short-name'] : 'VNFR');
808 m['group-tag'] = (groupTag ? (groupTag + ' - ') : '') + m['vnfr-name'] + (vnfrId ? ' (' + vnfrId.substring(1,8) + '...)' : '');
809
810 });
811 }
812 } catch (e) {
813 console.log('Exception caught:', e);
814 }
815 resolve();
816 })
817 })
818 nsr["epa-params"] = epa_params;
819 promises.push(NSR_Promise);
820 })
821 return promises;
822
823 function decorateNSRWithVDURConsoleUrls(nsr, vnfr) {
824 nsr['console-urls'] = nsr['console-urls'] ? nsr['console-urls'] : [];
825
826 vnfr && vnfr['vdur'] && vnfr['vdur'].map(function(vdur) {
827 // This console-url is what front-end will hit to generate a real console-url
828 vdur['console-url'] = 'api/vnfr/' + vnfr.id + '/vdur/' + vdur.id + '/console-url';
829 nsr['console-urls'].push({
830 id: vdur.id,
831 name: vnfr.name,
832 'console-url': vdur['console-url']
833 });
834 });
835 }
836
837 function decorateNSRWithVNFR(nsr, vnfr) {
838 var vnfrObj = {
839 id: vnfr.id,
840 "member-vnf-index-ref": vnfr["member-vnf-index-ref"],
841 "short-name": vnfr["short-name"],
842 "vnf-configuration": vnfr["vnf-configuration"],
843 "nsr-id": nsr['ns-instance-config-ref'],
844 "name": vnfr['name'],
845 "vdur": vnfr["vdur"],
846 "cloud-account": vnfr["cloud-account"]
847 };
848 var vnfrSg = nsr['vnfr-scaling-groups'];
849 var vnfrName = vnfr["name"];
850 if(vnfrSg) {
851 if(vnfrSg[vnfr.id]) {
852 vnfrName = vnfrSg[vnfr.id]["scaling-group-name-ref"] + ':' + vnfrSg[vnfr.id][ "instance-id"] + ':' + vnfrName;
853 }
854 }
855 var vnfrNfviMetrics = buildNfviGraphs(vnfr.vdur, vnfrName);
856 if (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) {
857 vnfrObj['service-primitives-present'] = true;
858 } else {
859 vnfrObj['service-primitives-present'] = false;
860 }
861 transforms.mergeVnfrNfviMetrics(vnfrNfviMetrics, nsr["nfvi-metrics"]);
862 //TODO: Should be sorted by create-time when it becomes available instead of id
863 // nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'create-time'), 0, vnfrObj);
864 nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'id'), 0, vnfrObj);
865 vnfrObj["dashboard-url"] = vnfr["dashboard-url"];
866 nsr["dashboard-urls"].push(vnfrObj);
867
868 decorateNSRWithVDURConsoleUrls(nsr, vnfr);
869 }
870 }
871 NSR.create = function(req) {
872 var api_server = req.query['api_server'];
873 var data = req.body.data;
874 console.log('Instantiating NSR on ', api_server);
875 return new Promise(function(resolve, reject) {
876 var requestHeaders = {};
877 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
878 'Authorization': req.session && req.session.authorization
879 });
880 request({
881 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config'),
882 method: 'POST',
883 headers: requestHeaders,
884 forever: constants.FOREVER_ON,
885 rejectUnauthorized: false,
886 json: data
887 }, function(error, response, body) {
888 if (utils.validateResponse('NSR.create', error, response, body, resolve, reject)) {
889 var nsr_id = null;
890 try {
891 nsr_id = data.nsr[0].id;
892 } catch (e) {
893 console.log("NSR.create unable to get nsr_id. Error: %s",
894 e.toString());
895 }
896 resolve({
897 statusCode: response.statusCode,
898 data: { nsr_id: nsr_id }
899 });
900 };
901 });
902 });
903 };
904 NSR.delete = function(req) {
905 var api_server = req.query["api_server"];
906 var id = req.params.id;
907 if (!id || !api_server) {
908 return new Promise(function(resolve, reject) {
909 console.log('Must specifiy api_server and id to delete NSR');
910 return reject({
911 statusCode: 500,
912 errorMessage: {
913 error: 'Must specifiy api_server and id to delete NSR'
914 }
915 });
916 });
917 };
918 console.log('Deleting NSR with id: ' + id + 'on server: ' + api_server);
919 return new Promise(function(resolve, reject) {
920 var requestHeaders = {};
921 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, {
922 'Authorization': req.session && req.session.authorization
923 });
924 request({
925 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id),
926 method: 'DELETE',
927 headers: requestHeaders,
928 forever: constants.FOREVER_ON,
929 rejectUnauthorized: false,
930 }, function(error, response, body) {
931 if (utils.validateResponse('NSR.delete', error, response, body, resolve, reject)) {
932 resolve({
933 statusCode: response.statusCode,
934 data: JSON.stringify(response.body)
935 });
936 };
937 });
938 });
939 };
940 NSR.decorateAndTransformNFVI = function(nsr) {
941 var toDecorate = [];
942 // var metricsToUse = ["vcpu", "memory", "storage", "network"];
943 var metricsToUse = ["vcpu", "memory"];
944 try {
945 var nfviMetrics = nsr["rw-nsr:nfvi-metrics"];
946 if (nfviMetrics) {
947 metricsToUse.map(function(name) {
948 toDecorate.push(nfviMetrics[name])
949 });
950 }
951 nsr["nfvi-metrics"] = toDecorate;
952 delete nsr["rw-nsr:nfvi-metrics"];
953 } catch (e) {}
954 return nsr;
955 }
956 //Not a great pattern, Need a better way of handling logging;
957 //Refactor and move to the logging/logging.js
958 var logCache = {
959 decorateAndTransformWithControls: {}
960 }
961 NSR.decorateAndTransformWithControls = function(nsr) {
962 var controlTypes = ["action-param", "control-param"];
963 var nsControls = [];
964 var Groups = {};
965 controlTypes.map(function(control) {
966 try {
967 var controls = nsr["rw-nsr:" + control];
968 // nsControls.push(controls);
969 controls.map(function(item) {
970 if (!Groups[item["group-tag"]]) {
971 Groups[item["group-tag"]] = {};
972 Groups[item["group-tag"]]["action-param"] = []
973 Groups[item["group-tag"]]["control-param"] = []
974 }
975 Groups[item["group-tag"]][control].push(item);
976 });
977 delete nsr["rw-nsr:" + control];
978 } catch (e) {
979 var id = nsr["ns-instance-config-ref"];
980 if (!logCache.decorateAndTransformWithControls[id]) {
981 logCache.decorateAndTransformWithControls[id] = {};
982 }
983 var log = logCache.decorateAndTransformWithControls[id];
984 if (!log[control]) {
985 log[control] = true;
986 console.log('No controls exist for ' + control + ' at ' + nsr["ns-instance-config-ref"]);
987 }
988 }
989 });
990 for (k in Groups) {
991 var obj = {}
992 obj[k] = Groups[k];
993 nsControls.push(obj)
994 }
995 nsr.nsControls = nsControls;
996 return nsr;
997 };
998 NSR.setStatus = function(req) {
999 var api_server = req.query['api_server'];
1000 var id = req.params.id;
1001 var status = req.body.status;
1002 console.log('Setting NSR (id: ' + id + ') status, on ' + api_server + ', to be: ' + status);
1003 return new Promise(function(resolve, reject) {
1004 var command;
1005 if (typeof(status) != "string") {
1006 reject({
1007 'ERROR': 'NSR.setStatus Error: status is not a string type'
1008 });
1009 }
1010 command = status.toUpperCase();
1011 if (command != "ENABLED" && command != "DISABLED") {
1012 reject({
1013 'ERROR': 'NSR.setStatus Error: status is: ' + command + '. It should be ENABLED or DISABLED'
1014 });
1015 }
1016 var requestHeaders = {};
1017 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
1018 'Authorization': req.session && req.session.authorization
1019 });
1020 request({
1021 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/admin-status/'),
1022 method: 'PUT',
1023 headers: requestHeaders,
1024 json: {
1025 "nsr:admin-status": command
1026 },
1027 forever: constants.FOREVER_ON,
1028 rejectUnauthorized: false,
1029 }, function(error, response, body) {
1030 if (utils.validateResponse('NSR.setStatus', error, response, body, resolve, reject)) {
1031 resolve({
1032 statusCode: response.statusCode
1033 });
1034 };
1035 });
1036 });
1037 };
1038
1039 NSR.createScalingGroupInstance = function(req) {
1040 var api_server = req.query['api_server'];
1041 var id = req.params.id;
1042 var scaling_group_id = req.params.scaling_group_id;
1043 if (!api_server || !id || !scaling_group_id) {
1044 return new Promise(function(resolve, reject) {
1045 return reject({
1046 statusCode: 500,
1047 errorMessage: {
1048 error: 'API server/NSR id/Scaling group not provided'
1049 }
1050 });
1051 });
1052 }
1053
1054 var instance_id = Math.floor(Math.random() * 65535);
1055
1056 var jsonData = {
1057 instance: [{
1058 // id: uuid.v1()
1059 id: instance_id
1060 }]
1061 };
1062
1063 console.log('Creating scaling group instance for NSR ', id, ', scaling group ', scaling_group_id, ' with instance id ', instance_id);
1064
1065 return new Promise(function(resolve, reject) {
1066 var requestHeaders = {};
1067 _.extend(requestHeaders,
1068 constants.HTTP_HEADERS.accept.data,
1069 constants.HTTP_HEADERS.content_type.data,
1070 {
1071 'Authorization': req.session && req.session.authorization
1072 }
1073 );
1074
1075 request({
1076 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/scaling-group/' + scaling_group_id + '/instance'),
1077 method: 'POST',
1078 headers: requestHeaders,
1079 json: jsonData,
1080 forever: constants.FOREVER_ON,
1081 rejectUnauthorized: false
1082 }, function (error, response, body) {
1083 if (utils.validateResponse('NSR.createScalingGroupInstance', error, response, body, resolve, reject)) {
1084 resolve({
1085 statusCode: response.statusCode,
1086 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1087 })
1088 }
1089 });
1090 });
1091 };
1092
1093 NSR.deleteScalingGroupInstance = function(req) {
1094 var api_server=req.query['api_server'];
1095 var id = req.params.id;
1096 var scaling_group_id = req.params.scaling_group_id;
1097 var scaling_instance_id = req.params.scaling_instance_id;
1098
1099 if (!api_server || !id || !scaling_group_id || !scaling_instance_id) {
1100 return new Promise(function(resolve, reject) {
1101 return reject({
1102 statusCode: 500,
1103 errorMessage: {
1104 error: 'API server/NSR id/Scaling group/Scaling instance id not provided'
1105 }
1106 });
1107 });
1108 }
1109
1110 console.log('Deleting scaling group instance id ', scaling_instance_id,
1111 ' for scaling group ', scaling_group_id,
1112 ', under NSR ', id);
1113
1114 return new Promise(function(resolve, reject) {
1115 var requestHeaders = {};
1116 _.extend(requestHeaders,
1117 constants.HTTP_HEADERS.accept.data,
1118 constants.HTTP_HEADERS.content_type.data,
1119 {
1120 'Authorization': req.session && req.session.authorization
1121 }
1122 );
1123
1124 request({
1125 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + id + '/scaling-group/' + scaling_group_id + '/instance/' + scaling_instance_id),
1126 method: 'DELETE',
1127 headers: requestHeaders,
1128 forever: constants.FOREVER_ON,
1129 rejectUnauthorized: false
1130 }, function (error, response, body) {
1131 if (utils.validateResponse('NSR.deleteScalingGroupInstance', error, response, body, resolve, reject)) {
1132 resolve({
1133 statusCode: response.statusCode,
1134 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1135 })
1136 }
1137 });
1138 });
1139 };
1140
1141 NSR.nsd = {};
1142 NSR.nsd.vld = {};
1143
1144 NSR.nsd.vld.get = function(req) {
1145 var api_server = req.query['api_server'];
1146 var nsr_id = req.params.nsr_id;
1147 var vld_id = req.params.vld_id;
1148
1149 if (!api_server || !nsr_id) {
1150 return new Promise(function(resolve, reject) {
1151 return reject({
1152 statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
1153 errorMessage: 'API server/NSR id not provided'
1154 });
1155 })
1156 }
1157 console.log('Getting VLD', vld_id ? (' ' + vld_id) : ('\'s'), ' for NSR id', nsr_id);
1158
1159 return new Promise(function(resolve, reject) {
1160 var requestHeaders = {};
1161 _.extend(requestHeaders,
1162 vld_id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection,
1163 {
1164 'Authorization': req.session && req.session.authorization
1165 }
1166 );
1167
1168 request({
1169 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld' + (vld_id ? '/' + vld_id : '') +'?deep'),
1170 method: 'GET',
1171 headers: requestHeaders,
1172 forever: constants.FOREVER_ON,
1173 rejectUnauthorized: false
1174 }, function (error, response, body) {
1175 if (utils.validateResponse('NSR.nsd.vld.get', error, response, body, resolve, reject)) {
1176 resolve({
1177 statusCode: response.statusCode,
1178 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1179 });
1180 }
1181 });
1182 });
1183 };
1184
1185 NSR.nsd.vld.create = function(req) {
1186 var api_server = req.query['api_server'];
1187 var nsr_id = req.params.nsr_id;
1188 var vld_id = req.params.vld_id;
1189 var data = req.body;
1190
1191 if (!api_server || !nsr_id) {
1192 return new Promise(function(resolve, reject) {
1193 return reject({
1194 statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
1195 errorMessage: 'API server/NSR id not provided'
1196 });
1197 });
1198 }
1199
1200 console.log((vld_id ? 'Updating VLD ' + vld_id : 'Creating VLD') + ' under NSR', nsr_id);
1201
1202 var jsonData = {
1203 vld: typeof(data) == 'string' ? JSON.parse(data) : data
1204 };
1205
1206 return new Promise(function(resolve, reject) {
1207 var requestHeaders = {};
1208 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
1209 'Authorization': req.session && req.session.authorization
1210 });
1211 request({
1212 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld' + (vld_id ? '/' + vld_id : '')),
1213 method: vld_id ? 'PUT' : 'POST',
1214 headers: requestHeaders,
1215 forever: constants.FOREVER_ON,
1216 rejectUnauthorized: false,
1217 json: jsonData
1218 }, function(error, response, body) {
1219 if (utils.validateResponse('NSR.nsd.vld.create/update', error, response, body, resolve, reject)) {
1220 resolve({
1221 statusCode: response.statusCode,
1222 data: (typeof(response.body) == 'string') ? JSON.parse(response.body) : response.body
1223 });
1224 }
1225 });
1226 });
1227 };
1228
1229 NSR.nsd.vld.update = NSR.nsd.vld.create;
1230
1231 NSR.nsd.vld.delete = function(req) {
1232 var api_server = req.query['api_server'];
1233 var nsr_id = req.params.nsr_id;
1234 var vld_id = req.params.vld_id;
1235
1236 if (!api_server || !nsr_id || !vld_id) {
1237 return new Promise(function(resolve, reject) {
1238 return reject({
1239 statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
1240 errorMessage: 'API server/NSR id/VLD id not provided'
1241 });
1242 })
1243 }
1244 console.log('Deleting VLD', vld_id, 'for NSR id', nsr_id);
1245
1246 return new Promise(function(resolve, reject) {
1247 var requestHeaders = {};
1248 _.extend(requestHeaders,
1249 constants.HTTP_HEADERS.accept.data,
1250 {
1251 'Authorization': req.session && req.session.authorization
1252 }
1253 );
1254
1255 request({
1256 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + nsr_id + '/nsd/vld/' + vld_id),
1257 method: 'DELETE',
1258 headers: requestHeaders,
1259 forever: constants.FOREVER_ON,
1260 rejectUnauthorized: false
1261 }, function (error, response, body) {
1262 if (utils.validateResponse('NSR.nsd.vld.delete', error, response, body, resolve, reject)) {
1263 resolve({
1264 statusCode: response.statusCode,
1265 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1266 });
1267 }
1268 });
1269 });
1270 }
1271
1272 VNFR.get = function(req) {
1273 var api_server = req.query["api_server"];
1274 var id = req.params.id;
1275 var uri = utils.confdPort(api_server);
1276 uri += APIVersion + '/api/operational/vnfr-catalog/vnfr' + (id ? '/' + id : '') + '?deep';
1277 var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
1278 'Authorization': req.session && req.session.authorization
1279 });
1280 return new Promise(function(resolve, reject) {
1281 request({
1282 url: utils.projectContextUrl(req, uri),
1283 method: 'GET',
1284 headers: headers,
1285 forever: constants.FOREVER_ON,
1286 rejectUnauthorized: false,
1287 }, function(error, response, body) {
1288 if (utils.validateResponse('VNFR.get', error, response, body, resolve, reject)) {
1289 var data = JSON.parse(response.body);
1290 var returnData = id ? (data["vnfr:vnfr"] ? [data["vnfr:vnfr"]] : []) : data.collection["vnfr:vnfr"];
1291 returnData.forEach(function(vnfr) {
1292 vnfr['nfvi-metrics'] = vnfr.vdur ? buildNfviGraphs(vnfr.vdur) : [];
1293 vnfr['epa-params'] = vnfr.vdur ? epa_aggregator(vnfr.vdur) : [];
1294 vnfr['service-primitives-present'] = (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['service-primitive'] && vnfr['vnf-configuration']['service-primitive'].length > 0) ? true : false;
1295 vnfr['vdur'] && vnfr['vdur'].map(function(vdur, vdurIndex) {
1296 // This console-url is what front-end will hit to generate a real console-url
1297 vdur['console-url'] = 'api/vnfr/' + vnfr.id + '/vdur/' + vdur.id + '/console-url';
1298 });
1299 });
1300 return resolve(returnData);
1301 };
1302 });
1303 });
1304 }
1305
1306 function buildNfviGraphs(VDURs, vnfrName){
1307 var temp = {};
1308 var toReturn = [];
1309 APIConfig.NfviMetrics.map(function(k) {
1310
1311 VDURs && VDURs.map(function(v,i) {
1312 //Check for RIFT-12699: VDUR NFVI Metrics not fully populated
1313 if (v["rw-vnfr:nfvi-metrics"] && v["rw-vnfr:nfvi-metrics"][k] && v["rw-vnfr:nfvi-metrics"][k].hasOwnProperty('utilization')) {
1314 if(!temp[k]) {
1315 temp[k] = {
1316 title: '',
1317 data: []
1318 };
1319 };
1320 try {
1321 var data = v["rw-vnfr:nfvi-metrics"][k];
1322 var newData = {};
1323 newData.name = v.name ? v.name : v.id.substring(0,6);
1324 newData.name = vnfrName ? vnfrName + ': ' + newData.name : newData.name;
1325 newData.id = v.id;
1326 //converts to perentage
1327 newData.utilization = data.utilization * 0.01;
1328 temp[k].data.push(newData);
1329 temp[k].title = v["rw-vnfr:nfvi-metrics"][k].label;
1330 } catch (e) {
1331 console.log('Something went wrong with the VNFR NFVI Metrics. Check that the data is being properly returned. ERROR: ', e);
1332 }
1333 }
1334 });
1335 if(temp[k]) {
1336 toReturn.push(temp[k]);
1337 }
1338 });
1339 return toReturn;
1340 }
1341
1342
1343 //Cache NSR reference for VNFR
1344 VNFR.cachedNSR = {};
1345 VNFR.getByNSR = function(req) {
1346 var api_server = req.query["api_server"];
1347 var id = req.params.nsr_id;
1348 var uri = utils.confdPort(api_server);
1349 var reqClone = _.clone(req);
1350 delete reqClone.params.id;
1351 uri += APIVersion + '/api/operational/ns-instance-opdata/nsr/' + id + '?deep';
1352 var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
1353 'Authorization': req.session && req.session.authorization
1354 });
1355 return new Promise(function(resolve, reject) {
1356 if (VNFR.cachedNSR[id]) {
1357 var data = VNFR.cachedNSR[id];
1358 var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
1359 VNFR.get(reqClone).then(function(vnfrData) {
1360 resolve(filterVnfrByList(vnfrList, vnfrData));
1361 });
1362 } else {
1363 request({
1364 url: utils.projectContextUrl(req, uri),
1365 method: 'GET',
1366 headers: headers,
1367 forever: constants.FOREVER_ON,
1368 rejectUnauthorized: false,
1369 }, function(error, response, body) {
1370 if (utils.validateResponse('VNFR.getByNSR', error, response, body, resolve, reject)) {
1371 var data = JSON.parse(response.body);
1372 data = data["nsr:nsr"];
1373 //Cache NSR data with NSR-ID as
1374 VNFR.cachedNSR[id] = data;
1375 var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
1376 var returnData = [];
1377 VNFR.get(reqClone).then(function(vnfrData) {
1378 resolve(filterVnfrByList(vnfrList, vnfrData));
1379 });
1380 };
1381 });
1382 }
1383 });
1384 };
1385
1386 function filterVnfrByList(vnfrList, vnfrData) {
1387 return vnfrData.map(function(vnfr) {
1388 if (vnfrList.indexOf(vnfr.id) > -1) {
1389 return vnfr;
1390 }
1391 })
1392 };
1393
1394 VLR.get = function(req) {
1395 var api_server = req.query["api_server"];
1396 var id = req.params.id;
1397 var uri = utils.confdPort(api_server);
1398 uri += APIVersion + '/api/operational/vlr-catalog/vlr' + (id ? '/' + id : '') + '?deep';
1399 var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
1400 'Authorization': req.session && req.session.authorization
1401 });
1402 return new Promise(function(resolve, reject) {
1403 request({
1404 url: utils.projectContextUrl(req, uri),
1405 method: 'GET',
1406 headers: headers,
1407 forever: constants.FOREVER_ON,
1408 rejectUnauthorized: false,
1409 }, function(error, response, body) {
1410 if (utils.validateResponse('VLR.get', error, response, body, resolve, reject)) {
1411 var data = JSON.parse(response.body);
1412 var returnData = id ? [data["vlr:vlr"]] : data.collection["vlr:vlr"];
1413 return resolve({
1414 data: returnData,
1415 statusCode: response.statusCode
1416 });
1417 };
1418 });
1419 });
1420 }
1421
1422 RIFT.api = function(req) {
1423 var api_server = req.query["api_server"];
1424 var uri = utils.confdPort(api_server);
1425 var url = req.path;
1426 return new Promise(function(resolve, reject) {
1427 request({
1428 url: utils.projectContextUrl(req, uri + url + '?deep'),
1429 method: 'GET',
1430 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
1431 'Authorization': req.session && req.session.authorization
1432 }),
1433 forever: constants.FOREVER_ON,
1434 rejectUnauthorized: false,
1435 }, function(error, response, body) {
1436 if (utils.validateResponse('RIFT.api', error, response, body, resolve, reject)) {
1437 resolve(JSON.parse(response.body))
1438 };
1439 })
1440 })
1441 };
1442
1443 ComputeTopology.get = function(req) {
1444 var api_server = req.query['api_server'];
1445 var nsr_id = req.params.id;
1446 var result = {
1447 id: nsr_id, // node id
1448 name: nsr_id, // node name to display
1449 parameters: {}, // the parameters that can be used to determine size/color, etc. for the node
1450 type: 'nsr',
1451 children: [] // children for the node
1452 };
1453 return new Promise(function(resolve, reject) {
1454 var nsrPromise = new Promise(function(success, failure) {
1455 request({
1456 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr/' + nsr_id + '?deep'),
1457 method: 'GET',
1458 headers: _.extend({},
1459 constants.HTTP_HEADERS.accept.data, {
1460 'Authorization': req.session && req.session.authorization
1461 }),
1462 forever: constants.FOREVER_ON,
1463 rejectUnauthorized: false,
1464 }, function(error, response, body) {
1465 if (utils.validateResponse('ComputeTopology.get ns-instance-opdata/nsr/:id', error, response, body, success, failure)) {
1466 var data;
1467 var isString = typeof(response.body) == "string";
1468 if (isString && response.body == '') {
1469 return success({});
1470 }
1471 try {
1472 data = isString ? JSON.parse(response.body) : response.body;
1473
1474 var nsrNFVIMetricData = data["nsr:nsr"]["rw-nsr:nfvi-metrics"];
1475 result.parameters = nsrNFVIMetricData;
1476
1477 result.name = data["nsr:nsr"]["name-ref"];
1478
1479 var nsrData = data["nsr:nsr"]["constituent-vnfr-ref"];
1480 success(nsrData);
1481 } catch (e) {
1482 console.log('Error parsing ns-instance-opdata for NSR ID', nsr_id, 'Exception:', e);
1483 return failure()
1484 }
1485 };
1486 });
1487 }).then(function(data) {
1488
1489 try {
1490 // got NSR data
1491 // now get VNFR data and populate the structure
1492 var vnfrPromises = [];
1493
1494 // Run separately to confirm that primary structure is populated before promise resolution takes over
1495 // and starts modifying the data
1496 data.forEach(function(vnfrObj) {
1497
1498 var vnfrId = vnfrObj['vnfr-id'];
1499
1500 // If anything needs to be added to result for each vnfrId, do it here
1501
1502 vnfrPromises.push(
1503 new Promise(function(success, failure) {
1504 rp({
1505 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/vnfr-catalog/vnfr/' + vnfrId + '?deep'),
1506 method: 'GET',
1507 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
1508 'Authorization': req.session && req.session.authorization
1509 }),
1510 forever: constants.FOREVER_ON,
1511 rejectUnauthorized: false,
1512 resolveWithFullResponse: true
1513 }, function(error, response, body) {
1514 if (utils.validateResponse('ComputeTopology.get vnfr-catalaog/vnfr/:id', error, response, body, success, failure)) {
1515 try {
1516 var data = JSON.parse(response.body);
1517 var returnData = data["vnfr:vnfr"];
1518
1519 // Push VNFRs in result
1520 result.children.push({
1521 id: vnfrId,
1522 name: returnData.name,
1523 parameters: {}, // nfvi metrics here
1524 children: [],
1525 type: 'vnfr'
1526 });
1527
1528 // Push VDURs in result
1529 returnData.vdur.forEach(function(vdur) {
1530 result.children[result.children.length - 1].children.push({
1531 id: vdur.id,
1532 name: vdur.id,
1533 parameters: {},
1534 type: 'vdur'
1535 // children: []
1536 });
1537 });
1538
1539 return success(returnData.vdur);
1540 } catch (e) {
1541 console.log('Error parsing vnfr-catalog for VNFR ID', vnfrId, 'Exception:', e);
1542 return failure();
1543 }
1544 };
1545 });
1546 })
1547 );
1548 });
1549
1550 Promise.all(vnfrPromises).then(function(output) {
1551 console.log('Resolved all VNFR requests successfully');
1552 // By now result must be completely populated. output is moot
1553
1554 // Sort the results as there's no order to them from RIFT-REST
1555 result.children.sort(sortByName);
1556
1557 result.children.forEach(function(vnfr) {
1558 vnfr.children.sort(sortByName);
1559 });
1560
1561 resolve({
1562 statusCode: 200,
1563 data: result
1564 });
1565 }).catch(function(error) {
1566 // Todo: Can this be made better?
1567 // Right now if one of the southbound APIs fails - we just return what's populated so far in result
1568 console.log('Problem with ComputeTopology.get vnfr-catalog/vnfr/:id', error, 'Resolving with partial data', result);
1569 resolve({
1570 statusCode: 200,
1571 data: result
1572 });
1573 });
1574 } catch (e) {
1575 // API came back with empty ns-instance-opdata response for NSR ID
1576 // bail
1577 console.log('Error iterating through ns-instance-opdata response for NSR ID', nsr_id, 'Exception:', e);
1578 resolve({
1579 statusCode: 200,
1580 data: result
1581 })
1582 }
1583 }, function(error) {
1584 // failed to get NSR data.
1585 // bail
1586 resolve({
1587 statusCode: 200,
1588 data: result
1589 });
1590 });
1591 });
1592 };
1593
1594 NetworkTopology.get = function(req) {
1595 var api_server = req.query["api_server"];
1596 var uri = utils.confdPort(api_server);
1597 uri += APIVersion + '/api/operational/network?deep';
1598 var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
1599 'Authorization': req.session && req.session.authorization
1600 });
1601 return new Promise(function(resolve, reject) {
1602 request({
1603 url: utils.projectContextUrl(req, uri),
1604 method: 'GET',
1605 headers: headers,
1606 forever: constants.FOREVER_ON,
1607 rejectUnauthorized: false
1608 }, function(error, response, body) {
1609 if (utils.validateResponse('NetworkTopology.get', error, response, body, resolve, reject)) {
1610 var data = JSON.parse(response.body);
1611 var returnData = transforms.transformNetworkTopology(
1612 data["ietf-network:network"]
1613 );
1614 resolve({
1615 statusCode: 200,
1616 data: returnData
1617 });
1618 };
1619 });
1620 })
1621 }
1622
1623 VDUR.get = function(req) {
1624 var api_server = req.query["api_server"];
1625 var vnfrID = req.params.vnfr_id;
1626 var vdurID = req.params.vdur_id;
1627 var uri = utils.confdPort(api_server);
1628 uri += APIVersion + '/api/operational/vnfr-catalog/vnfr/' + vnfrID + '/vdur/' + vdurID + '?deep';
1629 var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
1630 'Authorization': req.session && req.session.authorization
1631 });
1632 return new Promise(function(resolve, reject) {
1633 request({
1634 url: utils.projectContextUrl(req, uri),
1635 method: 'GET',
1636 headers: headers,
1637 forever: constants.FOREVER_ON,
1638 rejectUnauthorized: false,
1639 }, function(error, response, body) {
1640 if (utils.validateResponse('VDUR.get', error, response, body, resolve, reject)) {
1641 var data = JSON.parse(response.body);
1642 var returnData = data["vdur:vdur"];
1643 return resolve(returnData);
1644 };
1645 });
1646 })
1647 }
1648
1649 VDUR.consoleUrl = {};
1650 VDUR.consoleUrl.get = function(req) {
1651 var api_server = req.query["api_server"];
1652 var vnfrID = req.params.vnfr_id;
1653 var vdurID = req.params.vdur_id;
1654 var uri = utils.confdPort(api_server);
1655 uri += APIVersion + '/api/operational/vnfr-console/vnfr/' + vnfrID + '/vdur/' + vdurID + '/console-url' + '?deep';
1656 var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
1657 'Authorization': req.session && req.session.authorization
1658 });
1659 return new Promise(function(resolve, reject) {
1660 request({
1661 url: utils.projectContextUrl(req, uri),
1662 method: 'GET',
1663 headers: headers,
1664 forever: constants.FOREVER_ON,
1665 rejectUnauthorized: false,
1666 }, function(error, response, body) {
1667 if (utils.validateResponse('VDUR.consoleUrl.get', error, response, body, resolve, reject)) {
1668 var data = JSON.parse(response.body);
1669 var returnData = data;
1670 return resolve({
1671 data: returnData,
1672 statusCode: response.statusCode
1673 });
1674 };
1675 });
1676 })
1677 }
1678
1679 CloudAccount.get = function(req) {
1680 var api_server = req.query["api_server"];
1681 var uri = utils.confdPort(api_server);
1682 uri += APIVersion + '/api/operational/cloud/account?deep';
1683 var headers = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
1684 'Authorization': req.session && req.session.authorization
1685 });
1686 return new Promise(function(resolve, reject) {
1687 request({
1688 url: utils.projectContextUrl(req, uri),
1689 method: 'GET',
1690 headers: headers,
1691 forever: constants.FOREVER_ON,
1692 rejectUnauthorized: false,
1693 }, function(error, response, body) {
1694 if (utils.validateResponse('CloudAccount.get', error, response, body, resolve, reject)) {
1695 var data = JSON.parse(response.body);
1696 var returnData = data["collection"]["rw-cloud:account"];
1697 resolve({
1698 statusCode: 200,
1699 data: returnData
1700 });
1701 };
1702 });
1703 });
1704 }
1705
1706
1707 // Config-Agent Account APIs
1708 ConfigAgentAccount.get = function(req) {
1709 var self = this;
1710
1711 var api_server = req.query["api_server"];
1712 var id = req.params.id;
1713
1714 if (!id) {
1715 // Get all config accounts
1716 return new Promise(function(resolve, reject) {
1717
1718 var requestHeaders = {};
1719 _.extend(requestHeaders,
1720 constants.HTTP_HEADERS.accept.collection, {
1721 'Authorization': req.session && req.session.authorization
1722 });
1723
1724 request({
1725 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account'),
1726 type: 'GET',
1727 headers: requestHeaders,
1728 forever: constants.FOREVER_ON,
1729 rejectUnauthorized: false,
1730 },
1731 function(error, response, body) {
1732 var data;
1733 var statusCode;
1734 if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
1735 try {
1736 data = JSON.parse(response.body).collection['rw-config-agent:account'];
1737 statusCode = response.statusCode;
1738 } catch (e) {
1739 console.log('Problem with "ConfigAgentAccount.get"', e);
1740 var err = {};
1741 err.statusCode = 500;
1742 err.errorMessage = {
1743 error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
1744 }
1745 return reject(err);
1746 }
1747
1748 return resolve({
1749 statusCode: statusCode,
1750 data: data
1751 });
1752 };
1753 });
1754 });
1755 } else {
1756 //Get a specific config account
1757 return new Promise(function(resolve, reject) {
1758 var requestHeaders = {};
1759 _.extend(requestHeaders,
1760 constants.HTTP_HEADERS.accept.data, {
1761 'Authorization': req.session && req.session.authorization
1762 });
1763
1764 request({
1765 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account/' + id),
1766 type: 'GET',
1767 headers: requestHeaders,
1768 forever: constants.FOREVER_ON,
1769 rejectUnauthorized: false,
1770 },
1771 function(error, response, body) {
1772 var data;
1773 var statusCode;
1774 if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
1775 try {
1776 data = JSON.parse(response.body)['rw-config-agent:account'];
1777 statusCode = response.statusCode;
1778 } catch (e) {
1779 console.log('Problem with "ConfigAgentAccount.get"', e);
1780 var err = {};
1781 err.statusCode = 500;
1782 err.errorMessage = {
1783 error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
1784 }
1785 return reject(err);
1786 }
1787
1788 return resolve({
1789 statusCode: statusCode,
1790 data: data
1791 });
1792 }
1793 });
1794 });
1795 }
1796 };
1797
1798 ConfigAgentAccount.create = function(req) {
1799
1800 var api_server = req.query["api_server"];
1801 var data = req.body;
1802
1803 return new Promise(function(resolve, reject) {
1804 var jsonData = {
1805 "account": Array.isArray(data) ? data : [data]
1806 };
1807
1808 console.log('Creating with', JSON.stringify(jsonData));
1809
1810 var requestHeaders = {};
1811 _.extend(requestHeaders,
1812 constants.HTTP_HEADERS.accept.data,
1813 constants.HTTP_HEADERS.content_type.data, {
1814 'Authorization': req.session && req.session.authorization
1815 });
1816
1817 request({
1818 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/config-agent'),
1819 method: 'POST',
1820 headers: requestHeaders,
1821 forever: constants.FOREVER_ON,
1822 rejectUnauthorized: false,
1823 json: jsonData,
1824 }, function(error, response, body) {
1825 if (utils.validateResponse('ConfigAgentAccount.create', error, response, body, resolve, reject)) {
1826 return resolve({
1827 statusCode: response.statusCode,
1828 data: JSON.stringify(response.body),
1829 body:response.body.body
1830 });
1831 };
1832 });
1833 });
1834 };
1835
1836 ConfigAgentAccount.update = function(req) {
1837
1838 var api_server = req.query["api_server"];
1839 var id = req.params.id;
1840 var data = req.body;
1841
1842 return new Promise(function(resolve, reject) {
1843 var jsonData = {
1844 "rw-config-agent:account": data
1845 };
1846
1847 console.log('Updating config-agent', id, ' with', JSON.stringify(jsonData));
1848
1849 var requestHeaders = {};
1850 _.extend(requestHeaders,
1851 constants.HTTP_HEADERS.accept.data,
1852 constants.HTTP_HEADERS.content_type.data, {
1853 'Authorization': req.session && req.session.authorization
1854 });
1855
1856 request({
1857 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + id),
1858 method: 'PUT',
1859 headers: requestHeaders,
1860 forever: constants.FOREVER_ON,
1861 rejectUnauthorized: false,
1862 json: jsonData,
1863 }, function(error, response, body) {
1864 if (utils.validateResponse('ConfigAgentAccount.update', error, response, body, resolve, reject)) {
1865 return resolve({
1866 statusCode: response.statusCode,
1867 data: JSON.stringify(response.body)
1868 });
1869 };
1870 });
1871 });
1872 };
1873
1874 ConfigAgentAccount.delete = function(req) {
1875
1876 var api_server = req.query["api_server"];
1877 var id = req.params.id;
1878
1879 if (!id || !api_server) {
1880 return new Promise(function(resolve, reject) {
1881 console.log('Must specifiy api_server and id to delete config-agent account');
1882 return reject({
1883 statusCode: 500,
1884 errorMessage: {
1885 error: 'Must specifiy api_server and id to delete config agent account'
1886 }
1887 });
1888 });
1889 };
1890
1891 return new Promise(function(resolve, reject) {
1892 var requestHeaders = {};
1893 _.extend(requestHeaders,
1894 constants.HTTP_HEADERS.accept.data, {
1895 'Authorization': req.session && req.session.authorization
1896 });
1897 request({
1898 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + id),
1899 method: 'DELETE',
1900 headers: requestHeaders,
1901 forever: constants.FOREVER_ON,
1902 rejectUnauthorized: false,
1903 }, function(error, response, body) {
1904 if (utils.validateResponse('ConfigAgentAccount.delete', error, response, body, resolve, reject)) {
1905 return resolve({
1906 statusCode: response.statusCode,
1907 data: JSON.stringify(response.body)
1908 });
1909 };
1910 });
1911 });
1912 };
1913
1914
1915 DataCenters.get = function(req) {
1916 var api_server = req.query["api_server"];
1917 return new Promise(function(resolve, reject) {
1918 var requestHeaders = {};
1919 _.extend(requestHeaders,
1920 constants.HTTP_HEADERS.accept.data, {
1921 'Authorization': req.session && req.session.authorization
1922 });
1923 request({
1924 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/datacenters?deep'),
1925 method: 'GET',
1926 headers: requestHeaders,
1927 forever: constants.FOREVER_ON,
1928 rejectUnauthorized: false,
1929 }, function(error, response, body) {
1930 if (utils.validateResponse('DataCenters.get', error, response, body, resolve, reject)) {
1931 var returnData = {};
1932 try {
1933 data = JSON.parse(response.body)["rw-launchpad:datacenters"]["ro-accounts"];
1934 data.map(function(c) {
1935 returnData[c.name] = c.datacenters;
1936 })
1937 statusCode = response.statusCode;
1938 } catch (e) {
1939 console.log('Problem with "DataCenters.get"', e);
1940 var err = {};
1941 err.statusCode = 500;
1942 err.errorMessage = {
1943 error: 'Problem with "DataCenters.get": ' + e.toString()
1944 }
1945 return reject(err);
1946 }
1947 return resolve({
1948 statusCode: response.statusCode,
1949 data: returnData
1950 });
1951 };
1952 });
1953 });
1954 }
1955
1956 SSHkey.get = function(req) {
1957 var api_server = req.query["api_server"];
1958 return new Promise(function(resolve, reject) {
1959 var requestHeaders = {};
1960 _.extend(requestHeaders,
1961 constants.HTTP_HEADERS.accept.data, {
1962 'Authorization': req.session && req.session.authorization
1963 });
1964 request({
1965 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair?deep'),
1966 method: 'GET',
1967 headers: requestHeaders,
1968 forever: constants.FOREVER_ON,
1969 rejectUnauthorized: false,
1970 }, function(error, response, body) {
1971 if (utils.validateResponse('SSHkey.get', error, response, body, resolve, reject)) {
1972 var returnData = {};
1973 try {
1974 returnData = JSON.parse(response.body)['nsr:key-pair'];
1975 statusCode = response.statusCode;
1976 } catch (e) {
1977 console.log('Problem with "SSHkey.get"', e);
1978 var err = {};
1979 err.statusCode = 500;
1980 err.errorMessage = {
1981 error: 'Problem with "SSHkey.get": ' + e.toString()
1982 }
1983 return reject(err);
1984 }
1985 return resolve({
1986 statusCode: response.statusCode,
1987 data: returnData
1988 });
1989 };
1990 });
1991 });
1992 }
1993 SSHkey.delete = function(req) {
1994 var api_server = req.query['api_server'];
1995 var id = decodeURI(req.params.name);
1996 console.log('Deleting ssk-key', id);
1997 return new Promise(function(resolve, reject) {
1998 request({
1999 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/' + id),
2000 method: 'DELETE',
2001 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
2002 'Authorization': req.session && req.session.authorization
2003 }),
2004 forever: constants.FOREVER_ON,
2005 rejectUnauthorized: false,
2006 }, function(error, response, body) {
2007 if (utils.validateResponse('SSHkey.delete', error, response, body, resolve, reject)) {
2008 resolve({
2009 statusCode: response.statusCode
2010 });
2011 }
2012 });
2013 });
2014 };
2015 SSHkey.post = function(req) {
2016 var api_server = req.query['api_server'];
2017 var data = req.body;
2018 return new Promise(function(resolve, reject) {
2019 request({
2020 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/'),
2021 method: 'POST',
2022 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
2023 'Authorization': req.session && req.session.authorization
2024 }),
2025 json: data,
2026 forever: constants.FOREVER_ON,
2027 rejectUnauthorized: false,
2028 }, function(error, response, body) {
2029 if (utils.validateResponse('SSHkey.post', error, response, body, resolve, reject)) {
2030 resolve({
2031 data: 'success',
2032 statusCode: response.statusCode
2033 });
2034 }
2035 });
2036 });
2037 };
2038 SSHkey.put = function(req) {
2039 var api_server = req.query['api_server'];
2040 var data = req.body;
2041 return new Promise(function(resolve, reject) {
2042 request({
2043 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/'),
2044 method: 'PUT',
2045 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
2046 'Authorization': req.session && req.session.authorization
2047 }),
2048 json: data,
2049 forever: constants.FOREVER_ON,
2050 rejectUnauthorized: false,
2051 }, function(error, response, body) {
2052 if (utils.validateResponse('SSHkey.put', error, response, body, resolve, reject)) {
2053 resolve({
2054 statusCode: response.statusCode
2055 });
2056 }
2057 });
2058 });
2059 };
2060
2061 function sortByName(a, b) {
2062 return a.name > b.name;
2063 }
2064
2065 module.exports.catalog = Catalog;
2066 module.exports.nsr = NSR;
2067 module.exports.vnfr = VNFR;
2068 module.exports.vlr = VLR;
2069 module.exports.vdur = VDUR;
2070 module.exports.rift = RIFT;
2071 module.exports.computeTopology = ComputeTopology;
2072 module.exports.networkTopology = NetworkTopology;
2073 module.exports.config = Config;
2074 module.exports.cloud_account = CloudAccount;
2075 module.exports['config-agent-account'] = ConfigAgentAccount;
2076 module.exports.rpc = RPC;
2077 module.exports.data_centers = DataCenters;
2078 module.exports.SSHkey = SSHkey;