aboutsummaryrefslogtreecommitdiffstats
path: root/lib/cloudify.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/cloudify.js')
-rw-r--r--lib/cloudify.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/lib/cloudify.js b/lib/cloudify.js
index 053bdb8..5ab0663 100644
--- a/lib/cloudify.js
+++ b/lib/cloudify.js
@@ -20,8 +20,11 @@ See the License for the specific language governing permissions and limitations
const CLOUDIFY = "cloudify-manager";
const FINISHED = [ "terminated", "cancelled", "failed" ];
+const DEPLOYMENT_CREATION_FINISHED = [ "terminated" ];
const RETRY_INTERVAL = 5000; // Every 5 seconds
const MAX_TRIES = 720; // Up to 1 hour
+const DEP_CREATION_STATUS_RETRY_INTERVAL = 30000; // Every 30 seconds
+const DEP_CREATION_STATUS_MAX_TRIES = 10; // Up to 5 minutes
const DEFAULT_TENANT = "default_tenant";
const doRequest = require('./promise_request').doRequest;
const repeat = require('./repeat');
@@ -79,6 +82,17 @@ const getExecutionStatus = function(req, execution_id) {
return doRequest(req, reqOptions, null, CLOUDIFY);
};
+// Get current status of a deployment creation
+const getDeploymentCreationStatus = function(req, deployment_id) {
+ var reqOptions = {
+ method : "GET",
+ uri : cfyAPI + "/executions?deployment_id=" + deployment_id + "&workflow_id=create_deployment_environment&_include=id,status"
+ };
+ addAuthToOptions(reqOptions, req);
+
+ return doRequest(req, reqOptions, null, CLOUDIFY);
+};
+
// Poll for the result of a workflow execution until it's done
const getWorkflowResult = function(mainReq, execution_id) {
/* Defense: Some callers do not supply mainReq */
@@ -194,6 +208,83 @@ const initiateWorkflowExecution = function(req, deployment_id, workflow_id, para
});
};
+// Poll for the deployment creation status
+const getDeploymentCreationResult = function(mainReq, deployment_id) {
+ /* Defense: Some callers do not supply mainReq */
+ mainReq = mainReq || {};
+ logger.info(mainReq.dcaeReqId, "Getting status for deployment id: " + deployment_id);
+
+ // Function for testing if deployment creation is complete
+ // Expects the result of getDepCrStatus
+ const checkDepStatus = function(cloudify_response) {
+ cloudify_response = cloudify_response && cloudify_response.json;
+ logger.info(mainReq.dcaeReqId, "Checking Deployment creation result: " + JSON.stringify(cloudify_response) + " ==> " +
+ (cloudify_response.items.length == 1 && DEPLOYMENT_CREATION_FINISHED.indexOf(cloudify_response.items[0].status) < 0));
+ return cloudify_response.items.length == 1 && DEPLOYMENT_CREATION_FINISHED.indexOf(cloudify_response.items[0].status) < 0;
+ };
+
+ // Create deployment creation status checker function
+ const getDepCrStatus = function() {return getDeploymentCreationStatus(mainReq, deployment_id);};
+
+ return repeat.repeatWhile(getDepCrStatus, checkDepStatus, DEP_CREATION_STATUS_MAX_TRIES, DEP_CREATION_STATUS_RETRY_INTERVAL)
+ .then(
+
+ /* Handle fulfilled promise from repeatWhile */
+ function(res) {
+
+ logger.info(mainReq.dcaeReqId, 'Deployment creation result: ' + JSON.stringify(res));
+
+ /* Successful completion */
+ if (res.json && res.json.items.length == 1 && res.json.items[0].status === 'terminated') {
+ logger.info(mainReq.dcaeReqId, 'Deployment creation completed for deployment_id: ' + deployment_id);
+ return res;
+ }
+
+ /* If we get here, we don't have a success and we're going to throw something */
+
+ var error = {};
+
+ /* We expect a JSON object with a status */
+ if (res.json && res.json.items.length == 1 && res.json.items[0].status) {
+
+ /* Failure -- we need to return something that looks like the CM API failures */
+ if (res.json.items[0].status === 'failed') {
+ error.body = 'Deployment creation failed: ' + deployment_id + ' -- ' + (res.json.error ? JSON.stringify(res.json.error) : 'no error information');
+ }
+
+ /* Cancellation -- don't really expect this */
+ else if (res.json.items[0].status === 'canceled' || res.json.status === 'cancelled') {
+ error.body = 'Deployment creation canceled: ' + deployment_id;
+ }
+
+ /* Don't expect anything else -- but if we get it, it's not a success! */
+ else {
+ error.body = 'Deployment creation--unexpected status ' + res.json.items[0].status + ' for ' + deployment_id;
+ }
+ }
+
+ /* The body of the response from the API call to get execution status is not what we expect at all */
+ else {
+ error.body = 'Deployment creation--unexpected result body getting execution status from CM for ' + deployment_id;
+ }
+
+ throw error;
+ },
+
+ /* Handle rejection of promise from repeatWhile--don't use a catch because it would catch the error thrown above */
+ function(err) {
+ /* repeatWhile could fail and we get here because:
+ * -- repeatWhile explicitly rejects the promise because it has exhausted the retries
+ * -- repeatWhile propagates a system error (e.g., network problem) trying to access the API
+ * -- repeatWhile propagates a rejected promise due to a bad HTTP response status
+ * These should all get normalized in deploy.js--so we just rethrow the error.
+ */
+
+ throw err;
+
+ });
+};
+
// Uploads a blueprint via the Cloudify API
exports.uploadBlueprint = function(req, bpid, blueprint) {
logger.info(req.dcaeReqId, "uploadBlueprint " + bpid);
@@ -264,6 +355,11 @@ exports.executeWorkflow = function(req, deployment_id, workflow_id, parameters)
});
};
+// Return a promise for the final result of a deployment update
+exports.getDeploymentCreationResult = getDeploymentCreationResult;
+
+// Get the status of a deployment update
+exports.getDeploymentCreationStatus = getDeploymentCreationStatus;
// Retrieves outputs for a deployment
exports.getOutputs = function(req, dpid) {
@@ -469,3 +565,4 @@ exports.executeOperation = function (mainReq, deployment_id, operation, operatio
exeQueue.queueUpExecution(mainReq, deployment_id, workflow_id, parameters);
runQueuedExecution(mainReq, deployment_id, workflow_id, parameters);
};
+