| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 1 | /* |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 2 | * |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 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 _ = require('underscore'); |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 25 | var URL = require('url'); |
| 26 | var uuid = require('uuid'); |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 27 | var APIVersion = '/v1'; |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 28 | var PackageFileHandler = require('./packageFileHandler.js'); |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 29 | |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 30 | var Composer = {}; |
| 31 | var FileManager = {}; |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 32 | var DataCenters = {}; |
| 33 | // Catalog module methods |
| 34 | Composer.get = function(req) { |
| 35 | var api_server = req.query['api_server']; |
| 36 | var results = {} |
| 37 | return new Promise(function(resolve, reject) { |
| 38 | Promise.all([ |
| 39 | rp({ |
| 40 | uri: utils.confdPort(api_server) + APIVersion + '/api/config/nsd-catalog/nsd?deep', |
| 41 | method: 'GET', |
| 42 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 43 | 'Authorization': req.get('Authorization') |
| 44 | }), |
| 45 | forever: constants.FOREVER_ON, |
| 46 | rejectUnauthorized: false, |
| 47 | resolveWithFullResponse: true |
| 48 | }), |
| 49 | rp({ |
| 50 | uri: utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd?deep', |
| 51 | method: 'GET', |
| 52 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 53 | 'Authorization': req.get('Authorization') |
| 54 | }), |
| 55 | forever: constants.FOREVER_ON, |
| 56 | rejectUnauthorized: false, |
| 57 | resolveWithFullResponse: true |
| 58 | }), |
| 59 | rp({ |
| 60 | uri: utils.confdPort(api_server) + APIVersion + '/api/operational/ns-instance-opdata?deep', |
| 61 | method: 'GET', |
| 62 | headers: _.extend({}, constants.HTTP_HEADERS.accept.data, { |
| 63 | 'Authorization': req.get('Authorization') |
| 64 | }), |
| 65 | forever: constants.FOREVER_ON, |
| 66 | rejectUnauthorized: false, |
| 67 | resolveWithFullResponse: true |
| 68 | }) |
| 69 | // Not enabled for now |
| 70 | // rp({ |
| 71 | // uri: utils.confdPort(api_server) + '/api/config/pnfd-catalog/pnfd?deep', |
| 72 | // method: 'GET', |
| 73 | // headers: _.extend({}, |
| 74 | // constants.HTTP_HEADERS.accept.collection, |
| 75 | // { |
| 76 | // 'Authorization': req.get('Authorization') |
| 77 | // }), |
| 78 | // forever: constants.FOREVER_ON, |
| 79 | // rejectUnauthorized: false, |
| 80 | // resolveWithFullResponse: true |
| 81 | // }) |
| 82 | ]).then(function(result) { |
| 83 | var response = [{ |
| 84 | "id": "GUID-1", |
| 85 | "name": "RIFT.ware™ NS Descriptors Catalog", |
| 86 | "short-name": "rift.ware-nsd-cat", |
| 87 | "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.", |
| 88 | "vendor": "RIFT.io", |
| 89 | "version": "", |
| 90 | "created-on": "", |
| 91 | "type": "nsd", |
| 92 | "meta": { |
| 93 | "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" |
| 94 | }, |
| 95 | "descriptors": [] |
| 96 | }, { |
| 97 | "id": "GUID-2", |
| 98 | "name": "RIFT.ware™ VNF Descriptors Catalog", |
| 99 | "short-name": "rift.ware-vnfd-cat", |
| 100 | "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.", |
| 101 | "vendor": "RIFT.io", |
| 102 | "version": "", |
| 103 | "created-on": "", |
| 104 | "type": "vnfd", |
| 105 | "meta": { |
| 106 | "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> " |
| 107 | }, |
| 108 | "descriptors": [] |
| 109 | }, { |
| 110 | "id": "GUID-3", |
| 111 | "name": "RIFT.ware™ PNF Descriptors Catalog", |
| 112 | "short-name": "rift.ware-pnfd-cat", |
| 113 | "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.", |
| 114 | "vendor": "RIFT.io", |
| 115 | "version": "", |
| 116 | "created-on": "", |
| 117 | "type": "pnfd", |
| 118 | "meta": { |
| 119 | "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>" |
| 120 | }, |
| 121 | "descriptors": [] |
| 122 | }]; |
| 123 | if (result[0].body) { |
| 124 | response[0].descriptors = JSON.parse(result[0].body).collection['nsd:nsd']; |
| 125 | if (result[2].body) { |
| 126 | var data = JSON.parse(result[2].body); |
| 127 | if (data && data["nsr:ns-instance-opdata"] && data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"]) { |
| 128 | var nsdRefCountCollection = data["nsr:ns-instance-opdata"]["rw-nsr:nsd-ref-count"]; |
| 129 | response[0].descriptors.map(function(nsd) { |
| 130 | if (!nsd["meta"]) { |
| 131 | nsd["meta"] = {}; |
| 132 | } |
| 133 | if (typeof nsd['meta'] == 'string') { |
| 134 | nsd['meta'] = JSON.parse(nsd['meta']); |
| 135 | } |
| 136 | nsd["meta"]["instance-ref-count"] = _.findWhere(nsdRefCountCollection, { |
| 137 | "nsd-id-ref": nsd.id |
| 138 | })["instance-ref-count"]; |
| 139 | }); |
| 140 | } |
| 141 | } |
| 142 | }; |
| 143 | if (result[1].body) { |
| 144 | response[1].descriptors = JSON.parse(result[1].body).collection['vnfd:vnfd']; |
| 145 | }; |
| 146 | // if (result[2].body) { |
| 147 | // response[2].descriptors = JSON.parse(result[2].body).collection['pnfd:pnfd']; |
| 148 | // }; |
| 149 | resolve({ |
| 150 | statusCode: response.statusCode || 200, |
| 151 | data: JSON.stringify(response) |
| 152 | }); |
| 153 | }).catch(function(error) { |
| 154 | // Todo: Need better logic than all or nothing. |
| 155 | // Right now even if one of the southbound APIs fails - all fail |
| 156 | var res = {}; |
| 157 | console.log('Problem with Composer.get', error); |
| 158 | res.statusCode = error.statusCode || 500; |
| 159 | res.errorMessage = { |
| 160 | error: 'Failed to get catalogs' + error |
| 161 | }; |
| 162 | reject(res); |
| 163 | }); |
| 164 | }); |
| 165 | }; |
| 166 | Composer.delete = function(req) { |
| 167 | var api_server = req.query['api_server']; |
| 168 | var catalogType = req.params.catalogType; |
| 169 | var id = req.params.id; |
| 170 | console.log('Deleting', catalogType, id, 'from', api_server); |
| 171 | return new Promise(function(resolve, reject) { |
| 172 | request({ |
| 173 | uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog/' + catalogType + '/' + id, |
| 174 | method: 'DELETE', |
| 175 | headers: _.extend({}, constants.HTTP_HEADERS.accept.data, { |
| 176 | 'Authorization': req.get('Authorization') |
| 177 | }), |
| 178 | forever: constants.FOREVER_ON, |
| 179 | rejectUnauthorized: false, |
| 180 | }, function(error, response, body) { |
| 181 | if (utils.validateResponse('Composer.delete', error, response, body, resolve, reject)) { |
| 182 | resolve({ |
| 183 | statusCode: response.statusCode |
| 184 | }); |
| 185 | } |
| 186 | }); |
| 187 | }); |
| 188 | }; |
| 189 | Composer.getVNFD = function(req) { |
| 190 | var api_server = req.query['api_server']; |
| 191 | var vnfdID = req.body.data; |
| 192 | var authorization = req.get('Authorization'); |
| 193 | var VNFDs = []; |
| 194 | if (typeof(vnfdID) == "object" && vnfdID.constructor.name == "Array") { |
| 195 | vnfdID.map(function(id) { |
| 196 | VNFDs.push(requestVNFD(id)); |
| 197 | }); |
| 198 | } else { |
| 199 | VNFDs.push(requestVNFD(vnfdID)); |
| 200 | } |
| 201 | return new Promise(function(resolve, reject) { |
| 202 | Promise.all(VNFDs).then(function(data) { |
| 203 | resolve(data) |
| 204 | }).catch(function(error) { |
| 205 | // Todo: Need better logic than all or nothing. |
| 206 | // Right now even if one of the southbound APIs fails - all fail |
| 207 | var res = {}; |
| 208 | console.log('Problem with Composer.getVNFD', error); |
| 209 | res.statusCode = 404; |
| 210 | res.errorMessage = { |
| 211 | error: 'Failed to get VNFDs' + error |
| 212 | }; |
| 213 | reject(res); |
| 214 | }); |
| 215 | }); |
| 216 | |
| 217 | function requestVNFD(id) { |
| 218 | return new Promise(function(resolve, reject) { |
| 219 | var url = utils.confdPort(api_server) + APIVersion + '/api/config/vnfd-catalog/vnfd' + (id ? '/' + id : '') + '?deep'; |
| 220 | request({ |
| 221 | uri: url, |
| 222 | method: 'GET', |
| 223 | headers: _.extend({}, constants.HTTP_HEADERS.accept.data, { |
| 224 | 'Authorization': authorization |
| 225 | }), |
| 226 | forever: constants.FOREVER_ON, |
| 227 | rejectUnauthorized: false, |
| 228 | }, function(error, response, body) { |
| 229 | if (utils.validateResponse('Composer.create', error, response, body, resolve, reject)) { |
| 230 | var data; |
| 231 | //Is this still needed? |
| 232 | try { |
| 233 | data = JSON.parse(response.body) |
| 234 | } catch (e) { |
| 235 | reject({ |
| 236 | statusCode: response ? response.statusCode : 400, |
| 237 | errorMessage: 'Issue parsing VNFD ' + id + 'from ' + utils.confdPort(api_server) + '/api/config/vnfd-catalog/vnfd/' + id + '?deep' |
| 238 | }); |
| 239 | } |
| 240 | resolve(data); |
| 241 | } |
| 242 | }); |
| 243 | }); |
| 244 | } |
| 245 | }; |
| 246 | Composer.create = function(req) { |
| 247 | var api_server = req.query['api_server']; |
| 248 | var catalogType = req.params.catalogType; |
| 249 | var data = req.body; |
| 250 | console.log('Creating', catalogType, 'on', api_server); |
| 251 | var jsonData = {}; |
| 252 | jsonData[catalogType] = []; |
| 253 | jsonData[catalogType].push(data); |
| 254 | return new Promise(function(resolve, reject) { |
| 255 | var requestHeaders = {}; |
| 256 | _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, { |
| 257 | 'Authorization': req.get('Authorization') |
| 258 | }); |
| 259 | request({ |
| 260 | uri: utils.confdPort(api_server) + '/api/config/' + catalogType + '-catalog', |
| 261 | method: 'POST', |
| 262 | headers: requestHeaders, |
| 263 | forever: constants.FOREVER_ON, |
| 264 | rejectUnauthorized: false, |
| 265 | json: jsonData |
| 266 | }, function(error, response, body) { |
| 267 | if (utils.validateResponse('Composer.create', error, response, body, resolve, reject)) { |
| 268 | resolve({ |
| 269 | statusCode: response.statusCode |
| 270 | }); |
| 271 | } |
| 272 | }); |
| 273 | }); |
| 274 | }; |
| Laurence Maultsby | 261acea | 2017-01-18 20:12:34 -0500 | [diff] [blame] | 275 | Composer.updateSave = function(req) { |
| 276 | var api_server = req.query['api_server']; |
| 277 | var catalogType = req.params.catalogType; |
| 278 | var id = req.params.id; |
| 279 | var data = req.body; |
| 280 | console.log('Updating', catalogType, 'id', id, 'on', api_server); |
| 281 | var jsonData = {}; |
| 282 | jsonData[catalogType] = {}; |
| 283 | jsonData[catalogType] = data; |
| 284 | return new Promise(function(resolve, reject) { |
| 285 | var requestHeaders = {}; |
| 286 | _.extend(requestHeaders, constants.HTTP_HEADERS.accept.data, constants.HTTP_HEADERS.content_type.data, { |
| 287 | 'Authorization': req.get('Authorization') |
| 288 | }); |
| 289 | request({ |
| 290 | uri: utils.confdPort(api_server) + APIVersion + '/api/config/' + catalogType + '-catalog' + '/' + catalogType + '/' + id, |
| 291 | method: 'PUT', |
| 292 | headers: requestHeaders, |
| 293 | forever: constants.FOREVER_ON, |
| 294 | rejectUnauthorized: false, |
| 295 | json: jsonData |
| 296 | }, function(error, response, body) { |
| 297 | if (utils.validateResponse('Composer.update', error, response, body, resolve, reject)) { |
| 298 | resolve({ |
| 299 | statusCode: response.statusCode |
| 300 | }); |
| 301 | } |
| 302 | }); |
| 303 | }); |
| 304 | } |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 305 | |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 306 | Composer.update = function(req) { |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 307 | console.log(' Updating file', req.file.originalname, 'as', req.file.filename); |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 308 | var api_server = req.query['api_server']; |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 309 | // dev_download_server is for testing purposes. |
| 310 | // It is the direct IP address of the Node server where the |
| 311 | // package will be hosted. |
| 312 | var download_host = req.query['dev_download_server']; |
| 313 | |
| 314 | if (!download_host) { |
| Gennadiy Dubina | 6f5b417 | 2017-02-13 11:01:23 +0200 | [diff] [blame] | 315 | download_host = req.protocol + '://' + req.get('host');//api_server + ':' + utils.getPortForProtocol(req.protocol); |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 316 | } |
| 317 | var input = { |
| 318 | 'external-url': download_host + '/composer/update/' + req.file.filename, |
| 319 | 'package-type': 'VNFD', |
| 320 | 'package-id': uuid() |
| 321 | } |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 322 | return new Promise(function(resolve, reject) { |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 323 | Promise.all([ |
| 324 | rp({ |
| 325 | uri: utils.confdPort(api_server) + '/api/operations/package-update', |
| 326 | method: 'POST', |
| 327 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 328 | 'Authorization': req.get('Authorization') |
| 329 | }), |
| 330 | forever: constants.FOREVER_ON, |
| 331 | rejectUnauthorized: false, |
| 332 | resolveWithFullResponse: true, |
| 333 | json: true, |
| 334 | body: { |
| 335 | input: input |
| 336 | } |
| 337 | }) |
| 338 | ]).then(function(result) { |
| 339 | var data = {}; |
| 340 | data['transaction_id'] = result[0].body['output']['transaction-id']; |
| 341 | |
| 342 | // Add a status checker on the transaction and then to delete the file later |
| 343 | PackageFileHandler.checkCreatePackageStatusAndHandleFile(req, data['transaction_id'], true); |
| 344 | |
| 345 | // Return status to composer UI to update the status. |
| 346 | resolve({ |
| 347 | statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK, |
| 348 | data: data |
| 349 | }); |
| 350 | }).catch(function(error) { |
| 351 | var res = {}; |
| 352 | console.log('Problem with Composer.upload', error); |
| 353 | res.statusCode = error.statusCode || 500; |
| 354 | res.errorMessage = { |
| 355 | error: 'Failed to upload package ' + req.file.originalname + '. Error: ' + error |
| 356 | }; |
| 357 | reject(res); |
| Jeremy Mordkoff | e29efc3 | 2016-09-07 18:59:17 -0400 | [diff] [blame] | 358 | }); |
| 359 | }); |
| 360 | }; |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 361 | |
| 362 | Composer.upload = function(req) { |
| 363 | console.log(' Uploading file', req.file.originalname, 'as', req.file.filename); |
| 364 | var api_server = req.query['api_server']; |
| 365 | // dev_download_server is for testing purposes. |
| 366 | // It is the direct IP address of the Node server where the |
| 367 | // package will be hosted. |
| 368 | var download_host = req.query['dev_download_server']; |
| 369 | |
| 370 | if (!download_host) { |
| Gennadiy Dubina | 6f5b417 | 2017-02-13 11:01:23 +0200 | [diff] [blame] | 371 | download_host = req.protocol + '://' + req.get('host');//req.api_server + ':' + utils.getPortForProtocol(req.protocol); |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 372 | } |
| 373 | |
| 374 | return new Promise(function(resolve, reject) { |
| 375 | Promise.all([ |
| 376 | rp({ |
| 377 | uri: utils.confdPort(api_server) + '/api/operations/package-create', |
| 378 | method: 'POST', |
| 379 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 380 | 'Authorization': req.get('Authorization') |
| 381 | }), |
| 382 | forever: constants.FOREVER_ON, |
| 383 | rejectUnauthorized: false, |
| 384 | resolveWithFullResponse: true, |
| 385 | json: true, |
| 386 | body: { |
| 387 | input: { |
| 388 | 'external-url': download_host + '/composer/upload/' + req.file.filename, |
| 389 | 'package-type': 'VNFD', |
| 390 | 'package-id': uuid() |
| 391 | } |
| 392 | } |
| 393 | }) |
| 394 | ]).then(function(result) { |
| 395 | var data = {}; |
| 396 | data['transaction_id'] = result[0].body['output']['transaction-id']; |
| 397 | |
| 398 | // Add a status checker on the transaction and then to delete the file later |
| 399 | PackageFileHandler.checkCreatePackageStatusAndHandleFile(req, data['transaction_id']); |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 400 | |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 401 | // Return status to composer UI to update the status. |
| 402 | resolve({ |
| 403 | statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK, |
| 404 | data: data |
| 405 | }); |
| 406 | }).catch(function(error) { |
| 407 | var res = {}; |
| 408 | console.log('Problem with Composer.upload', error); |
| 409 | res.statusCode = error.statusCode || 500; |
| 410 | res.errorMessage = { |
| 411 | error: 'Failed to upload package ' + req.file.originalname + '. Error: ' + error |
| 412 | }; |
| 413 | reject(res); |
| 414 | }); |
| 415 | }); |
| 416 | }; |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 417 | |
| 418 | |
| 419 | |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 420 | Composer.addFile = function(req) { |
| 421 | console.log(' Uploading file', req.file.originalname, 'as', req.file.filename); |
| 422 | var api_server = req.query['api_server']; |
| 423 | var download_host = req.query['dev_download_server']; |
| 424 | var package_id = req.query['package_id']; |
| 425 | var package_type = req.query['package_type'].toUpperCase(); |
| 426 | var package_path = req.query['package_path']; |
| 427 | if (!download_host) { |
| Gennadiy Dubina | 6f5b417 | 2017-02-13 11:01:23 +0200 | [diff] [blame] | 428 | download_host = req.protocol + '://' + req.get('host');//api_server + ':' + utils.getPortForProtocol(req.protocol); |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 429 | } |
| Laurence Maultsby | 8f1f42c | 2017-01-30 15:00:04 -0500 | [diff] [blame] | 430 | var input = { |
| 431 | 'external-url': download_host + '/composer/upload/' + req.query['package_id'] + '/' + req.file.filename, |
| 432 | 'package-type': package_type, |
| 433 | 'package-id': package_id, |
| 434 | 'package-path': package_path + '/' + req.file.filename |
| 435 | } |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 436 | return new Promise(function(resolve, reject) { |
| 437 | Promise.all([ |
| 438 | rp({ |
| 439 | uri: utils.confdPort(api_server) + '/api/operations/package-file-add', |
| 440 | method: 'POST', |
| 441 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 442 | 'Authorization': req.get('Authorization') |
| 443 | }), |
| 444 | forever: constants.FOREVER_ON, |
| 445 | rejectUnauthorized: false, |
| 446 | resolveWithFullResponse: true, |
| 447 | json: true, |
| 448 | body: { |
| Laurence Maultsby | 8f1f42c | 2017-01-30 15:00:04 -0500 | [diff] [blame] | 449 | input: input |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 450 | } |
| 451 | }) |
| 452 | ]).then(function(result) { |
| 453 | var data = {}; |
| Laurence Maultsby | e4df686 | 2017-01-17 09:37:31 -0500 | [diff] [blame] | 454 | data['transaction_id'] = result[0].body['output']['task-id']; |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 455 | resolve({ |
| 456 | statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK, |
| 457 | data: data |
| 458 | }); |
| 459 | }).catch(function(error) { |
| 460 | var res = {}; |
| 461 | console.log('Problem with Composer.upload', error); |
| 462 | res.statusCode = error.statusCode || 500; |
| 463 | res.errorMessage = { |
| 464 | error: 'Failed to upload package ' + req.file.originalname + '. Error: ' + error |
| 465 | }; |
| 466 | reject(res); |
| 467 | }); |
| 468 | }); |
| 469 | } |
| 470 | |
| 471 | Composer.exportPackage = function(req) { |
| 472 | // /api/operations/package-export |
| 473 | var api_server = req.query['api_server']; |
| 474 | return new Promise(function(resolve, reject) { |
| 475 | Promise.all([ |
| 476 | rp({ |
| 477 | uri: utils.confdPort(api_server) + '/api/operations/package-export', |
| 478 | method: 'POST', |
| 479 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 480 | 'Authorization': req.get('Authorization') |
| 481 | }), |
| 482 | forever: constants.FOREVER_ON, |
| 483 | rejectUnauthorized: false, |
| 484 | resolveWithFullResponse: true, |
| 485 | json: true, |
| 486 | body: { "input": req.body} |
| 487 | }) |
| 488 | ]).then(function(result) { |
| 489 | var data = {}; |
| 490 | resolve({ |
| 491 | statusCode: constants.HTTP_RESPONSE_CODES.SUCCESS.OK, |
| 492 | data: result[0].body |
| 493 | }); |
| 494 | }).catch(function(error) { |
| 495 | var res = {}; |
| 496 | console.log('Problem with Composer.exportPackage', error); |
| 497 | res.statusCode = error.statusCode || 500; |
| 498 | res.errorMessage = { |
| 499 | error: error |
| 500 | }; |
| 501 | reject(res); |
| 502 | }); |
| 503 | }); |
| 504 | } |
| 505 | |
| 506 | FileManager.get = function(req) { |
| 507 | var api_server = req.query['api_server']; |
| 508 | var type = req.query['package_type'] && req.query['package_type'].toUpperCase(); |
| 509 | var id = req.query['package_id']; |
| 510 | var downloadUrl = req.query['url']; |
| 511 | var path = req.query['package_path']; |
| 512 | var payload = { |
| 513 | "input": { |
| 514 | "package-type": type, |
| 515 | "package-id": id |
| 516 | } |
| 517 | } |
| 518 | if(req.method == 'GET') { |
| 519 | if(downloadUrl && path) { |
| 520 | payload.input['external-url'] = downloadUrl; |
| 521 | payload.input['package-path'] = path; |
| 522 | return download(payload); |
| 523 | } else { |
| 524 | return list(payload); |
| 525 | } |
| 526 | } |
| 527 | if(req.method == 'DELETE') { |
| 528 | payload.input['package-path'] = path; |
| 529 | return deleteFile(payload) |
| 530 | } |
| 531 | |
| 532 | function deleteFile(payload) { |
| 533 | return new Promise(function(resolve, reject) { |
| 534 | rp({ |
| 535 | uri: utils.confdPort(api_server) + '/api/operations/rw-pkg-mgmt:package-file-delete', |
| 536 | method: 'POST', |
| 537 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 538 | 'Authorization': req.get('Authorization') |
| 539 | }), |
| 540 | json: payload, |
| 541 | forever: constants.FOREVER_ON, |
| 542 | rejectUnauthorized: false, |
| 543 | resolveWithFullResponse: true |
| 544 | }).then(function(data) { |
| 545 | if (utils.validateResponse('FileManager.delete', data.error, data, data.body, resolve, reject)) { |
| 546 | resolve({ |
| 547 | statusCode: data.statusCode, |
| 548 | data: data.body |
| 549 | }); |
| 550 | } |
| 551 | }) |
| 552 | }) |
| 553 | } |
| 554 | function download(payload) { |
| 555 | return new Promise(function(resolve, reject) { |
| 556 | rp({ |
| 557 | uri: utils.confdPort(api_server) + '/api/operations/rw-pkg-mgmt:package-file-add', |
| 558 | method: 'POST', |
| 559 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 560 | 'Authorization': req.get('Authorization') |
| 561 | }), |
| 562 | json: payload, |
| 563 | forever: constants.FOREVER_ON, |
| 564 | rejectUnauthorized: false, |
| 565 | resolveWithFullResponse: true |
| 566 | }).then(function(data) { |
| 567 | if (utils.validateResponse('FileManager.get', data.error, data, data.body, resolve, reject)) { |
| 568 | resolve({ |
| 569 | statusCode: data.statusCode, |
| 570 | data: data.body |
| 571 | }); |
| 572 | } |
| 573 | }) |
| 574 | }) |
| 575 | } |
| 576 | function list(payload) { |
| 577 | return new Promise(function(resolve, reject) { |
| 578 | rp({ |
| 579 | uri: utils.confdPort(api_server) + '/api/operations/get-package-endpoint', |
| 580 | method: 'POST', |
| 581 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 582 | 'Authorization': req.get('Authorization') |
| 583 | }), |
| 584 | json: payload, |
| 585 | forever: constants.FOREVER_ON, |
| 586 | rejectUnauthorized: false, |
| 587 | resolveWithFullResponse: true |
| 588 | }).then(function(data) { |
| 589 | if (utils.validateResponse('FileManager.get', data.error, data, data.body, resolve, reject)) { |
| 590 | var endpoint = null; |
| 591 | var parsedEndpoint = null; |
| 592 | try { |
| 593 | endpoint = data.body.output.endpoint |
| 594 | } catch(e) { |
| 595 | console.log('Something went wrong with the FileManager.get data that was returned'); |
| 596 | reject({}); |
| 597 | } |
| 598 | parsedEndpoint = URL.parse(endpoint); |
| 599 | rp({ |
| 600 | uri: api_server + ':' + parsedEndpoint.port + parsedEndpoint.path, |
| 601 | method: 'GET', |
| 602 | headers: _.extend({}, constants.HTTP_HEADERS.accept.collection, { |
| 603 | 'Authorization': req.get('Authorization') |
| 604 | }), |
| 605 | forever: constants.FOREVER_ON, |
| 606 | rejectUnauthorized: false, |
| 607 | resolveWithFullResponse: true |
| 608 | }).then(function(data) { |
| 609 | if (utils.validateResponse('FileManager.get', data.error, data, data.body, resolve, reject)) { |
| 610 | resolve({ |
| 611 | statusCode: data.statusCode, |
| 612 | data: data.body |
| 613 | }); |
| 614 | } |
| Laurence Maultsby | df332f5 | 2017-01-19 11:44:34 -0500 | [diff] [blame] | 615 | }).catch(function(err) { |
| 616 | console.log('Failed to retrieve FileManager.list') |
| 617 | resolve(err); |
| Laurence Maultsby | b066071 | 2017-01-06 16:01:19 +0000 | [diff] [blame] | 618 | }) |
| 619 | } |
| 620 | }) |
| 621 | }) |
| 622 | } |
| 623 | } |
| 624 | FileManager.job = function(req) { |
| 625 | var api_server = req.query["api_server"]; |
| 626 | var uri = utils.confdPort(api_server); |
| 627 | var url = '/api/operational/download-jobs'; |
| 628 | var id = req.params['id']; |
| 629 | return new Promise(function(resolve, reject) { |
| 630 | request({ |
| 631 | url: uri + url + '?deep', |
| 632 | method: 'GET', |
| 633 | headers: _.extend({}, constants.HTTP_HEADERS.accept.data, { |
| 634 | 'Authorization': req.get('Authorization') |
| 635 | }), |
| 636 | forever: constants.FOREVER_ON, |
| 637 | rejectUnauthorized: false, |
| 638 | }, function(error, response, body) { |
| 639 | if (utils.validateResponse('restconfAPI.streams', error, response, body, resolve, reject)) { |
| 640 | var data = JSON.parse(response.body)['rw-pkg-mgmt:download-jobs']; |
| 641 | var returnData = []; |
| 642 | data && data.job.map(function(d) { |
| 643 | if(d['package-id'] == id) { |
| 644 | returnData.push(d) |
| 645 | } |
| 646 | }) |
| 647 | resolve({ |
| 648 | statusCode: response.statusCode, |
| 649 | data: returnData |
| 650 | }) |
| 651 | }; |
| 652 | }) |
| 653 | }) |
| 654 | } |
| 655 | module.exports = { |
| 656 | Composer:Composer, |
| 657 | FileManager: FileManager |
| 658 | }; |