Revert "BUG-410 -- update RIFT platform"
[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 ResourceOrchestratorAccount = {};
42 var ConfigAgentAccount = {};
43 var RPC = {};
44 var SSHkey = {};
45 // API Configuration Info
46 var APIConfig = {}
47 APIConfig.NfviMetrics = ['vcpu', 'memory'];
48
49 RPC.executeNSServicePrimitive = function(req) {
50 var api_server = req.query['api_server'];
51 return new Promise(function(resolve, reject) {
52 var uri = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operations/exec-ns-service-primitive');
53 var jsonData = {
54 "input": utils.addProjectContextToRPCPayload(req, uri, req.body)
55 };
56
57 var headers = _.extend({},
58 constants.HTTP_HEADERS.accept.data,
59 constants.HTTP_HEADERS.content_type.data, {
60 'Authorization': req.session && req.session.authorization
61 }
62 );
63 request({
64 url: uri,
65 method: 'POST',
66 headers: headers,
67 forever: constants.FOREVER_ON,
68 rejectUnauthorized: false,
69 json: jsonData
70 }, function(error, response, body) {
71 if (utils.validateResponse('RPC.executeNSServicePrimitive', error, response, body, resolve, reject)) {
72 return resolve({
73 statusCode: response.statusCode,
74 data: JSON.stringify(response.body)
75 });
76 }
77 })
78 });
79 };
80
81 RPC.getNSServicePrimitiveValues = function(req) {
82 var api_server = req.query['api_server'];
83 // var nsr_id = req.body['nsr_id_ref'];
84 // var nsConfigPrimitiveName = req.body['name'];
85 return new Promise(function(resolve, reject) {
86 var uri = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operations/get-ns-service-primitive-values');
87
88 var jsonData = {
89 "input": utils.addProjectContextToRPCPayload(req, uri, req.body)
90 };
91
92 var headers = _.extend({},
93 constants.HTTP_HEADERS.accept.data,
94 constants.HTTP_HEADERS.content_type.data, {
95 'Authorization': req.session && req.session.authorization
96 }
97 );
98 request({
99 uri: uri,
100 method: 'POST',
101 headers: headers,
102 forever: constants.FOREVER_ON,
103 rejectUnauthorized: false,
104 json: jsonData
105 }, function(error, response, body) {
106 if (utils.validateResponse('RPC.getNSServicePrimitiveValues', error, response, body, resolve, reject)) {
107
108 resolve({
109 statusCode: response.statusCode,
110 data: JSON.parse(body)
111 });
112 }
113 });
114 }).catch(function(error) {
115 console.log('error getting primitive values');
116 });
117 };
118 RPC.refreshAccountConnectionStatus = function(req) {
119 var api_server = req.query['api_server'];
120 var Name = req.params.name;
121 var Type = req.params.type;
122 var jsonData = {
123 input: {}
124 };
125 var rpcInfo = {
126 sdn: {
127 label: 'sdn-account',
128 rpc: 'update-sdn-status'
129 },
130 config: {
131 label: 'cfg-agent-account',
132 rpc: 'update-cfg-agent-status'
133 },
134 cloud: {
135 label: 'cloud-account',
136 rpc: 'update-cloud-status'
137 }
138 }
139 jsonData.input[rpcInfo[Type].label] = Name;
140
141 var uri = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operations/' + rpcInfo[Type].rpc);
142
143 jsonData.input = utils.addProjectContextToRPCPayload(req, uri, jsonData.input);
144
145 var headers = _.extend({},
146 constants.HTTP_HEADERS.accept.data,
147 constants.HTTP_HEADERS.content_type.data, {
148 'Authorization': req.session && req.session.authorization
149 }
150 );
151 return new Promise(function(resolve, reject) {
152 request({
153 uri: uri,
154 method: 'POST',
155 headers: headers,
156 forever: constants.FOREVER_ON,
157 rejectUnauthorized: false,
158 json: jsonData
159 }, function(error, response, body) {
160 if (utils.validateResponse('RPC.refreshAccountConnectionStatus', error, response, body, resolve, reject)) {
161
162 resolve({
163 statusCode: response.statusCode,
164 data: body
165 });
166 }
167 });
168 }).catch(function(error) {
169 console.log('Error refreshing account info');
170 });
171 };
172
173
174 var DataCenters = {};
175 // Catalog module methods
176 Catalog.get = function(req) {
177 var api_server = req.query['api_server'];
178 var results = {}
179 var projectPrefix = req.session.projectId ? "project-" : "";
180 return new Promise(function(resolve, reject) {
181 Promise.all([
182 rp({
183 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep'),
184 method: 'GET',
185 headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
186 'Authorization': req.session && req.session.authorization
187 }),
188 forever: constants.FOREVER_ON,
189 rejectUnauthorized: false,
190 resolveWithFullResponse: true
191 }),
192 rp({
193 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd?deep'),
194 method: 'GET',
195 headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
196 'Authorization': req.session && req.session.authorization
197 }),
198 forever: constants.FOREVER_ON,
199 rejectUnauthorized: false,
200 resolveWithFullResponse: true
201 }),
202 rp({
203 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata?deep'),
204 method: 'GET',
205 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
206 'Authorization': req.session && req.session.authorization
207 }),
208 forever: constants.FOREVER_ON,
209 rejectUnauthorized: false,
210 resolveWithFullResponse: true
211 })
212 // Not enabled for now
213 // rp({
214 // uri: utils.confdPort(api_server) + APIVersion + '/api/config/pnfd-catalog/pnfd?deep',
215 // method: 'GET',
216 // headers: _.extend({},
217 // constants.HTTP_HEADERS.accept.collection,
218 // {
219 // 'Authorization': req.session && req.session.authorization
220 // }),
221 // forever: constants.FOREVER_ON,
222 // rejectUnauthorized: false,
223 // resolveWithFullResponse: true
224 // })
225 ]).then(function(result) {
226 console.log('Resolved all request promises (NSD, VNFD) successfully');
227 var response = [{
228 "id": "GUID-1",
229 "name": "RIFT.wareâ„¢ NS Descriptors Catalog",
230 "short-name": "rift.ware-nsd-cat",
231 "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.",
232 "vendor": "RIFT.io",
233 "version": "",
234 "created-on": "",
235 "type": "nsd",
236 "meta": {
237 "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"
238 },
239 "descriptors": []
240 }, {
241 "id": "GUID-2",
242 "name": "RIFT.wareâ„¢ VNF Descriptors Catalog",
243 "short-name": "rift.ware-vnfd-cat",
244 "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.",
245 "vendor": "RIFT.io",
246 "version": "",
247 "created-on": "",
248 "type": "vnfd",
249 "meta": {
250 "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> "
251 },
252 "descriptors": []
253 }, {
254 "id": "GUID-3",
255 "name": "RIFT.wareâ„¢ PNF Descriptors Catalog",
256 "short-name": "rift.ware-pnfd-cat",
257 "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.",
258 "vendor": "RIFT.io",
259 "version": "",
260 "created-on": "",
261 "type": "pnfd",
262 "meta": {
263 "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>"
264 },
265 "descriptors": []
266 }];
267 var vnfdCatalog = null;
268 var vnfdDict = {};
269 if (result[1].body) {
270 response[1].descriptors = utils.dataToJsonSansPropNameNamespace(result[1].body).collection['vnfd'];
271 vnfdCatalog = response[1].descriptors.map(function(v, i) {
272 vnfdDict[v.id] = v['short-name'] || v.name;
273 })
274 }
275 if (result[0].body) {
276 response[0].descriptors = utils.dataToJsonSansPropNameNamespace(result[0].body).collection['nsd'];
277 if (result[2].body) {
278 var data = JSON.parse(result[2].body);
279 if (data && data["ns-instance-opdata"]) {
280 response[0].descriptors.map(function(nsd) {
281 if (!nsd["meta"]) {
282 nsd["meta"] = {};
283 }
284 if (typeof nsd['meta'] == 'string') {
285 nsd['meta'] = JSON.parse(nsd['meta']);
286 }
287 nsd["constituent-vnfd"] && nsd["constituent-vnfd"].map(function(v) {
288 v.name = vnfdDict[v["vnfd-id-ref"]];
289 })
290 });
291 }
292 }
293 };
294 resolve({
295 statusCode: response.statusCode || 200,
296 data: JSON.stringify(response)
297 });
298 }).catch(function(error) {
299 // Todo: Need better logic than all or nothing.
300 // Right now even if one of the southbound APIs fails - all fail
301 var res = {};
302 console.log('Problem with Catalog.get', error);
303 res.statusCode = error.statusCode || 500;
304 res.errorMessage = {
305 error: 'Failed to get catalogs' + error
306 };
307 reject(res);
308 });
309 });
310 };
311 Catalog.delete = function(req) {
312 var api_server = req.query['api_server'];
313 var catalogType = req.params.catalogType;
314 var id = req.params.id;
315 console.log('Deleting', catalogType, id, 'from', api_server);
316 return new Promise(function(resolve, reject) {
317 request({
318 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog/' + catalogType + '/' + encodeURIComponent(id)),
319 method: 'DELETE',
320 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
321 'Authorization': req.session && req.session.authorization
322 }),
323 forever: constants.FOREVER_ON,
324 rejectUnauthorized: false,
325 }, function(error, response, body) {
326 if (utils.validateResponse('Catalog.delete', error, response, body, resolve, reject)) {
327 resolve({
328 statusCode: response.statusCode
329 });
330 }
331 });
332 });
333 };
334 Catalog.getVNFD = function(req) {
335 var api_server = req.query['api_server'];
336 var vnfdID = req.body.data;
337 var authorization = req.session && req.session.authorization;
338 var VNFDs = [];
339 if (typeof(vnfdID) == "object" && vnfdID.constructor.name == "Array") {
340 vnfdID.map(function(id) {
341 VNFDs.push(requestVNFD(id));
342 });
343 } else {
344 VNFDs.push(requestVNFD(vnfdID));
345 }
346 return new Promise(function(resolve, reject) {
347 Promise.all(VNFDs).then(function(data) {
348 resolve(data)
349 }).catch(function(error) {
350 // Todo: Need better logic than all or nothing.
351 // Right now even if one of the southbound APIs fails - all fail
352 var res = {};
353 console.log('Problem with Catalog.getVNFD', error);
354 res.statusCode = 404;
355 res.errorMessage = {
356 error: 'Failed to get VNFDs' + error
357 };
358 reject(res);
359 });
360 });
361
362 function requestVNFD(id) {
363 return new Promise(function(resolve, reject) {
364 var url = utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd' + (id ? '/' + encodeURIComponent(id) : '') + '?deep';
365 request({
366 uri: utils.projectContextUrl(req, url),
367 method: 'GET',
368 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
369 'Authorization': authorization
370 }),
371 forever: constants.FOREVER_ON,
372 rejectUnauthorized: false,
373 }, function(error, response, body) {
374 if (utils.validateResponse('Catalog.getVNFD', error, response, body, resolve, reject)) {
375 var data;
376 //Is this still needed?
377 try {
378 data = JSON.parse(response.body)
379 } catch (e) {
380 reject({
381 statusCode: response ? response.statusCode : 400,
382 errorMessage: 'Issue parsing VNFD ' + id + 'from ' + utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd/' + id + '?deep'
383 });
384 }
385 resolve(data);
386 }
387 });
388 });
389 }
390 };
391 Catalog.create = function(req) {
392 var api_server = req.query['api_server'];
393 var catalogType = req.params.catalogType;
394 var data = req.body;
395 console.log('Creating', catalogType, 'on', api_server);
396 var jsonData = {};
397 jsonData[catalogType] = [];
398 jsonData[catalogType].push(data);
399 return new Promise(function(resolve, reject) {
400 var requestHeaders = {};
401 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
402 'Authorization': req.session && req.session.authorization
403 });
404 request({
405 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog'),
406 method: 'POST',
407 headers: requestHeaders,
408 forever: constants.FOREVER_ON,
409 rejectUnauthorized: false,
410 json: jsonData
411 }, function(error, response, body) {
412 if (utils.validateResponse('Catalog.create', error, response, body, resolve, reject)) {
413 resolve({
414 statusCode: response.statusCode
415 });
416 }
417 });
418 });
419 };
420 Catalog.update = function(req) {
421 var api_server = req.query['api_server'];
422 var catalogType = req.params.catalogType;
423 var id = req.params.id;
424 var data = req.body;
425 console.log('Updating', catalogType, 'id', id, 'on', api_server);
426 var jsonData = {};
427 jsonData[catalogType] = {};
428 jsonData[catalogType] = data;
429 return new Promise(function(resolve, reject) {
430 var requestHeaders = {};
431 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
432 'Authorization': req.session && req.session.authorization
433 });
434 request({
435 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog' + '/' + catalogType + '/' + encodeURIComponent(id)),
436 method: 'PUT',
437 headers: requestHeaders,
438 forever: constants.FOREVER_ON,
439 rejectUnauthorized: false,
440 json: jsonData
441 }, function(error, response, body) {
442 if (utils.validateResponse('Catalog.update', error, response, body, resolve, reject)) {
443 resolve({
444 statusCode: response.statusCode
445 });
446 }
447 });
448 });
449 };
450
451 Catalog.decorateNsdCatalogWithPlacementGroups = function decorateNsdCatalogWithPlacementGroups(catalog) {
452 var newData = catalog;
453 var parsedCatalog = JSON.parse(catalog.data);
454 var nsds = parsedCatalog[0].descriptors;
455 var vnfds = parsedCatalog[1].descriptors;
456 var vnfdDict = (function(){
457 var dict = {};
458 vnfds.map(function(v, i) {
459 dict[v.id] = v;
460 })
461 return dict;
462 })(vnfds);
463
464 nsds.map(function(c, i) {
465 //Rename and decorate NSD placement groups
466 c['ns-placement-groups'] = c['placement-groups'] && c['placement-groups'].map(function(p, i) {
467 //Adds vnfd name to member-vnfd entry
468 p['member-vnfd'] = p['member-vnfd'].map(function(v) {
469 v.name = vnfdDict[v['vnfd-id-ref']].name;
470 return v;
471 });
472 p['host-aggregate'] = [];
473 return p;
474 });
475
476 //Adds vnf placement groups to nsd object for UI
477 c['vnf-placement-groups'] = [];
478 c['constituent-vnfd'] && c['constituent-vnfd'].map(function(v) {
479 var vnf = vnfdDict[v['vnfd-id-ref']];
480 // var vnfPg = {
481 // name: vnf.name,
482 // 'placement-groups': vnf['placement-groups'].map(function(vp){
483 // vp['host-aggregate'] = [{}];
484 // return vp;
485 // })
486 // };
487 v['vnf-name'] = vnf.name;
488 vnf['placement-groups'] && vnf['placement-groups'].map(function(vp) {
489 vp['host-aggregate'] = [];
490 vp['vnf-name'] = vnf.name;
491 vp['vnfd-id-ref'] = v['vnfd-id-ref'];
492 vp['member-vnf-index'] = v['member-vnf-index'];
493 c['vnf-placement-groups'].push(vp);
494 })
495 })
496 return c;
497 })
498 // parsedCatalog[0].descriptors = nsds;
499 newData.data = JSON.stringify(parsedCatalog);
500 return newData;
501 }
502
503 // NSR module methods
504 // Spend some time refactoring this
505 // refactor to accept only request object
506 NSR.get = function(req) {
507 var self = this;
508 var nsrPromises = [];
509 var api_server = req.query["api_server"];
510 var id = req.params.id;
511 var projectPrefix = req.session.projectId ? "project-" : "";
512 var vnfdInfo = new Promise(function(resolve, reject) {
513 request({
514 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd'),
515 method: 'GET',
516 headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, {
517 'Authorization': req.session && req.session.authorization
518 }),
519 forever: constants.FOREVER_ON,
520 rejectUnauthorized: false,
521 }, function(error, response, body) {
522 if (utils.validateResponse('NSR.get vnfd-catalog', error, response, body, resolve, reject)) {
523 var data;
524 var isString = typeof(response.body) == "string";
525 if (isString && response.body == '') return resolve('empty');
526 data = isString ? JSON.parse(response.body) : response.body;
527 var vnfdData = data.collection[projectPrefix + "vnfd:vnfd"];
528 if (vnfdData.constructor.name == "Object") {
529 vnfdData = [vnfdData];
530 }
531 var vnfdDict = {};
532 vnfdData.map(function(v, i) {
533 vnfdDict[v.id] = v;
534 })
535 resolve(vnfdDict);
536 };
537 })//
538 })
539 var config = new Promise(function(resolve, reject) {
540 request({
541 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-config/nsr' + (id ? '/' + encodeURIComponent(id) : '') + '?deep'),
542 method: 'GET',
543 headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
544 'Authorization': req.session && req.session.authorization
545 }),
546 forever: constants.FOREVER_ON,
547 rejectUnauthorized: false,
548 }, function(error, response, body) {
549 if (utils.validateResponse('NSR.get ns-instance-config', error, response, body, resolve, reject)) {
550 var data;
551 var isString = typeof(response.body) == "string";
552 if (isString && response.body == '') return resolve();
553 data = isString ? JSON.parse(response.body) : response.body;
554 data = id ? data : data.collection;
555 var nsrData = data["nsr:nsr"];
556 if (nsrData.constructor.name == "Object") {
557 nsrData = [nsrData];
558 }
559 resolve(nsrData);
560 };
561 });
562 });
563 var opData = new Promise(function(resolve, reject) {
564 request({
565 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr' + (id ? '/' + encodeURIComponent(id) : '') + '?deep'),
566 method: 'GET',
567 headers: _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
568 'Authorization': req.session && req.session.authorization
569 }),
570 forever: constants.FOREVER_ON,
571 rejectUnauthorized: false,
572 }, function(error, response, body) {
573 if (utils.validateResponse('NSR.get ns-instance-opdata', error, response, body, resolve, reject)) {
574 var data;
575 var isString = typeof(response.body) == "string";
576 if (isString && response.body == '') return resolve();
577 data = isString ? JSON.parse(response.body) : response.body;
578 data = id ? data : data.collection;
579 var nsrData = data["nsr:nsr"];
580 if (nsrData.constructor.name == "Object") {
581 nsrData = [nsrData];
582 }
583 nsrData.forEach(self.decorateWithScalingGroupDict);
584 nsrData.forEach(self.decorateAndTransformNFVI);
585 nsrData.forEach(self.decorateAndTransformWithControls);
586 Promise.all(self.addVnfrDataPromise(req, nsrData)).then(function() {
587 Promise.all(self.addVlrDataPromise(req, nsrData)).then(function() {
588 resolve(nsrData);
589 });
590 });
591 };
592 });
593 }).catch(function(error) {
594 console.log('error getting aggregated NS opdata', error)
595 //note this will actually trigger the success callback
596 });
597 return new Promise(function(resolve, reject) {
598 //Need smarter error handling here
599 Promise.all([config, opData, vnfdInfo]).then(function(resolves) {
600 var aggregate = {};
601 // resolves[0] ==> ns-instance-config
602 // resolves[1] ==> ns-instance-opdata
603
604 var nsInstanceConfig = resolves[0] && resolves[0];
605 var nsInstanceOpdata = resolves[1] && resolves[1];
606 var vnfdCatalog = resolves[2];
607
608 if (!nsInstanceConfig && !nsInstanceOpdata) {
609 return resolve({
610 nsrs: []
611 });
612 }
613
614 nsInstanceConfig.forEach(function(v, k) {
615 v.nsd_name = v['nsd'] && v['nsd']['name'];
616 var scaling_group_descriptor = null;
617
618 scaling_group_descriptor = v['nsd'] && v['nsd']['scaling-group-descriptor'];
619
620 if (scaling_group_descriptor) {
621 scaling_group_descriptor.map(function(sgd, sgdi) {
622 sgd['vnfd-member'] && sgd['vnfd-member'].map(function(vnfd, vnfdi) {
623 var vnfrObj = _.findWhere(_.findWhere(nsInstanceOpdata, {
624 'ns-instance-config-ref': v.id
625 }).vnfrs, {
626 'member-vnf-index-ref': vnfd['member-vnf-index-ref']
627 });
628 if (vnfrObj) {
629 var vnfdId = _.findWhere(v.nsd['constituent-vnfd'], {'member-vnf-index': vnfrObj['member-vnf-index-ref']})['vnfd-id-ref'];
630 vnfd['short-name'] = vnfrObj['short-name'];
631 vnfd['vnfd'] = {id: vnfrObj.id, logo: vnfdCatalog[vnfdId]['logo']}
632 }
633 })
634 })
635 v['scaling-group-descriptor'] = scaling_group_descriptor;
636 }
637
638 if (nsInstanceOpdata && nsInstanceOpdata.constructor.name == "Array") {
639 nsInstanceOpdata.forEach(function(w, l) {
640 if (v.id == w["ns-instance-config-ref"]) {
641 for (prop in w) {
642 if (prop != "ns-instance-config-ref" && !v.hasOwnProperty(prop)) {
643 v[prop] = w[prop];
644 }
645 }
646 }
647 });
648 }
649
650 v['scaling-group-record'] && v['scaling-group-record'].map(function(sgr) {
651 var scalingGroupName = sgr['scaling-group-name-ref'];
652 sgr['instance'] && sgr['instance'].map(function(instance) {
653 var scalingGroupInstanceId = instance['instance-id'];
654 instance['vnfrs'] && instance['vnfrs'].map(function(vnfr) {
655 var vnfrObj = _.findWhere(v['vnfrs'], {id: vnfr});
656 if (vnfrObj) {
657 vnfrObj['scaling-group-name'] = scalingGroupName;
658 vnfrObj['scaling-group-instance-id'] = scalingGroupInstanceId;
659 }
660 });
661 });
662 });
663
664 v['vnfrs'] && v['vnfrs'].map(function(vnfrObj){
665 var vnfdId = _.findWhere(v.nsd['constituent-vnfd'], {'member-vnf-index': vnfrObj['member-vnf-index-ref']})['vnfd-id-ref'];
666 vnfrObj.vnfd = vnfdCatalog[vnfdId];
667 });
668 });
669 var nsrsData = nsInstanceConfig;
670 nsrsData.sort(function(a, b) {
671 return a["create-time"] - b["create-time"];
672 });
673 resolve({
674 nsrs: nsrsData
675 });
676 }).catch(function(error) {
677 reject({
678 statusCode: 404,
679 errorMessage: error
680 })
681 })
682 });
683 };
684 // Static VNFR Cache bu VNFR ID
685 var staticVNFRCache = {};
686
687 /**
688 * [decorateWithScalingGroupDict description]
689 * @param {[type]} nsr [description]
690 * @return {[type]}
691 {vnfr-id} : {
692 "scaling-group-name-ref": "sg1",
693 "instance-id": 0,
694 "op-status": "running",
695 "is-default": "true",
696 "create-time": 1463593760,
697 "config-status": "configuring",
698 "vnfrs": [
699 "432154e3-164e-4c05-83ee-3b56e4c898e7"
700 ]
701 }
702 */
703 NSR.decorateWithScalingGroupDict = function(nsr) {
704 var sg = nsr["scaling-group-record"];
705 var dict = {};
706 if(sg) {
707 sg.map(function(s) {
708 var sgRef = s['scaling-group-name-ref'];
709 s.instance && s.instance.map(function(si) {
710 si.vnfrs && si.vnfrs.map(function(v) {
711 dict[v] = si;
712 dict[v]["scaling-group-name-ref"] = sgRef;
713 })
714 })
715 })
716 }
717 return nsr['vnfr-scaling-groups'] = dict;
718 }
719
720
721 NSR.addVlrDataPromise = function(req, nsrs) {
722 var api_server = req.query['api_server'];
723 var promises = [];
724 nsrs.map(function(nsr) {
725 var vlrPromises = [];
726 var vlr = nsr['vlr'];
727 nsr['decorated-vlrs'] = [];
728 if (!vlr) {
729 console.log('No VL\'s found in NS');
730 }
731 vlr && vlr.map(function(vlrObject) {
732 req.params.id = vlrObject['vlr-ref'];
733 var vlrPromise = VLR.get(req).then(function(vlr) {
734 try {
735 var vlrItem = vlr['data'][0];
736 decorateNSRWithVLR(nsr, vlrObject, vlrItem);
737 } catch (e) {
738 console.log('Expection caught getting VLRs and adding to NSR:', e);
739 }
740 })
741 vlrPromises.push(vlrPromise);
742 });
743 var NSR_Promise = new Promise(function(resolve, reject) {
744 Promise.all(vlrPromises).then(function() {
745 resolve();
746 })
747 });
748 promises.push(NSR_Promise);
749 });
750 return promises;
751
752 function decorateNSRWithVLR(nsr, nsrVLRObject, vlr) {
753 var vlrObject = _.extend(nsrVLRObject, vlr);
754 vlrObject['vnfr-connection-point-ref'] && vlrObject['vnfr-connection-point-ref'].map(function(vnfrCP) {
755 var vnfrName = nsr['vnfrs'] && nsr['vnfrs'].length && _.findWhere(nsr['vnfrs'], {id: vnfrCP['vnfr-id']})['name'];
756 vnfrName && (vnfrCP['vnfr-name'] = vnfrName);
757 });
758 nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'name'), 0, vlrObject);
759 // nsr['decorated-vlrs'].splice(_.sortedIndex(nsr['decorated-vlrs'], vlrObject, 'create-time'), 0, vlrObject);
760 }
761 }
762
763
764 NSR.addVnfrDataPromise = function(req, nsrs) {
765 var api_server = req.query['api_server'];
766 var promises = [];
767 nsrs.map(function(nsr) {
768 var epa_params = {};
769 var constituent_vnfr_ref = nsr["constituent-vnfr-ref"];
770 var vnfrPromises = [];
771 nsr["vnfrs"] = [];
772 nsr["dashboard-urls"] = [];
773 nsr['nfvi-metrics'] = [];
774 if (!constituent_vnfr_ref) {
775 console.log('Something is wrong, there are no constituent-vnfr-refs');
776 constituent_vnfr_ref = [];
777 }
778 //Get VNFR Static Data
779 constituent_vnfr_ref && constituent_vnfr_ref.map(function(constituentVnfrObj) {
780 req.params.id = constituentVnfrObj['vnfr-id'];
781 var vnfrPromise;
782 vnfrPromise = VNFR.get(req).then(function(vnfr) {
783 try {
784 var vnfrItem = vnfr[0];
785 decorateNSRWithVNFR(nsr, vnfrItem)
786 staticVNFRCache[vnfrItem.id] = vnfrItem;
787 } catch (e) {
788 console.log('Exception caught:', e);
789 }
790 });
791 vnfrPromises.push(vnfrPromise);
792 });
793 var NSR_Promise = new Promise(function(resolve, reject) {
794 Promise.all(vnfrPromises).then(function() {
795 var vnfrs = staticVNFRCache;
796 //Aggregate EPA Params
797 constituent_vnfr_ref && constituent_vnfr_ref.map(function(k) {
798 if (vnfrs[k['vnfr-id']]) {
799 epa_params = epa_aggregator(vnfrs[k['vnfr-id']].vdur, epa_params);
800 }
801 })
802 //Add VNFR Name to monitoring params
803 try {
804 if (nsr["monitoring-param"]) {
805 nsr["monitoring-param"].map(function(m) {
806 // var vnfr = vnfrs[m["vnfr-id"]] || {};
807 // m["vnfr-name"] = vnfr['name'] ? vnfr['name'] : (vnfr['short-name'] ? vnfr['short-name'] : 'VNFR');
808 var groupTag = m['group-tag'];
809 var vnfrId = m['vnfr-mon-param-ref'] && m['vnfr-mon-param-ref'][0] && m['vnfr-mon-param-ref'][0]['vnfr-id-ref'];
810 var vnfr = vnfrs[vnfrId] || {};
811 m["vnfr-name"] = vnfr['name'] ? vnfr['name'] : (vnfr['short-name'] ? vnfr['short-name'] : 'VNFR');
812 m['group-tag'] = (groupTag ? (groupTag + ' - ') : '') + m['vnfr-name'] + (vnfrId ? ' (' + vnfrId.substring(1,8) + '...)' : '');
813
814 });
815 }
816 } catch (e) {
817 console.log('Exception caught:', e);
818 }
819 resolve();
820 })
821 })
822 nsr["epa-params"] = epa_params;
823 promises.push(NSR_Promise);
824 })
825 return promises;
826
827 function decorateNSRWithVDURConsoleUrls(nsr, vnfr) {
828 nsr['console-urls'] = nsr['console-urls'] ? nsr['console-urls'] : [];
829
830 vnfr && vnfr['vdur'] && vnfr['vdur'].map(function(vdur) {
831 // This console-url is what front-end will hit to generate a real console-url
832 vdur['console-url'] = 'api/vnfr/' + encodeURIComponent(vnfr.id) + '/vdur/' + encodeURIComponent(vdur.id) + '/console-url';
833 nsr['console-urls'].push({
834 id: vdur.id,
835 name: vnfr.name,
836 'console-url': vdur['console-url']
837 });
838 });
839 }
840
841 function decorateNSRWithVNFR(nsr, vnfr) {
842 var vnfrObj = {
843 id: vnfr.id,
844 "member-vnf-index-ref": vnfr["member-vnf-index-ref"],
845 "short-name": vnfr["short-name"],
846 "vnf-configuration": vnfr["vnf-configuration"],
847 "nsr-id": nsr['ns-instance-config-ref'],
848 "name": vnfr['name'],
849 "vdur": vnfr["vdur"],
850 "datacenter": vnfr["datacenter"]
851 };
852 var vnfrSg = nsr['vnfr-scaling-groups'];
853 var vnfrName = vnfr["name"];
854 if(vnfrSg) {
855 if(vnfrSg[vnfr.id]) {
856 vnfrName = vnfrSg[vnfr.id]["scaling-group-name-ref"] + ':' + vnfrSg[vnfr.id][ "instance-id"] + ':' + vnfrName;
857 }
858 }
859 var vnfrNfviMetrics = buildNfviGraphs(vnfr.vdur, vnfrName);
860 if (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['config-primitive'] && vnfr['vnf-configuration']['config-primitive'].length > 0) {
861 vnfrObj['service-primitives-present'] = true;
862 } else {
863 vnfrObj['service-primitives-present'] = false;
864 }
865 transforms.mergeVnfrNfviMetrics(vnfrNfviMetrics, nsr["nfvi-metrics"]);
866 //TODO: Should be sorted by create-time when it becomes available instead of id
867 // nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'create-time'), 0, vnfrObj);
868 nsr["vnfrs"].splice(_.sortedIndex(nsr['vnfrs'], vnfrObj, 'id'), 0, vnfrObj);
869 vnfrObj["dashboard-url"] = vnfr["dashboard-url"];
870 nsr["dashboard-urls"].push(vnfrObj);
871
872 decorateNSRWithVDURConsoleUrls(nsr, vnfr);
873 }
874 }
875 NSR.create = function(req) {
876 var api_server = req.query['api_server'];
877 var data = req.body.data;
878 console.log('Instantiating NSR on ', api_server);
879 return new Promise(function(resolve, reject) {
880 var requestHeaders = {};
881 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
882 'Authorization': req.session && req.session.authorization
883 });
884 request({
885 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config'),
886 method: 'POST',
887 headers: requestHeaders,
888 forever: constants.FOREVER_ON,
889 rejectUnauthorized: false,
890 json: data
891 }, function(error, response, body) {
892 if (utils.validateResponse('NSR.create', error, response, body, resolve, reject)) {
893 var nsr_id = null;
894 try {
895 nsr_id = data.nsr[0].id;
896 } catch (e) {
897 console.log("NSR.create unable to get nsr_id. Error: %s",
898 e.toString());
899 }
900 resolve({
901 statusCode: response.statusCode,
902 data: { nsr_id: nsr_id }
903 });
904 };
905 });
906 });
907 };
908 NSR.delete = function(req) {
909 var api_server = req.query["api_server"];
910 var id = req.params.id;
911 if (!id || !api_server) {
912 return new Promise(function(resolve, reject) {
913 console.log('Must specifiy api_server and id to delete NSR');
914 return reject({
915 statusCode: 500,
916 errorMessage: {
917 error: 'Must specifiy api_server and id to delete NSR'
918 }
919 });
920 });
921 };
922 console.log('Deleting NSR with id: ' + id + 'on server: ' + api_server);
923 return new Promise(function(resolve, reject) {
924 var requestHeaders = {};
925 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, {
926 'Authorization': req.session && req.session.authorization
927 });
928 request({
929 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(id)),
930 method: 'DELETE',
931 headers: requestHeaders,
932 forever: constants.FOREVER_ON,
933 rejectUnauthorized: false,
934 }, function(error, response, body) {
935 if (utils.validateResponse('NSR.delete', error, response, body, resolve, reject)) {
936 resolve({
937 statusCode: response.statusCode,
938 data: JSON.stringify(response.body)
939 });
940 };
941 });
942 });
943 };
944 NSR.decorateAndTransformNFVI = function(nsr) {
945 var toDecorate = [];
946 // var metricsToUse = ["vcpu", "memory", "storage", "network"];
947 var metricsToUse = ["vcpu", "memory"];
948 try {
949 var nfviMetrics = nsr["rw-nsr:nfvi-metrics"];
950 if (nfviMetrics) {
951 metricsToUse.map(function(name) {
952 toDecorate.push(nfviMetrics[name])
953 });
954 }
955 nsr["nfvi-metrics"] = toDecorate;
956 delete nsr["rw-nsr:nfvi-metrics"];
957 } catch (e) {}
958 return nsr;
959 }
960 //Not a great pattern, Need a better way of handling logging;
961 //Refactor and move to the logging/logging.js
962 var logCache = {
963 decorateAndTransformWithControls: {}
964 }
965 NSR.decorateAndTransformWithControls = function(nsr) {
966 var controlTypes = ["action-param", "control-param"];
967 var nsControls = [];
968 var Groups = {};
969 controlTypes.map(function(control) {
970 try {
971 var controls = nsr["rw-nsr:" + control];
972 // nsControls.push(controls);
973 controls.map(function(item) {
974 if (!Groups[item["group-tag"]]) {
975 Groups[item["group-tag"]] = {};
976 Groups[item["group-tag"]]["action-param"] = []
977 Groups[item["group-tag"]]["control-param"] = []
978 }
979 Groups[item["group-tag"]][control].push(item);
980 });
981 delete nsr["rw-nsr:" + control];
982 } catch (e) {
983 var id = nsr["ns-instance-config-ref"];
984 if (!logCache.decorateAndTransformWithControls[id]) {
985 logCache.decorateAndTransformWithControls[id] = {};
986 }
987 var log = logCache.decorateAndTransformWithControls[id];
988 if (!log[control]) {
989 log[control] = true;
990 console.log('No controls exist for ' + control + ' at ' + nsr["ns-instance-config-ref"]);
991 }
992 }
993 });
994 for (k in Groups) {
995 var obj = {}
996 obj[k] = Groups[k];
997 nsControls.push(obj)
998 }
999 nsr.nsControls = nsControls;
1000 return nsr;
1001 };
1002 NSR.setStatus = function(req) {
1003 var api_server = req.query['api_server'];
1004 var id = req.params.id;
1005 var status = req.body.status;
1006 console.log('Setting NSR (id: ' + id + ') status, on ' + api_server + ', to be: ' + status);
1007 return new Promise(function(resolve, reject) {
1008 var command;
1009 if (typeof(status) != "string") {
1010 reject({
1011 'ERROR': 'NSR.setStatus Error: status is not a string type'
1012 });
1013 }
1014 command = status.toUpperCase();
1015 if (command != "ENABLED" && command != "DISABLED") {
1016 reject({
1017 'ERROR': 'NSR.setStatus Error: status is: ' + command + '. It should be ENABLED or DISABLED'
1018 });
1019 }
1020 var requestHeaders = {};
1021 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
1022 'Authorization': req.session && req.session.authorization
1023 });
1024 request({
1025 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(id) + '/admin-status/'),
1026 method: 'PUT',
1027 headers: requestHeaders,
1028 json: {
1029 "nsr:admin-status": command
1030 },
1031 forever: constants.FOREVER_ON,
1032 rejectUnauthorized: false,
1033 }, function(error, response, body) {
1034 if (utils.validateResponse('NSR.setStatus', error, response, body, resolve, reject)) {
1035 resolve({
1036 statusCode: response.statusCode
1037 });
1038 };
1039 });
1040 });
1041 };
1042
1043 NSR.createScalingGroupInstance = function(req) {
1044 var api_server = req.query['api_server'];
1045 var id = req.params.id;
1046 var scaling_group_id = req.params.scaling_group_id;
1047 if (!api_server || !id || !scaling_group_id) {
1048 return new Promise(function(resolve, reject) {
1049 return reject({
1050 statusCode: 500,
1051 errorMessage: {
1052 error: 'API server/NSR id/Scaling group not provided'
1053 }
1054 });
1055 });
1056 }
1057
1058 var instance_id = Math.floor(Math.random() * 65535);
1059
1060 var jsonData = {
1061 instance: [{
1062 // id: uuid.v1()
1063 id: instance_id
1064 }]
1065 };
1066
1067 console.log('Creating scaling group instance for NSR ', id, ', scaling group ', scaling_group_id, ' with instance id ', instance_id);
1068
1069 return new Promise(function(resolve, reject) {
1070 var requestHeaders = {};
1071 _.extend(requestHeaders,
1072 constants.HTTP_HEADERS.accept.data,
1073 constants.HTTP_HEADERS.content_type.data,
1074 {
1075 'Authorization': req.session && req.session.authorization
1076 }
1077 );
1078
1079 request({
1080 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(id) + '/scaling-group/' + encodeURIComponent(scaling_group_id) + '/instance'),
1081 method: 'POST',
1082 headers: requestHeaders,
1083 json: jsonData,
1084 forever: constants.FOREVER_ON,
1085 rejectUnauthorized: false
1086 }, function (error, response, body) {
1087 if (utils.validateResponse('NSR.createScalingGroupInstance', error, response, body, resolve, reject)) {
1088 resolve({
1089 statusCode: response.statusCode,
1090 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1091 })
1092 }
1093 });
1094 });
1095 };
1096
1097 NSR.deleteScalingGroupInstance = function(req) {
1098 var api_server=req.query['api_server'];
1099 var id = req.params.id;
1100 var scaling_group_id = req.params.scaling_group_id;
1101 var scaling_instance_id = req.params.scaling_instance_id;
1102
1103 if (!api_server || !id || !scaling_group_id || !scaling_instance_id) {
1104 return new Promise(function(resolve, reject) {
1105 return reject({
1106 statusCode: 500,
1107 errorMessage: {
1108 error: 'API server/NSR id/Scaling group/Scaling instance id not provided'
1109 }
1110 });
1111 });
1112 }
1113
1114 console.log('Deleting scaling group instance id ', scaling_instance_id,
1115 ' for scaling group ', scaling_group_id,
1116 ', under NSR ', id);
1117
1118 return new Promise(function(resolve, reject) {
1119 var requestHeaders = {};
1120 _.extend(requestHeaders,
1121 constants.HTTP_HEADERS.accept.data,
1122 constants.HTTP_HEADERS.content_type.data,
1123 {
1124 'Authorization': req.session && req.session.authorization
1125 }
1126 );
1127
1128 request({
1129 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(id) + '/scaling-group/' + encodeURIComponent(scaling_group_id) + '/instance/' + encodeURIComponent(scaling_instance_id)),
1130 method: 'DELETE',
1131 headers: requestHeaders,
1132 forever: constants.FOREVER_ON,
1133 rejectUnauthorized: false
1134 }, function (error, response, body) {
1135 if (utils.validateResponse('NSR.deleteScalingGroupInstance', error, response, body, resolve, reject)) {
1136 resolve({
1137 statusCode: response.statusCode,
1138 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1139 })
1140 }
1141 });
1142 });
1143 };
1144
1145 NSR.nsd = {};
1146 NSR.nsd.vld = {};
1147
1148 NSR.nsd.vld.get = function(req) {
1149 var api_server = req.query['api_server'];
1150 var nsr_id = req.params.nsr_id;
1151 var vld_id = req.params.vld_id;
1152
1153 if (!api_server || !nsr_id) {
1154 return new Promise(function(resolve, reject) {
1155 return reject({
1156 statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
1157 errorMessage: 'API server/NSR id not provided'
1158 });
1159 })
1160 }
1161 console.log('Getting VLD', vld_id ? (' ' + vld_id) : ('\'s'), ' for NSR id', nsr_id);
1162
1163 return new Promise(function(resolve, reject) {
1164 var requestHeaders = {};
1165 _.extend(requestHeaders,
1166 vld_id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection,
1167 {
1168 'Authorization': req.session && req.session.authorization
1169 }
1170 );
1171
1172 request({
1173 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(nsr_id) + '/nsd/vld' + (vld_id ? '/' + encodeURIComponent(vld_id) : '') +'?deep'),
1174 method: 'GET',
1175 headers: requestHeaders,
1176 forever: constants.FOREVER_ON,
1177 rejectUnauthorized: false
1178 }, function (error, response, body) {
1179 if (utils.validateResponse('NSR.nsd.vld.get', error, response, body, resolve, reject)) {
1180 resolve({
1181 statusCode: response.statusCode,
1182 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1183 });
1184 }
1185 });
1186 });
1187 };
1188
1189 NSR.nsd.vld.create = function(req) {
1190 var api_server = req.query['api_server'];
1191 var nsr_id = req.params.nsr_id;
1192 var vld_id = req.params.vld_id;
1193 var data = req.body;
1194
1195 if (!api_server || !nsr_id) {
1196 return new Promise(function(resolve, reject) {
1197 return reject({
1198 statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
1199 errorMessage: 'API server/NSR id not provided'
1200 });
1201 });
1202 }
1203
1204 console.log((vld_id ? 'Updating VLD ' + vld_id : 'Creating VLD') + ' under NSR', nsr_id);
1205
1206 var jsonData = {
1207 vld: typeof(data) == 'string' ? JSON.parse(data) : data
1208 };
1209
1210 return new Promise(function(resolve, reject) {
1211 var requestHeaders = {};
1212 _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, {
1213 'Authorization': req.session && req.session.authorization
1214 });
1215 request({
1216 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(nsr_id) + '/nsd/vld' + (vld_id ? '/' + encodeURIComponent(vld_id) : '')),
1217 method: vld_id ? 'PUT' : 'POST',
1218 headers: requestHeaders,
1219 forever: constants.FOREVER_ON,
1220 rejectUnauthorized: false,
1221 json: jsonData
1222 }, function(error, response, body) {
1223 if (utils.validateResponse('NSR.nsd.vld.create/update', error, response, body, resolve, reject)) {
1224 resolve({
1225 statusCode: response.statusCode,
1226 data: (typeof(response.body) == 'string') ? JSON.parse(response.body) : response.body
1227 });
1228 }
1229 });
1230 });
1231 };
1232
1233 NSR.nsd.vld.update = NSR.nsd.vld.create;
1234
1235 NSR.nsd.vld.delete = function(req) {
1236 var api_server = req.query['api_server'];
1237 var nsr_id = req.params.nsr_id;
1238 var vld_id = req.params.vld_id;
1239
1240 if (!api_server || !nsr_id || !vld_id) {
1241 return new Promise(function(resolve, reject) {
1242 return reject({
1243 statusCode: constants.HTTPS_RESPONSE_CODES.ERROR.INTERNAL_SERVER_ERROR,
1244 errorMessage: 'API server/NSR id/VLD id not provided'
1245 });
1246 })
1247 }
1248 console.log('Deleting VLD', vld_id, 'for NSR id', nsr_id);
1249
1250 return new Promise(function(resolve, reject) {
1251 var requestHeaders = {};
1252 _.extend(requestHeaders,
1253 constants.HTTP_HEADERS.accept.data,
1254 {
1255 'Authorization': req.session && req.session.authorization
1256 }
1257 );
1258
1259 request({
1260 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/ns-instance-config/nsr/' + encodeURIComponent(nsr_id) + '/nsd/vld/' + encodeURIComponent(vld_id)),
1261 method: 'DELETE',
1262 headers: requestHeaders,
1263 forever: constants.FOREVER_ON,
1264 rejectUnauthorized: false
1265 }, function (error, response, body) {
1266 if (utils.validateResponse('NSR.nsd.vld.delete', error, response, body, resolve, reject)) {
1267 resolve({
1268 statusCode: response.statusCode,
1269 data: typeof response.body == 'string' ? JSON.parse(response.body):response.body
1270 });
1271 }
1272 });
1273 });
1274 }
1275
1276 VNFR.get = function(req) {
1277 var api_server = req.query["api_server"];
1278 var id = req.params.id;
1279 var uri = utils.confdPort(api_server);
1280 uri += APIVersion + '/api/operational/vnfr-catalog/vnfr' + (id ? '/' + encodeURIComponent(id) : '') + '?deep';
1281 var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
1282 'Authorization': req.session && req.session.authorization
1283 });
1284 return new Promise(function(resolve, reject) {
1285 request({
1286 url: utils.projectContextUrl(req, uri),
1287 method: 'GET',
1288 headers: headers,
1289 forever: constants.FOREVER_ON,
1290 rejectUnauthorized: false,
1291 }, function(error, response, body) {
1292 if (utils.validateResponse('VNFR.get', error, response, body, resolve, reject)) {
1293 var data = JSON.parse(response.body);
1294 var returnData = id ? (data["vnfr:vnfr"] ? [data["vnfr:vnfr"]] : []) : data.collection["vnfr:vnfr"];
1295 returnData.forEach(function(vnfr) {
1296 vnfr['nfvi-metrics'] = vnfr.vdur ? buildNfviGraphs(vnfr.vdur) : [];
1297 vnfr['epa-params'] = vnfr.vdur ? epa_aggregator(vnfr.vdur) : [];
1298 vnfr['service-primitives-present'] = (vnfr['vnf-configuration'] && vnfr['vnf-configuration']['config-primitive'] && vnfr['vnf-configuration']['config-primitive'].length > 0) ? true : false;
1299 vnfr['vdur'] && vnfr['vdur'].map(function(vdur, vdurIndex) {
1300 // This console-url is what front-end will hit to generate a real console-url
1301 vdur['console-url'] = 'api/vnfr/' + encodeURIComponent(vnfr.id) + '/vdur/' + encodeURIComponent(vdur.id) + '/console-url';
1302 });
1303 });
1304 return resolve(returnData);
1305 };
1306 });
1307 });
1308 }
1309
1310 function buildNfviGraphs(VDURs, vnfrName){
1311 var temp = {};
1312 var toReturn = [];
1313 APIConfig.NfviMetrics.map(function(k) {
1314
1315 VDURs && VDURs.map(function(v,i) {
1316 //Check for RIFT-12699: VDUR NFVI Metrics not fully populated
1317 if (v["rw-vnfr:nfvi-metrics"] && v["rw-vnfr:nfvi-metrics"][k] && v["rw-vnfr:nfvi-metrics"][k].hasOwnProperty('utilization')) {
1318 if(!temp[k]) {
1319 temp[k] = {
1320 title: '',
1321 data: []
1322 };
1323 };
1324 try {
1325 var data = v["rw-vnfr:nfvi-metrics"][k];
1326 var newData = {};
1327 newData.name = v.name ? v.name : v.id.substring(0,6);
1328 newData.name = vnfrName ? vnfrName + ': ' + newData.name : newData.name;
1329 newData.id = v.id;
1330 //converts to perentage
1331 newData.utilization = data.utilization * 0.01;
1332 temp[k].data.push(newData);
1333 temp[k].title = v["rw-vnfr:nfvi-metrics"][k].label;
1334 } catch (e) {
1335 console.log('Something went wrong with the VNFR NFVI Metrics. Check that the data is being properly returned. ERROR: ', e);
1336 }
1337 }
1338 });
1339 if(temp[k]) {
1340 toReturn.push(temp[k]);
1341 }
1342 });
1343 return toReturn;
1344 }
1345
1346
1347 //Cache NSR reference for VNFR
1348 VNFR.cachedNSR = {};
1349 VNFR.getByNSR = function(req) {
1350 var api_server = req.query["api_server"];
1351 var id = req.params.nsr_id;
1352 var uri = utils.confdPort(api_server);
1353 var reqClone = _.clone(req);
1354 delete reqClone.params.id;
1355 uri += APIVersion + '/api/operational/ns-instance-opdata/nsr/' + encodeURIComponent(id) + '?deep';
1356 var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
1357 'Authorization': req.session && req.session.authorization
1358 });
1359 return new Promise(function(resolve, reject) {
1360 if (VNFR.cachedNSR[id]) {
1361 var data = VNFR.cachedNSR[id];
1362 var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
1363 VNFR.get(reqClone).then(function(vnfrData) {
1364 resolve(filterVnfrByList(vnfrList, vnfrData));
1365 });
1366 } else {
1367 request({
1368 url: utils.projectContextUrl(req, uri),
1369 method: 'GET',
1370 headers: headers,
1371 forever: constants.FOREVER_ON,
1372 rejectUnauthorized: false,
1373 }, function(error, response, body) {
1374 if (utils.validateResponse('VNFR.getByNSR', error, response, body, resolve, reject)) {
1375 var data = JSON.parse(response.body);
1376 data = data["nsr:nsr"];
1377 //Cache NSR data with NSR-ID as
1378 VNFR.cachedNSR[id] = data;
1379 var vnfrList = _.pluck(data["constituent-vnfr-ref"], 'vnfr-id');
1380 var returnData = [];
1381 VNFR.get(reqClone).then(function(vnfrData) {
1382 resolve(filterVnfrByList(vnfrList, vnfrData));
1383 });
1384 };
1385 });
1386 }
1387 });
1388 };
1389
1390 function filterVnfrByList(vnfrList, vnfrData) {
1391 return vnfrData.map(function(vnfr) {
1392 if (vnfrList.indexOf(vnfr.id) > -1) {
1393 return vnfr;
1394 }
1395 })
1396 };
1397
1398 VLR.get = function(req) {
1399 var api_server = req.query["api_server"];
1400 var id = req.params.id;
1401 var uri = utils.confdPort(api_server);
1402 uri += APIVersion + '/api/operational/vlr-catalog/vlr' + (id ? '/' + encodeURIComponent(id) : '') + '?deep';
1403 var headers = _.extend({}, id ? constants.HTTP_HEADERS.accept.data : constants.HTTP_HEADERS.accept.collection, {
1404 'Authorization': req.session && req.session.authorization
1405 });
1406 return new Promise(function(resolve, reject) {
1407 request({
1408 url: utils.projectContextUrl(req, uri),
1409 method: 'GET',
1410 headers: headers,
1411 forever: constants.FOREVER_ON,
1412 rejectUnauthorized: false,
1413 }, function(error, response, body) {
1414 if (utils.validateResponse('VLR.get', error, response, body, resolve, reject)) {
1415 var data = JSON.parse(response.body);
1416 var returnData = id ? [data["vlr:vlr"]] : data.collection["vlr:vlr"];
1417 return resolve({
1418 data: returnData,
1419 statusCode: response.statusCode
1420 });
1421 };
1422 });
1423 });
1424 }
1425
1426 RIFT.api = function(req) {
1427 var api_server = req.query["api_server"];
1428 var uri = utils.confdPort(api_server);
1429 var url = req.path;
1430 return new Promise(function(resolve, reject) {
1431 request({
1432 url: utils.projectContextUrl(req, uri + url + '?deep'),
1433 method: 'GET',
1434 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
1435 'Authorization': req.session && req.session.authorization
1436 }),
1437 forever: constants.FOREVER_ON,
1438 rejectUnauthorized: false,
1439 }, function(error, response, body) {
1440 if (utils.validateResponse('RIFT.api', error, response, body, resolve, reject)) {
1441 resolve(JSON.parse(response.body))
1442 };
1443 })
1444 })
1445 };
1446
1447 ComputeTopology.get = function(req) {
1448 var api_server = req.query['api_server'];
1449 var nsr_id = req.params.id;
1450 var result = {
1451 id: nsr_id, // node id
1452 name: nsr_id, // node name to display
1453 parameters: {}, // the parameters that can be used to determine size/color, etc. for the node
1454 type: 'nsr',
1455 children: [] // children for the node
1456 };
1457 return new Promise(function(resolve, reject) {
1458 var nsrPromise = new Promise(function(success, failure) {
1459 request({
1460 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata/nsr/' + encodeURIComponent(nsr_id) + '?deep'),
1461 method: 'GET',
1462 headers: _.extend({},
1463 constants.HTTP_HEADERS.accept.data, {
1464 'Authorization': req.session && req.session.authorization
1465 }),
1466 forever: constants.FOREVER_ON,
1467 rejectUnauthorized: false,
1468 }, function(error, response, body) {
1469 if (utils.validateResponse('ComputeTopology.get ns-instance-opdata/nsr/:id', error, response, body, success, failure)) {
1470 var data;
1471 var isString = typeof(response.body) == "string";
1472 if (isString && response.body == '') {
1473 return success({});
1474 }
1475 try {
1476 data = isString ? JSON.parse(response.body) : response.body;
1477
1478 var nsrNFVIMetricData = data["nsr:nsr"]["rw-nsr:nfvi-metrics"];
1479 result.parameters = nsrNFVIMetricData;
1480
1481 result.name = data["nsr:nsr"]["name-ref"];
1482
1483 var nsrData = data["nsr:nsr"]["constituent-vnfr-ref"];
1484 success(nsrData);
1485 } catch (e) {
1486 console.log('Error parsing ns-instance-opdata for NSR ID', nsr_id, 'Exception:', e);
1487 return failure()
1488 }
1489 };
1490 });
1491 }).then(function(data) {
1492
1493 try {
1494 // got NSR data
1495 // now get VNFR data and populate the structure
1496 var vnfrPromises = [];
1497
1498 // Run separately to confirm that primary structure is populated before promise resolution takes over
1499 // and starts modifying the data
1500 data.forEach(function(vnfrObj) {
1501
1502 var vnfrId = vnfrObj['vnfr-id'];
1503
1504 // If anything needs to be added to result for each vnfrId, do it here
1505
1506 vnfrPromises.push(
1507 new Promise(function(success, failure) {
1508 rp({
1509 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/vnfr-catalog/vnfr/' + encodeURIComponent(vnfrId) + '?deep'),
1510 method: 'GET',
1511 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
1512 'Authorization': req.session && req.session.authorization
1513 }),
1514 forever: constants.FOREVER_ON,
1515 rejectUnauthorized: false,
1516 resolveWithFullResponse: true
1517 }, function(error, response, body) {
1518 if (utils.validateResponse('ComputeTopology.get vnfr-catalaog/vnfr/:id', error, response, body, success, failure)) {
1519 try {
1520 var data = JSON.parse(response.body);
1521 var returnData = data["vnfr:vnfr"];
1522
1523 // Push VNFRs in result
1524 result.children.push({
1525 id: vnfrId,
1526 name: returnData.name,
1527 parameters: {}, // nfvi metrics here
1528 children: [],
1529 type: 'vnfr'
1530 });
1531
1532 // Push VDURs in result
1533 returnData.vdur.forEach(function(vdur) {
1534 result.children[result.children.length - 1].children.push({
1535 id: vdur.id,
1536 name: vdur.id,
1537 parameters: {},
1538 type: 'vdur'
1539 // children: []
1540 });
1541 });
1542
1543 return success(returnData.vdur);
1544 } catch (e) {
1545 console.log('Error parsing vnfr-catalog for VNFR ID', vnfrId, 'Exception:', e);
1546 return failure();
1547 }
1548 };
1549 });
1550 })
1551 );
1552 });
1553
1554 Promise.all(vnfrPromises).then(function(output) {
1555 console.log('Resolved all VNFR requests successfully');
1556 // By now result must be completely populated. output is moot
1557
1558 // Sort the results as there's no order to them from RIFT-REST
1559 result.children.sort(sortByName);
1560
1561 result.children.forEach(function(vnfr) {
1562 vnfr.children.sort(sortByName);
1563 });
1564
1565 resolve({
1566 statusCode: 200,
1567 data: result
1568 });
1569 }).catch(function(error) {
1570 // Todo: Can this be made better?
1571 // Right now if one of the southbound APIs fails - we just return what's populated so far in result
1572 console.log('Problem with ComputeTopology.get vnfr-catalog/vnfr/:id', error, 'Resolving with partial data', result);
1573 resolve({
1574 statusCode: 200,
1575 data: result
1576 });
1577 });
1578 } catch (e) {
1579 // API came back with empty ns-instance-opdata response for NSR ID
1580 // bail
1581 console.log('Error iterating through ns-instance-opdata response for NSR ID', nsr_id, 'Exception:', e);
1582 resolve({
1583 statusCode: 200,
1584 data: result
1585 })
1586 }
1587 }, function(error) {
1588 // failed to get NSR data.
1589 // bail
1590 resolve({
1591 statusCode: 200,
1592 data: result
1593 });
1594 });
1595 });
1596 };
1597
1598 NetworkTopology.get = function(req) {
1599 var api_server = req.query["api_server"];
1600 var uri = utils.confdPort(api_server);
1601 uri += APIVersion + '/api/operational/network?deep';
1602 var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
1603 'Authorization': req.session && req.session.authorization
1604 });
1605 return new Promise(function(resolve, reject) {
1606 request({
1607 url: utils.projectContextUrl(req, uri),
1608 method: 'GET',
1609 headers: headers,
1610 forever: constants.FOREVER_ON,
1611 rejectUnauthorized: false
1612 }, function(error, response, body) {
1613 if (utils.validateResponse('NetworkTopology.get', error, response, body, resolve, reject)) {
1614 var data = JSON.parse(response.body);
1615 var returnData = transforms.transformNetworkTopology(
1616 data["ietf-network:network"]
1617 );
1618 resolve({
1619 statusCode: 200,
1620 data: returnData
1621 });
1622 };
1623 });
1624 })
1625 }
1626
1627 VDUR.get = function(req) {
1628 var api_server = req.query["api_server"];
1629 var vnfrID = req.params.vnfr_id;
1630 var vdurID = req.params.vdur_id;
1631 var uri = utils.confdPort(api_server);
1632 uri += APIVersion + '/api/operational/vnfr-catalog/vnfr/' + encodeURIComponent(vnfrID) + '/vdur/' + encodeURIComponent(vdurID) + '?deep';
1633 var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
1634 'Authorization': req.session && req.session.authorization
1635 });
1636 return new Promise(function(resolve, reject) {
1637 request({
1638 url: utils.projectContextUrl(req, uri),
1639 method: 'GET',
1640 headers: headers,
1641 forever: constants.FOREVER_ON,
1642 rejectUnauthorized: false,
1643 }, function(error, response, body) {
1644 if (utils.validateResponse('VDUR.get', error, response, body, resolve, reject)) {
1645 var data = JSON.parse(response.body);
1646 var returnData = data["vdur:vdur"];
1647 return resolve(returnData);
1648 };
1649 });
1650 })
1651 }
1652
1653 VDUR.consoleUrl = {};
1654 VDUR.consoleUrl.get = function(req) {
1655 var api_server = req.query["api_server"];
1656 var vnfrID = req.params.vnfr_id;
1657 var vdurID = req.params.vdur_id;
1658 var uri = utils.confdPort(api_server);
1659 uri += APIVersion + '/api/operational/vnfr-console/vnfr/' + encodeURIComponent(vnfrID) + '/vdur/' + encodeURIComponent(vdurID) + '/console-url' + '?deep';
1660 var headers = _.extend({}, constants.HTTP_HEADERS.accept.data, {
1661 'Authorization': req.session && req.session.authorization
1662 });
1663 return new Promise(function(resolve, reject) {
1664 request({
1665 url: utils.projectContextUrl(req, uri),
1666 method: 'GET',
1667 headers: headers,
1668 forever: constants.FOREVER_ON,
1669 rejectUnauthorized: false,
1670 }, function(error, response, body) {
1671 if (utils.validateResponse('VDUR.consoleUrl.get', error, response, body, resolve, reject)) {
1672 var data = JSON.parse(response.body);
1673 var returnData = data;
1674 return resolve({
1675 data: returnData,
1676 statusCode: response.statusCode
1677 });
1678 };
1679 });
1680 })
1681 }
1682
1683 CloudAccount.get = function(req) {
1684 var api_server = req.query["api_server"];
1685 var uri = utils.confdPort(api_server);
1686 uri += APIVersion + '/api/operational/cloud/account?deep';
1687 var headers = _.extend({}, constants.HTTP_HEADERS.accept.collection, {
1688 'Authorization': req.session && req.session.authorization
1689 });
1690 return new Promise(function(resolve, reject) {
1691 request({
1692 url: utils.projectContextUrl(req, uri),
1693 method: 'GET',
1694 headers: headers,
1695 forever: constants.FOREVER_ON,
1696 rejectUnauthorized: false,
1697 }, function(error, response, body) {
1698 if (utils.validateResponse('CloudAccount.get', error, response, body, resolve, reject)) {
1699 var data = JSON.parse(response.body);
1700 var returnData = data["collection"]["rw-cloud:account"];
1701 resolve({
1702 statusCode: 200,
1703 data: returnData
1704 });
1705 };
1706 });
1707 });
1708 }
1709 ResourceOrchestratorAccount.get = function(req) {
1710 var self = this;
1711 var api_server = req.query["api_server"];
1712 var accountID = req.params.id || req.params.name;
1713
1714 return new Promise(function(resolve, reject) {
1715 var requestHeaders = {};
1716 _.extend(requestHeaders,
1717 constants.HTTP_HEADERS.accept.collection, {
1718 'Authorization': req.session && req.session.authorization
1719 }
1720 );
1721 var urlOp = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ro-account/account');
1722 var urlConfig = utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/ro-account-state/account');
1723 if(accountID) {
1724 urlOp = url + '/' + encodeURIComponent(accountID);
1725 urlConfig = url + '/' + encodeURIComponent(accountID);
1726 }
1727 var allRequests = [];
1728 var roOpData = new Promise(function(resolve, reject) {
1729 request({
1730 url: urlOp,
1731 type: 'GET',
1732 headers: requestHeaders,
1733 forever: constants.FOREVER_ON,
1734 rejectUnauthorized: false
1735 },
1736 function(error, response, body) {
1737 var data;
1738 if (utils.validateResponse('RoAccount.get', error, response, body, resolve, reject)) {
1739 try {
1740 data = JSON.parse(response.body).collection['rw-ro-account:account']
1741 } catch (e) {
1742 console.log('Problem with "RoAccount.get"', e);
1743 var err = {};
1744 err.statusCode = 500;
1745 err.errorMessage = {
1746 error: 'Problem with "RoAccount.get": ' + e // + e.toString()
1747 }
1748 return reject(err);
1749 }
1750 return resolve({
1751 statusCode: response.statusCode,
1752 data: data
1753 });
1754 };
1755 }
1756 );
1757 });
1758 var roConfigData = new Promise(function(resolve, reject){
1759 request({
1760 url: urlConfig,
1761 type: 'GET',
1762 headers: requestHeaders,
1763 forever: constants.FOREVER_ON,
1764 rejectUnauthorized: false
1765 },
1766 function(error, response, body) {
1767 var data;
1768 if (utils.validateResponse('RoAccount.get', error, response, body, resolve, reject)) {
1769 try {
1770 data = JSON.parse(response.body).collection['rw-ro-account:account']
1771 } catch (e) {
1772 console.log('Problem with "RoAccount.get"', e);
1773 var err = {};
1774 err.statusCode = 500;
1775 err.errorMessage = {
1776 error: 'Problem with "RoAccount.get": ' + e // + e.toString()
1777 }
1778 return reject(err);
1779 }
1780 return resolve({
1781 statusCode: response.statusCode,
1782 data: data
1783 });
1784 };
1785 }
1786 );
1787 });
1788
1789 allRequests.push(roOpData);
1790 allRequests.push(roConfigData);
1791 Promise.all(allRequests).then(function(data) {
1792 var state = data[1].data;
1793 var op = data[0].data;
1794 var result = [];
1795 var dict = {"rift":{}};
1796 if (!accountID) {
1797 state.length && state.map(function(s){
1798 dict[s.name] = s;
1799 });
1800 op.length && op.map(function(o) {
1801 dict[o.name] = _.extend(dict[o.name], o);
1802 });
1803 Object.keys(dict).map(function(d) {
1804 result.push(dict[d]);
1805 })
1806 } else {
1807 result = _.extend(op, state);
1808 }
1809 resolve({
1810 statusCode: 200,
1811 data: result
1812 })
1813 })
1814
1815 })
1816 }
1817
1818
1819 // Config-Agent Account APIs
1820 ConfigAgentAccount.get = function(req) {
1821 var self = this;
1822
1823 var api_server = req.query["api_server"];
1824 var id = req.params.id;
1825
1826 if (!id) {
1827 // Get all config accounts
1828 return new Promise(function(resolve, reject) {
1829
1830 var requestHeaders = {};
1831 _.extend(requestHeaders,
1832 constants.HTTP_HEADERS.accept.collection, {
1833 'Authorization': req.session && req.session.authorization
1834 });
1835
1836 request({
1837 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account'),
1838 type: 'GET',
1839 headers: requestHeaders,
1840 forever: constants.FOREVER_ON,
1841 rejectUnauthorized: false,
1842 },
1843 function(error, response, body) {
1844 var data;
1845 var statusCode;
1846 if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
1847 try {
1848 data = JSON.parse(response.body).collection['rw-config-agent:account'];
1849 statusCode = response.statusCode;
1850 } catch (e) {
1851 console.log('Problem with "ConfigAgentAccount.get"', e);
1852 var err = {};
1853 err.statusCode = 500;
1854 err.errorMessage = {
1855 error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
1856 }
1857 return reject(err);
1858 }
1859
1860 return resolve({
1861 statusCode: statusCode,
1862 data: data
1863 });
1864 };
1865 });
1866 });
1867 } else {
1868 //Get a specific config account
1869 return new Promise(function(resolve, reject) {
1870 var requestHeaders = {};
1871 _.extend(requestHeaders,
1872 constants.HTTP_HEADERS.accept.data, {
1873 'Authorization': req.session && req.session.authorization
1874 });
1875
1876 request({
1877 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/config-agent/account/' + encodeURIComponent(id)),
1878 type: 'GET',
1879 headers: requestHeaders,
1880 forever: constants.FOREVER_ON,
1881 rejectUnauthorized: false,
1882 },
1883 function(error, response, body) {
1884 var data;
1885 var statusCode;
1886 if (utils.validateResponse('ConfigAgentAccount.get', error, response, body, resolve, reject)) {
1887 try {
1888 data = JSON.parse(response.body)['rw-config-agent:account'];
1889 statusCode = response.statusCode;
1890 } catch (e) {
1891 console.log('Problem with "ConfigAgentAccount.get"', e);
1892 var err = {};
1893 err.statusCode = 500;
1894 err.errorMessage = {
1895 error: 'Problem with "ConfigAgentAccount.get": ' + e.toString()
1896 }
1897 return reject(err);
1898 }
1899
1900 return resolve({
1901 statusCode: statusCode,
1902 data: data
1903 });
1904 }
1905 });
1906 });
1907 }
1908 };
1909
1910 ConfigAgentAccount.create = function(req) {
1911
1912 var api_server = req.query["api_server"];
1913 var data = req.body;
1914
1915 return new Promise(function(resolve, reject) {
1916 var jsonData = {
1917 "account": Array.isArray(data) ? data : [data]
1918 };
1919
1920 console.log('Creating with', JSON.stringify(jsonData));
1921
1922 var requestHeaders = {};
1923 _.extend(requestHeaders,
1924 constants.HTTP_HEADERS.accept.data,
1925 constants.HTTP_HEADERS.content_type.data, {
1926 'Authorization': req.session && req.session.authorization
1927 });
1928
1929 request({
1930 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/config-agent'),
1931 method: 'POST',
1932 headers: requestHeaders,
1933 forever: constants.FOREVER_ON,
1934 rejectUnauthorized: false,
1935 json: jsonData,
1936 }, function(error, response, body) {
1937 if (utils.validateResponse('ConfigAgentAccount.create', error, response, body, resolve, reject)) {
1938 return resolve({
1939 statusCode: response.statusCode,
1940 data: JSON.stringify(response.body),
1941 body:response.body.body
1942 });
1943 };
1944 });
1945 });
1946 };
1947
1948 ConfigAgentAccount.update = function(req) {
1949
1950 var api_server = req.query["api_server"];
1951 var id = req.params.id;
1952 var data = req.body;
1953
1954 return new Promise(function(resolve, reject) {
1955 var jsonData = {
1956 "rw-config-agent:account": data
1957 };
1958
1959 console.log('Updating config-agent', id, ' with', JSON.stringify(jsonData));
1960
1961 var requestHeaders = {};
1962 _.extend(requestHeaders,
1963 constants.HTTP_HEADERS.accept.data,
1964 constants.HTTP_HEADERS.content_type.data, {
1965 'Authorization': req.session && req.session.authorization
1966 });
1967
1968 request({
1969 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + encodeURIComponent(id)),
1970 method: 'PUT',
1971 headers: requestHeaders,
1972 forever: constants.FOREVER_ON,
1973 rejectUnauthorized: false,
1974 json: jsonData,
1975 }, function(error, response, body) {
1976 if (utils.validateResponse('ConfigAgentAccount.update', error, response, body, resolve, reject)) {
1977 return resolve({
1978 statusCode: response.statusCode,
1979 data: JSON.stringify(response.body)
1980 });
1981 };
1982 });
1983 });
1984 };
1985
1986 ConfigAgentAccount.delete = function(req) {
1987
1988 var api_server = req.query["api_server"];
1989 var id = req.params.id;
1990
1991 if (!id || !api_server) {
1992 return new Promise(function(resolve, reject) {
1993 console.log('Must specifiy api_server and id to delete config-agent account');
1994 return reject({
1995 statusCode: 500,
1996 errorMessage: {
1997 error: 'Must specifiy api_server and id to delete config agent account'
1998 }
1999 });
2000 });
2001 };
2002
2003 return new Promise(function(resolve, reject) {
2004 var requestHeaders = {};
2005 _.extend(requestHeaders,
2006 constants.HTTP_HEADERS.accept.data, {
2007 'Authorization': req.session && req.session.authorization
2008 });
2009 request({
2010 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/config-agent/account/' + encodeURIComponent(id)),
2011 method: 'DELETE',
2012 headers: requestHeaders,
2013 forever: constants.FOREVER_ON,
2014 rejectUnauthorized: false,
2015 }, function(error, response, body) {
2016 if (utils.validateResponse('ConfigAgentAccount.delete', error, response, body, resolve, reject)) {
2017 return resolve({
2018 statusCode: response.statusCode,
2019 data: JSON.stringify(response.body)
2020 });
2021 };
2022 });
2023 });
2024 };
2025
2026
2027 DataCenters.get = function(req) {
2028 var api_server = req.query["api_server"];
2029 return new Promise(function(resolve, reject) {
2030 var requestHeaders = {};
2031 _.extend(requestHeaders,
2032 constants.HTTP_HEADERS.accept.data, {
2033 'Authorization': req.session && req.session.authorization
2034 });
2035 request({
2036 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/operational/datacenters?deep'),
2037 method: 'GET',
2038 headers: requestHeaders,
2039 forever: constants.FOREVER_ON,
2040 rejectUnauthorized: false,
2041 }, function(error, response, body) {
2042 if (utils.validateResponse('DataCenters.get', error, response, body, resolve, reject)) {
2043 var returnData = {};
2044 try {
2045 data = JSON.parse(response.body)["rw-launchpad:datacenters"]["ro-accounts"];
2046 data.map(function(c) {
2047 returnData[c.name] = c.datacenters;
2048 })
2049 statusCode = response.statusCode;
2050 } catch (e) {
2051 console.log('Problem with "DataCenters.get"', e);
2052 var err = {};
2053 err.statusCode = 500;
2054 err.errorMessage = {
2055 error: 'Problem with "DataCenters.get": ' + e.toString()
2056 }
2057 return reject(err);
2058 }
2059 return resolve({
2060 statusCode: response.statusCode,
2061 data: returnData
2062 });
2063 };
2064 });
2065 });
2066 }
2067
2068 SSHkey.get = function(req) {
2069 var api_server = req.query["api_server"];
2070 return new Promise(function(resolve, reject) {
2071 var requestHeaders = {};
2072 _.extend(requestHeaders,
2073 constants.HTTP_HEADERS.accept.data, {
2074 'Authorization': req.session && req.session.authorization
2075 });
2076 request({
2077 url: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair?deep'),
2078 method: 'GET',
2079 headers: requestHeaders,
2080 forever: constants.FOREVER_ON,
2081 rejectUnauthorized: false,
2082 }, function(error, response, body) {
2083 if (utils.validateResponse('SSHkey.get', error, response, body, resolve, reject)) {
2084 var returnData = {};
2085 try {
2086 returnData = JSON.parse(response.body)['nsr:key-pair'];
2087 statusCode = response.statusCode;
2088 } catch (e) {
2089 console.log('Problem with "SSHkey.get"', e);
2090 var err = {};
2091 err.statusCode = 500;
2092 err.errorMessage = {
2093 error: 'Problem with "SSHkey.get": ' + e.toString()
2094 }
2095 return reject(err);
2096 }
2097 return resolve({
2098 statusCode: response.statusCode,
2099 data: returnData
2100 });
2101 };
2102 });
2103 });
2104 }
2105 SSHkey.delete = function(req) {
2106 var api_server = req.query['api_server'];
2107 var id = decodeURI(req.params.name);
2108 console.log('Deleting ssk-key', id);
2109 return new Promise(function(resolve, reject) {
2110 request({
2111 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/' + encodeURIComponent(id)),
2112 method: 'DELETE',
2113 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
2114 'Authorization': req.session && req.session.authorization
2115 }),
2116 forever: constants.FOREVER_ON,
2117 rejectUnauthorized: false,
2118 }, function(error, response, body) {
2119 if (utils.validateResponse('SSHkey.delete', error, response, body, resolve, reject)) {
2120 resolve({
2121 statusCode: response.statusCode
2122 });
2123 }
2124 });
2125 });
2126 };
2127 SSHkey.post = function(req) {
2128 var api_server = req.query['api_server'];
2129 var data = req.body;
2130 return new Promise(function(resolve, reject) {
2131 request({
2132 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/'),
2133 method: 'POST',
2134 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
2135 'Authorization': req.session && req.session.authorization
2136 }),
2137 json: data,
2138 forever: constants.FOREVER_ON,
2139 rejectUnauthorized: false,
2140 }, function(error, response, body) {
2141 if (utils.validateResponse('SSHkey.post', error, response, body, resolve, reject)) {
2142 resolve({
2143 data: 'success',
2144 statusCode: response.statusCode
2145 });
2146 }
2147 });
2148 });
2149 };
2150 SSHkey.put = function(req) {
2151 var api_server = req.query['api_server'];
2152 var data = req.body;
2153 return new Promise(function(resolve, reject) {
2154 request({
2155 uri: utils.projectContextUrl(req, utils.confdPort(api_server) + APIVersion + '/api/config/key-pair/'),
2156 method: 'PUT',
2157 headers: _.extend({}, constants.HTTP_HEADERS.accept.data, {
2158 'Authorization': req.session && req.session.authorization
2159 }),
2160 json: data,
2161 forever: constants.FOREVER_ON,
2162 rejectUnauthorized: false,
2163 }, function(error, response, body) {
2164 if (utils.validateResponse('SSHkey.put', error, response, body, resolve, reject)) {
2165 resolve({
2166 statusCode: response.statusCode
2167 });
2168 }
2169 });
2170 });
2171 };
2172
2173 function sortByName(a, b) {
2174 return a.name > b.name;
2175 }
2176
2177 module.exports.catalog = Catalog;
2178 module.exports.nsr = NSR;
2179 module.exports.vnfr = VNFR;
2180 module.exports.vlr = VLR;
2181 module.exports.vdur = VDUR;
2182 module.exports.rift = RIFT;
2183 module.exports.computeTopology = ComputeTopology;
2184 module.exports.networkTopology = NetworkTopology;
2185 module.exports.config = Config;
2186 module.exports.cloud_account = CloudAccount;
2187 module.exports.ResourceOrchestratorAccount = ResourceOrchestratorAccount;
2188 module.exports['config-agent-account'] = ConfigAgentAccount;
2189 module.exports.rpc = RPC;
2190 module.exports.data_centers = DataCenters;
2191 module.exports.SSHkey = SSHkey;