aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorShadi Haidar <sh1986@att.com>2020-01-14 13:31:20 -0500
committerShadi Haidar <sh1986@att.com>2020-08-19 17:51:07 -0400
commit3d364e4ffa2bfdbffa75679ad67fbaa93ce0b8bf (patch)
tree6dfefbd3a80f38b567f06f37621cda1f524572c2 /lib
parentd6a5b946f05f43a9942d3d564d66a0a3396933a5 (diff)
DH install/uninstall improvements
Install workflow changes: -Use inventory blueprint (BP) typeId when uploading BP to Cloudify/CFY -Set global visibility when uploading BP to CFY for multi-tenant access -Re-use BP if it exists in CFY rather than alawys uploading a new BP -Do not add a new service in inventory anymore Un-Install workflow changes: -Retreive associated BP against the deployment -Check if any other deployments still exist against the BP -If no associated deployments, get the associated tenant for the BP -Only delete BP if there are no more associated BPs -Do not remove associated service from inventory (it won't exist) Coverage summary Statements : 78.01% ( 997/1278 ) Branches : 56.45% ( 302/535 ) Functions : 74.89% ( 164/219 ) Lines : 78.54% ( 988/1258 ) Issue-ID: DCAEGEN2-2022 Signed-off-by: Shadi Haidar <sh1986@att.com> Change-Id: I9cb197edc3a0276c5ca95f9c936fc7300d849f56 Signed-off-by: Shadi Haidar <sh1986@att.com> Signed-off-by: Shadi Haidar (sh1986) <sh1986@att.com> Signed-off-by: Shadi Haidar <sh1986@att.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/cloudify.js93
-rw-r--r--lib/dcae-deployments.js48
-rw-r--r--lib/deploy.js54
3 files changed, 146 insertions, 49 deletions
diff --git a/lib/cloudify.js b/lib/cloudify.js
index 77e6d72..2c7af6e 100644
--- a/lib/cloudify.js
+++ b/lib/cloudify.js
@@ -92,6 +92,17 @@ const getDeploymentCreationStatus = function(req, deployment_id) {
return doRequest(req, reqOptions, null, CLOUDIFY);
};
+// Get blueprint_id for a particular deployment
+exports.getBlueprintIdFromDeployment = function(req, deployment_id) {
+ const reqOptions = {
+ method : "GET",
+ uri : cfyAPI + "/deployments/" + deployment_id + "?_include=blueprint_id"
+ };
+ addAuthToOptions(reqOptions, req);
+
+ return doRequest(req, reqOptions, null, CLOUDIFY);
+};
+
// Poll for the result of a workflow execution until it's done
// Return a promise for the final result of a workflow execution
exports.waitForWorkflowExecution = function(mainReq, execution_id) {
@@ -243,7 +254,7 @@ exports.uploadBlueprint = function(req, bpid, blueprint) {
// Set up the HTTP PUT request
const reqOptions = {
method : "PUT",
- uri : cfyAPI + "/blueprints/" + bpid,
+ uri : cfyAPI + "/blueprints/" + bpid + "?visibility=global",
headers : {
"Content-Type" : "application/octet-stream",
"Accept" : "*/*"
@@ -255,6 +266,86 @@ exports.uploadBlueprint = function(req, bpid, blueprint) {
return doRequest(req, reqOptions, zip_buffer, CLOUDIFY);
};
+// Checks if a blueprint exists in cloudify
+exports.checkBlueprintExits = function(req, bpid) {
+
+ // Set up the HTTP GET request
+ var reqOptions = {
+ method : "GET",
+ uri : cfyAPI + "/blueprints?id=" + bpid,
+ headers : {
+ "Content-Type" : "application/json",
+ "Accept" : "*/*"
+ }
+ };
+ addAuthToOptions(reqOptions, req);
+
+ return doRequest(req, reqOptions, null, CLOUDIFY)
+
+ .then (function(result) {
+ if (result.json.metadata.pagination.total > 0 ) {
+ return true;
+ }
+ else {
+ return false;
+ }
+ })
+ .catch(function(error) {
+ logger.debug(req.dcaeReqId, "Error getting BP from Cloudify for deployment id: " + req.params['deploymentId'] + " and blueprint id: " + bpid );
+ throw(error);
+ });
+};
+
+// Get the tenant_name associated with a blueprint
+exports.getBlueprintTenantName = function(req, bpid) {
+
+ // Set up the HTTP GET request
+ var reqOptions = {
+ method : "GET",
+ uri : cfyAPI + "/blueprints?id=" + bpid + "&_include=tenant_name",
+ headers : {
+ "Content-Type" : "application/json",
+ "Accept" : "*/*"
+ }
+ };
+ addAuthToOptions(reqOptions, req);
+
+ return doRequest(req, reqOptions, null, CLOUDIFY);
+};
+
+// Checks if a blueprint should be deleted from cloudify due to no associated deployments
+exports.shouldBlueprintGetDeleted = function(req, bpid) {
+
+ // Set up the HTTP GET request
+ var reqOptions = {
+ method : "GET",
+ uri : cfyAPI + "/deployments?blueprint_id=" + bpid + "&_all_tenants=true&_include=id",
+ headers : {
+ "Content-Type" : "application/json",
+ "Accept" : "*/*"
+ }
+ };
+ const tenant = req.query.cfy_tenant_name;
+ req.query.cfy_tenant_name = DEFAULT_TENANT;
+ addAuthToOptions(reqOptions, req);
+ req.query.cfy_tenant_name = tenant;
+
+ return doRequest(req, reqOptions, null, CLOUDIFY)
+
+ .then (function(result) {
+ if (result.json.metadata.pagination.total > 0 ) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ })
+ .catch(function(error) {
+ logger.debug(req.dcaeReqId, "Error getting deployments info from Cloudify for deployment id: " + req.params['deploymentId'] + " and blueprint id: " + bpid );
+ throw(error);
+ });
+};
+
// Creates a deployment from a blueprint
exports.createDeployment = function(req, dpid, bpid, inputs) {
diff --git a/lib/dcae-deployments.js b/lib/dcae-deployments.js
index 193f6b9..708a949 100644
--- a/lib/dcae-deployments.js
+++ b/lib/dcae-deployments.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2017-2020 AT&T Intellectual Property. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ const deploy = require('./deploy');
const middleware = require('./middleware');
const inv = require('./inventory');
const log = require('./logging').getLogger();
+const DEFAULT_TENANT = "default_tenant";
/* Pick up config exported by main */
const config = process.mainModule.exports.config;
@@ -63,7 +64,7 @@ const createLinks = function(req, deploymentId, executionId) {
var baseURL = req.protocol + '://' + req.get('Host') + req.app.mountpath + '/' + deploymentId;
return {
self: baseURL,
- status: baseURL + '/operation/' + executionId
+ status: baseURL + '/operation/' + executionId + '?cfy_tenant_name=' + req.query.cfy_tenant_name || DEFAULT_TENANT
};
};
@@ -105,31 +106,20 @@ app.put('/:deploymentId', function(req, res, next) {
throw e;
}
- /* Make sure the deploymentId doesn't already exist */
- inventory.verifyUniqueDeploymentId(req, req.params['deploymentId'])
-
- /* Get the blueprint for this service type */
- .then(function(res) {
- return getBlueprint(req, req.body['serviceTypeId']);
- })
-
- /* Add this new service instance to inventory
- * Easier to remove from inventory if deployment fails than vice versa
- * Also lets client check for deployed/deploying instances if client wants to limit number of instances
- */
- .then(function (blueprintInfo) {
- req.dcaeBlueprint = blueprintInfo.blueprint;
- return inventory.addService(req, req.params['deploymentId'], blueprintInfo.typeId, "dummyVnfId", "dummyVnfType", "dummyLocation");
- })
+ return getBlueprint(req, req.body['serviceTypeId'])
/* Upload blueprint, create deployment and start install workflow (but don't wait for completion */
- .then (function() {
+ .then (function(blueprintInfo) {
+ req.dcaeBlueprint = blueprintInfo.blueprint;
+ req.bpTypeId = blueprintInfo.typeId;
req.dcaeAddedToInventory = true;
- return deploy.launchBlueprint(req, req.params['deploymentId'], req.dcaeBlueprint, req.body['inputs']);
+ return deploy.launchBlueprint(req, req.params['deploymentId'], req.dcaeBlueprint,
+ "TID-" + req.bpTypeId, req.body['inputs']);
})
/* Send the HTTP response indicating workflow has started */
.then(function(result) {
+ log.info(req.dcaeReqId, "Result from deployment creation/execution: " + JSON.stringify(result));
res.status(202).json(createResponse(req, result));
log.audit(req, 202, "Execution ID: " + result.executionId);
return result;
@@ -150,15 +140,6 @@ app.put('/:deploymentId', function(req, res, next) {
/* If we haven't already sent a response, let the error handler send response and log the error */
if (!res.headersSent) {
-
- /* If we made an inventory entry, remove it */
- if (req.dcaeAddedToInventory) {
- inventory.deleteService(req, req.params['deploymentId'])
- .catch(function(error) {
- log.error(error, req);
- });
- }
-
next(error);
}
else {
@@ -179,14 +160,6 @@ app.delete('/:deploymentId', function(req, res, next) {
/* Launch the uninstall workflow */
deploy.launchUninstall(req, req.params['deploymentId'])
- /* Delete the service from inventory */
- .then(function(result) {
- return inventory.deleteService(req, req.params['deploymentId'])
- .then (function() {
- return result;
- });
- })
-
/* Send the HTTP response indicating workflow has started */
.then(function(result) {
res.status(202).send(createResponse(req, result));
@@ -198,7 +171,6 @@ app.delete('/:deploymentId', function(req, res, next) {
.then(function(result) {
return deploy.finishUninstall(req, result.deploymentId, result.executionId);
})
-
/* Log completion in audit log */
.then(function(result) {
log.audit(req, 200, "Undeployed id: " + req.params['deploymentId']);
diff --git a/lib/deploy.js b/lib/deploy.js
index cb78f6f..d4ce1d4 100644
--- a/lib/deploy.js
+++ b/lib/deploy.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2017-2020 AT&T Intellectual Property. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -130,19 +130,32 @@ var delay = function(dtime) {
// Go through the Cloudify API call sequence to upload blueprint, create deployment, and launch install workflow
// (but don't wait for the workflow to finish)
-exports.launchBlueprint = function(req, id, blueprint, inputs) {
+exports.launchBlueprint = function(req, id, blueprint, bpid, inputs) {
+ const log_blueprint_id = "blueprintId(" + bpid + "): ";
const log_deployment_id = "deploymentId(" + id + "): ";
- var step_log = log_deployment_id + "uploading blueprint";
+ var step_log = log_blueprint_id + "uploading blueprint";
logger.info(req.dcaeReqId, step_log);
- return cfy.uploadBlueprint(req, id, blueprint)
+
+ return cfy.checkBlueprintExits(req, bpid)
+
+ .then (function (result) {
+ logger.info(req.dcaeReqId, " checkBlueprintExits result " + result);
+ // Upload blueprint
+ if ( result === false ) {
+ logger.info(req.dcaeReqId, " blueprint with id: " + log_blueprint_id + " does not exist. Uploading");
+ return cfy.uploadBlueprint(req, bpid, blueprint)
+ }
+ else {
+ logger.info(req.dcaeReqId, " blueprint with id: " + log_blueprint_id + " already exits. No need to upload");
+ }
+ })
.then (function(result) {
step_log = log_deployment_id + "creating deployment";
logger.info(req.dcaeReqId, step_log);
// Create deployment
- return cfy.createDeployment(req, id, id, inputs);
+ return cfy.createDeployment(req, id, bpid, inputs);
})
-
// create the deployment and keep checking, for up to 5 minutes, until creation is complete
.then(function(result) {
step_log = log_deployment_id + "waiting for deployment creation";
@@ -210,22 +223,43 @@ exports.launchUninstall = function(req, deploymentId) {
exports.finishUninstall = function(req, deploymentId, executionId) {
logger.info(req.dcaeReqId, "finishUninstall: " + deploymentId + " -- executionId: " + executionId);
+ var bid = "";
return cfy.waitForWorkflowExecution(req, executionId)
.then (function(result){
logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " uninstall workflow successfully executed");
+ logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " getting associated blueprint_id");
+ return cfy.getBlueprintIdFromDeployment(req, deploymentId);
+ })
+ .then (function(result){
+ bid = result.json.blueprint_id;
+ logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " associated blueprint_id: " + bid);
// Delete the deployment
return delay(DELAY_DELETE_DEPLOYMENT).then(function() {
return cfy.deleteDeployment(req, deploymentId);
- });
+ });
})
.then (function(result){
logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " deployment deleted");
- // Delete the blueprint
- return delay(DELAY_DELETE_BLUEPRINT).then(function() {
- return cfy.deleteBlueprint(req, deploymentId);
+ return delay(DELAY_DELETE_DEPLOYMENT).then(function() {
+ return cfy.shouldBlueprintGetDeleted(req, bid);
});
})
+ .then (function (result) {
+ logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " shouldBlueprintGetDeleted: " + result);
+ if ( result === true ) {
+ return cfy.getBlueprintTenantName(req, bid)
+ .then (function(result){
+ const tenant = result.json.items[0].tenant_name;
+ logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " deleting bluerpint with id: "
+ + bid + " and tenant_name: " + tenant);
+ // Delete the blueprint
+ req.query.cfy_tenant_name = tenant;
+ return cfy.deleteBlueprint(req, bid);
+ });
+ }
+ })
.then (function(result){
+ logger.info(req.dcaeReqId, "deploymentId: " + deploymentId + " done with uninstall");
return result;
})
.catch (function(err){