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