aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAlex Shatov <alexs@att.com>2018-01-24 13:35:28 -0500
committerAlex Shatov <alexs@att.com>2018-01-24 13:35:28 -0500
commit4e30c82b172cf422ab5179e3c566ef01ca14cb3a (patch)
tree0efa3043daeb8001516d671df5d8e1b81ca4b798 /lib
parent70253f7088be04125d9fac8f9bddfaa63778608e (diff)
unit tests coverage 68% and more info in audit
* refactored the unit test - simpler dh server initialization * new unit tests for the dcae-deployments * new unit tests for healthcheck - info * new server_instance_uuid - unique per deployment-handler instance for logging and info * dragging req object over the stack to show req data in logging and audit and metrics * new feature variable collection of policies per component in DCAE Change-Id: I8388d7e5e11e3a6c871cf3d507bd8a07b09add29 Issue-ID: DCAEGEN2-249 Signed-off-by: Alex Shatov <alexs@att.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/cloudify.js58
-rw-r--r--lib/config.js5
-rw-r--r--lib/consul.js6
-rw-r--r--lib/dcae-deployments.js107
-rw-r--r--lib/deploy.js144
-rw-r--r--lib/info.js40
-rw-r--r--lib/inventory.js24
-rw-r--r--lib/logging.js4
-rw-r--r--lib/policy.js9
-rw-r--r--lib/promise_request.js14
10 files changed, 215 insertions, 196 deletions
diff --git a/lib/cloudify.js b/lib/cloudify.js
index 23e779a..b03ecac 100644
--- a/lib/cloudify.js
+++ b/lib/cloudify.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -75,19 +75,17 @@ var delay = function(dtime) {
};
// Get current status of a workflow execution
-const getExecutionStatus = function(execution_id, mainReq) {
- /* Defense: Some callers do not supply mainReq */
- mainReq = mainReq || {};
+const getExecutionStatus = function(req, execution_id) {
var reqOptions = {
method : "GET",
uri : cfyAPI + "/executions/" + execution_id
};
addAuthToOptions(reqOptions);
- return doRequest(reqOptions, null, CLOUDIFY, mainReq);
+ return doRequest(req, reqOptions, null, CLOUDIFY);
};
// Poll for the result of a workflow execution until it's done
-var getWorkflowResult = function(execution_id, mainReq) {
+const getWorkflowResult = function(mainReq, execution_id) {
/* Defense: Some callers do not supply mainReq */
mainReq = mainReq || {};
logger.debug(mainReq.dcaeReqId, "Getting workflow result for execution id: " + execution_id);
@@ -100,7 +98,7 @@ var getWorkflowResult = function(execution_id, mainReq) {
};
// Create execution status checker function
- var getExecStatus = function() {return getExecutionStatus(execution_id, mainReq);};
+ var getExecStatus = function() {return getExecutionStatus(mainReq, execution_id);};
return repeat.repeatWhile(getExecStatus, checkStatus, MAX_TRIES, RETRY_INTERVAL)
.then(
@@ -181,18 +179,18 @@ const startWorkflowExecution = function(mainReq, deployment_id, workflow_id, par
if (parameters) {body.parameters = parameters;}
// Make the POST request
- return doRequest(reqOptions, JSON.stringify(body), CLOUDIFY, mainReq);
+ return doRequest(mainReq, reqOptions, JSON.stringify(body), CLOUDIFY);
};
//Initiate a workflow execution against a deployment
-const initiateWorkflowExecution = function(deployment_id, workflow_id, parameters) {
- return startWorkflowExecution(null, deployment_id, workflow_id, parameters)
+const initiateWorkflowExecution = function(req, deployment_id, workflow_id, parameters) {
+ return startWorkflowExecution(req, deployment_id, workflow_id, parameters)
.then(function(result) {
- logger.debug(null, "Result from POSTing workflow execution start: " + JSON.stringify(result));
+ logger.debug(req.dcaeReqId, "Result from POSTing workflow execution start: " + JSON.stringify(result));
if (result.json && result.json.id) {
return {deploymentId: deployment_id, workflowType: workflow_id, executionId: result.json.id};
}
- logger.debug(null,"Did not get expected JSON body from POST to start workflow");
+ logger.debug(req.dcaeReqId,"Did not get expected JSON body from POST to start workflow");
var err = new Error("POST to start workflow got success response but no body");
err.status = err.code = 502;
throw err;
@@ -200,7 +198,7 @@ const initiateWorkflowExecution = function(deployment_id, workflow_id, parameter
};
// Uploads a blueprint via the Cloudify API
-exports.uploadBlueprint = function(bpid, blueprint) {
+exports.uploadBlueprint = function(req, bpid, blueprint) {
// Cloudify API wants a gzipped tar of a directory, not the blueprint text
var zip = new admzip();
@@ -220,11 +218,11 @@ exports.uploadBlueprint = function(bpid, blueprint) {
addAuthToOptions(reqOptions);
// Initiate PUT request and return the promise for a result
- return doRequest(reqOptions, src, CLOUDIFY);
+ return doRequest(req, reqOptions, src, CLOUDIFY);
};
// Creates a deployment from a blueprint
-exports.createDeployment = function(dpid, bpid, inputs) {
+exports.createDeployment = function(req, dpid, bpid, inputs) {
// Set up the HTTP PUT request
var reqOptions = {
@@ -245,7 +243,7 @@ exports.createDeployment = function(dpid, bpid, inputs) {
}
// Make the PUT request to create the deployment
- return doRequest(reqOptions, JSON.stringify(body), CLOUDIFY);
+ return doRequest(req, reqOptions, JSON.stringify(body), CLOUDIFY);
};
// Initiate a workflow execution against a deployment
@@ -258,19 +256,19 @@ exports.getWorkflowExecutionStatus = getExecutionStatus;
exports.getWorkflowResult = getWorkflowResult;
// Executes a workflow against a deployment and returns a promise for final result
-exports.executeWorkflow = function(deployment_id, workflow_id, parameters) {
- return initiateWorkflowExecution(deployment_id, workflow_id, parameters)
+exports.executeWorkflow = function(req, deployment_id, workflow_id, parameters) {
+ return initiateWorkflowExecution(req, deployment_id, workflow_id, parameters)
// Wait for the result
.then (function(result) {
- logger.debug(null, "Result from initiating workflow: " + JSON.stringify(result));
- return getWorkflowResult(result.executionId);
+ logger.debug(req.dcaeReqId, "Result from initiating workflow: " + JSON.stringify(result));
+ return getWorkflowResult(req, result.executionId);
});
};
// Retrieves outputs for a deployment
-exports.getOutputs = function(dpid) {
+exports.getOutputs = function(req, dpid) {
var reqOptions = {
method : "GET",
uri : cfyAPI + "/deployments/" + dpid + "/outputs",
@@ -280,11 +278,11 @@ exports.getOutputs = function(dpid) {
};
addAuthToOptions(reqOptions);
- return doRequest(reqOptions, null, CLOUDIFY);
+ return doRequest(req, reqOptions, null, CLOUDIFY);
};
// Get the output descriptions for a deployment
-exports.getOutputDescriptions = function(dpid) {
+exports.getOutputDescriptions = function(req, dpid) {
var reqOptions = {
method : "GET",
uri : cfyAPI + "/deployments/" + dpid + "?include=outputs",
@@ -294,29 +292,29 @@ exports.getOutputDescriptions = function(dpid) {
};
addAuthToOptions(reqOptions);
- return doRequest(reqOptions, null, CLOUDIFY);
+ return doRequest(req, reqOptions, null, CLOUDIFY);
};
// Deletes a deployment
-exports.deleteDeployment = function(dpid) {
+exports.deleteDeployment = function(req, dpid) {
var reqOptions = {
method : "DELETE",
uri : cfyAPI + "/deployments/" + dpid
};
addAuthToOptions(reqOptions);
- return doRequest(reqOptions, null, CLOUDIFY);
+ return doRequest(req, reqOptions, null, CLOUDIFY);
};
// Deletes a blueprint
-exports.deleteBlueprint = function(bpid) {
+exports.deleteBlueprint = function(req, bpid) {
var reqOptions = {
method : "DELETE",
uri : cfyAPI + "/blueprints/" + bpid
};
addAuthToOptions(reqOptions);
- return doRequest(reqOptions, null, CLOUDIFY);
+ return doRequest(req, reqOptions, null, CLOUDIFY);
};
// Allow client to set the Cloudify API root address
@@ -349,7 +347,7 @@ exports.getNodeInstances = function (mainReq, on_next_node_instances, offset) {
addAuthToOptions(reqOptions);
logger.debug(mainReq.dcaeReqId, "getNodeInstances: " + JSON.stringify(reqOptions));
- return doRequest(reqOptions, null, CLOUDIFY, mainReq)
+ return doRequest(mainReq, reqOptions, null, CLOUDIFY)
.then(function(cloudify_response) {
logger.debug(mainReq.dcaeReqId, "getNodeInstances response: " + JSON.stringify(cloudify_response));
var response = {};
@@ -403,7 +401,7 @@ const runQueuedExecution = function(mainReq, deployment_id, workflow_id, paramet
553, "api", 553, CLOUDIFY);
}
exeQueue.setExecutionId(deployment_id, execution_id);
- return getWorkflowResult(execution_id, mainReq);
+ return getWorkflowResult(mainReq, execution_id);
})
.then(function(result) {
logger.debug(mainReq.dcaeReqId, 'successfully finished execution: ' + execution_id + " for" + exe_deployment_str);
diff --git a/lib/config.js b/lib/config.js
index e44e9b5..b71199c 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -148,7 +148,8 @@ const getTLSCredentials = function() {
}
exports.configure = function() {
- var config = {};
+ const config = {};
+ config.server_instance_uuid = utils.generateId();
/* Get configuration from configuration store */
return getFileContents(PACKAGE_JSON_FILE)
diff --git a/lib/consul.js b/lib/consul.js
index 3a3257b..226291f 100644
--- a/lib/consul.js
+++ b/lib/consul.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -29,7 +29,7 @@ module.exports = {
* If there is no such key, resolve to null.
*/
getKey: function(key) {
- return doRequest({method: 'GET', uri: CONSUL_URL + KEY + key + '?raw'}, null, CONSUL)
+ return doRequest(null, {method: 'GET', uri: CONSUL_URL + KEY + key + '?raw'}, null, CONSUL)
.then(function(res) {
return res.json || res.body;
})
@@ -51,7 +51,7 @@ module.exports = {
* If the service is not found, returns a zero-length array.
*/
getService: function(serviceId) {
- return doRequest({method: 'GET', uri: CONSUL_URL + SERVICE + serviceId}, null, CONSUL)
+ return doRequest(null, {method: 'GET', uri: CONSUL_URL + SERVICE + serviceId}, null, CONSUL)
.then(function(res){
return res.json.map(function(r) {
/* Address for external service is in r.Address with r.ServiceAddress empty */
diff --git a/lib/dcae-deployments.js b/lib/dcae-deployments.js
index 38dc3c4..9c1d918 100644
--- a/lib/dcae-deployments.js
+++ b/lib/dcae-deployments.js
@@ -1,16 +1,16 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 AT&T Intellectual Property. All rights reserved.
-Licensed under the Apache License, Version 2.0 (the "License");
+Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing,
+Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied.
+CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
*/
@@ -36,11 +36,18 @@ const inventory = inv({url: config.inventory.url});
/* Set up middleware stack for initial processing of request */
app.use(middleware.checkType('application/json')); // Validate type
app.use(bodyParser.json({strict: true})); // Parse body as JSON
+app.use(function(req, res, next) {
+ log.debug(req.dcaeReqId,
+ "new req: " + req.method + " " + req.originalUrl +
+ " from: " + req.ip + " body: " + JSON.stringify(req.body)
+ );
+ next();
+});
/* Return a promise for a blueprint for the given service type ID */
-const getBlueprint = function(serviceTypeId) {
- return inventory.getBlueprintByType(serviceTypeId)
+const getBlueprint = function(req, serviceTypeId) {
+ return inventory.getBlueprintByType(req, serviceTypeId)
.then(function (blueprintInfo) {
if (!blueprintInfo.blueprint) {
var e = new Error("No service type with ID " + serviceTypeId);
@@ -48,7 +55,7 @@ const getBlueprint = function(serviceTypeId) {
throw e;
}
return blueprintInfo;
- })
+ })
};
/* Generate self and status links object for responses */
@@ -57,7 +64,7 @@ const createLinks = function(req, deploymentId, executionId) {
return {
self: baseURL,
status: baseURL + '/operation/' + executionId
- };
+ };
};
/* Generate a success response body for PUT and DELETE operations */
@@ -71,13 +78,11 @@ const createResponse = function(req, result) {
/* Look up running (or in process of deploying) instances of the given service type */
app.get('/', function (req, res, next) {
var services = []
-
-
- var searchTerm = {};
+ var searchTerm;
req.query['serviceTypeId'] && (searchTerm = {typeId: req.query['serviceTypeId']});
-
- inventory.getServicesByType(searchTerm)
+
+ inventory.getServicesByType(req, searchTerm)
.then(function (result) {
var deployments = result.map(function(service){
return {
@@ -92,70 +97,68 @@ app.get('/', function (req, res, next) {
/* Accept an incoming deployment request */
app.put('/:deploymentId', function(req, res, next) {
-
- log.debug(req.dcaeReqId, "body: " + JSON.stringify(req.body));
-
+
/* Make sure there's a serviceTypeId in the body */
if (!req.body['serviceTypeId']) {
var e = new Error ('Missing required parameter serviceTypeId');
e.status = 400;
throw e;
}
-
+
/* Make sure the deploymentId doesn't already exist */
- inventory.verifyUniqueDeploymentId(req.params['deploymentId'])
+ inventory.verifyUniqueDeploymentId(req, req.params['deploymentId'])
/* Get the blueprint for this service type */
.then(function(res) {
- return getBlueprint(req.body['serviceTypeId']);
+ return getBlueprint(req, req.body['serviceTypeId']);
})
-
- /* Add this new service instance to inventory
- * Easier to remove from inventory if deployment fails than vice versa
+
+ /* 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.params['deploymentId'], blueprintInfo.typeId, "dummyVnfId", "dummyVnfType", "dummyLocation");
+ return inventory.addService(req, req.params['deploymentId'], blueprintInfo.typeId, "dummyVnfId", "dummyVnfType", "dummyLocation");
})
-
+
/* Upload blueprint, create deployment and start install workflow (but don't wait for completion */
.then (function() {
req.dcaeAddedToInventory = true;
- return deploy.launchBlueprint(req.params['deploymentId'], req.dcaeBlueprint, req.body['inputs']);
+ return deploy.launchBlueprint(req, req.params['deploymentId'], req.dcaeBlueprint, req.body['inputs']);
})
-
+
/* Send the HTTP response indicating workflow has started */
.then(function(result) {
res.status(202).json(createResponse(req, result));
log.audit(req, 202, "Execution ID: " + result.executionId);
return result;
})
-
+
/* Finish deployment--wait for the install workflow to complete, retrieve and annotate outputs */
.then(function(result) {
- return deploy.finishInstallation(result.deploymentId, result.executionId);
+ return deploy.finishInstallation(req, result.deploymentId, result.executionId);
})
-
+
/* Log completion in audit log */
.then (function(result) {
log.audit(req, 200, "Deployed id: " + req.params['deploymentId']);
})
-
+
/* All errors show up here */
- .catch(function(error) {
-
+ .catch(function(error) {
+
/* 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.params['deploymentId'])
+ inventory.deleteService(req, req.params['deploymentId'])
.catch(function(error) {
log.error(error, req);
});
}
-
+
next(error);
}
else {
@@ -164,46 +167,46 @@ app.put('/:deploymentId', function(req, res, next) {
error.message = "Error deploying deploymentId " + req.params['deploymentId'] + ": " + error.message
log.error(error, req);
log.audit(req, 500, error.message);
- }
+ }
});
});
/* Delete a running service instance */
app.delete('/:deploymentId', function(req, res, next) {
-
+
/* Launch the uninstall workflow */
- deploy.launchUninstall(req.params['deploymentId'])
-
+ deploy.launchUninstall(req, req.params['deploymentId'])
+
/* Delete the service from inventory */
.then(function(result) {
- return inventory.deleteService(req.params['deploymentId'])
+ 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));
log.audit(req, 202, "ExecutionId: " + result.executionId);
return result;
})
-
+
/* Finish the delete processing--wait for the uninstall to complete, delete deployment, delete blueprint */
.then(function(result) {
- return deploy.finishUninstall(result.deploymentId, result.executionId);
+ 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']);
+ log.audit(req, 200, "Undeployed id: " + req.params['deploymentId']);
})
-
+
/* All errors show up here */
.catch(function(error) {
/* If we haven't already sent a response, give it to the error handler to send response */
- if (!res.headersSent) {
+ if (!res.headersSent) {
next(error);
}
else {
@@ -217,8 +220,8 @@ app.delete('/:deploymentId', function(req, res, next) {
/* Get the status of a workflow execution */
app.get('/:deploymentId/operation/:executionId', function(req, res, next){
- deploy.getExecutionStatus(req.params['executionId'])
-
+ deploy.getExecutionStatus(req, req.params['executionId'])
+
/* Send success response */
.then(function(result) {
result.requestId = req.dcaeReqId;
@@ -226,9 +229,9 @@ app.get('/:deploymentId/operation/:executionId', function(req, res, next){
res.status(200).json(result);
log.audit(req, 200, "Workflow type: " + result.operationType + " -- execution status: " + result.status);
})
-
+
.catch(next); /* Let the error handler send the response and log the error */
-
+
});
-module.exports = app; \ No newline at end of file
+module.exports = app;
diff --git a/lib/deploy.js b/lib/deploy.js
index 7f83620..e651773 100644
--- a/lib/deploy.js
+++ b/lib/deploy.js
@@ -1,16 +1,16 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 AT&T Intellectual Property. All rights reserved.
-Licensed under the Apache License, Version 2.0 (the "License");
+Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing,
+Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied.
+CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
*/
@@ -58,7 +58,7 @@ var parseContent = function(input) {
// create a normalized representation of errors, whether they're a node.js Error or a Cloudify API error
var normalizeError = function (err) {
var e;
-
+
if (err instanceof Error) {
/* node.js system error */
e = createError("Error communicating with CM: " + err.message, 504, "system", 202, 'cloudify-manager');
@@ -71,7 +71,7 @@ var normalizeError = function (err) {
var status = err.status || 502;
var cfyCode = "UNKNOWN";
var cfyMessage;
-
+
if (err.body) {
var p = parseContent(err.body);
if (p.json) {
@@ -84,28 +84,28 @@ var normalizeError = function (err) {
}
message = "Status " + status + " from CM API -- error code: " + cfyCode + " -- message: " + cfyMessage;
}
-
+
/* Pass through 400-level status, recast 500-level */
var returnStatus = (err.status > 499) ? 502 : err.status;
e = createError(message, returnStatus, "api", 502, 'cloudify-manager');
}
-
+
return e;
};
// Augment the raw outputs from a deployment with the descriptions from the blueprint
-var annotateOutputs = function (id, rawOutputs) {
+var annotateOutputs = function (req, id, rawOutputs) {
return new Promise(function(resolve, reject) {
-
+
var outItems = Object.keys(rawOutputs);
-
+
if (outItems.length < 1) {
// No output items, so obviously no descriptions, just return empty object
resolve({});
}
else {
// Call Cloudify to get the descriptions
- cfy.getOutputDescriptions(id)
+ cfy.getOutputDescriptions(req, id)
.then(function(res) {
// Assemble an outputs object with values from raw output and descriptions just obtained
var p = parseContent(res.body);
@@ -115,16 +115,16 @@ var annotateOutputs = function (id, rawOutputs) {
outs[i] = {value: rawOutputs[i]};
if (p.content.outputs[i] && p.content.outputs[i].description) {
outs[i].description = p.content.outputs[i].description;
- }
+ }
});
resolve(outs);
}
else {
reject({code: "API_INVALID_RESPONSE", message: "Invalid response for output descriptions query"});
- }
+ }
});
}
-
+
});
};
@@ -137,41 +137,43 @@ 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)
-const launchBlueprint = function(id, blueprint, inputs) {
- logger.debug(null, "deploymentId: " + id + " starting blueprint upload");
+const launchBlueprint = function(req, id, blueprint, inputs) {
+ logger.debug(req.dcaeReqId, "deploymentId: " + id + " starting blueprint upload");
// Upload blueprint
- return cfy.uploadBlueprint(id, blueprint)
-
+ return cfy.uploadBlueprint(req, id, blueprint)
+
// Create deployment
.then (function(result) {
- logger.debug(null, "deploymentId: " + id + " blueprint uploaded");
+ logger.debug(req.dcaeReqId, "deploymentId: " + id + " blueprint uploaded");
// Create deployment
- return cfy.createDeployment(id, id, inputs);
+ return cfy.createDeployment(req, id, id, inputs);
})
-
+
// Launch the workflow, but don't wait for it to complete
.then(function(result){
- logger.debug(null, "deploymentId: " + id + " deployment created");
+ logger.debug(req.dcaeReqId, "deploymentId: " + id + " deployment created");
return delay(DELAY_INSTALL_WORKFLOW)
- .then(function(){
- return cfy.initiateWorkflowExecution(id, 'install');
+ .then(function(){
+ return cfy.initiateWorkflowExecution(req, id, 'install');
});
})
.catch(function(error) {
- logger.debug(null, "Error: " + error + " for launch blueprint for deploymentId " + id);
+ logger.debug(req.dcaeReqId, "Error: " + error + " for launch blueprint for deploymentId " + id);
throw normalizeError(error);
});
};
exports.launchBlueprint = launchBlueprint;
// Finish installation launched with launchBlueprint
-const finishInstallation = function(deploymentId, executionId) {
- logger.debug(null, "finishInstallation: " + deploymentId + " -- executionId: " + executionId);
- return cfy.getWorkflowResult(executionId)
+const finishInstallation = function(req, deploymentId, executionId) {
+ logger.debug(req.dcaeReqId, "finishInstallation: " + deploymentId + " -- executionId: " + executionId);
+ return cfy.getWorkflowResult(req, executionId)
.then (function(result){
- logger.debug(null, "deploymentId: " + deploymentId + " install workflow successfully executed");
+ logger.debug(req.dcaeReqId, "deploymentId: " + deploymentId + " install workflow successfully executed");
// Retrieve the outputs from the deployment, as specified in the blueprint
- return delay(DELAY_RETRIEVE_OUTPUTS).then(function() { return cfy.getOutputs(deploymentId); });
+ return delay(DELAY_RETRIEVE_OUTPUTS).then(function() {
+ return cfy.getOutputs(req, deploymentId);
+ });
})
.then(function(result) {
// We have the raw outputs from the deployment but not annotated with the descriptions
@@ -182,45 +184,49 @@ const finishInstallation = function(deploymentId, executionId) {
if (p.content.outputs) {
rawOutputs = p.content.outputs;
}
- }
+ }
}
- logger.debug(null, "output retrieval result for " + deploymentId + ": " + JSON.stringify(result));
- return annotateOutputs(deploymentId, rawOutputs);
+ logger.debug(req.dcaeReqId, "output retrieval result for " + deploymentId + ": " + JSON.stringify(result));
+ return annotateOutputs(req, deploymentId, rawOutputs);
})
.catch(function(err) {
- logger.debug(null, "Error finishing install workflow: " + err + " -- " + JSON.stringify(err));
+ logger.debug(req.dcaeReqId, "Error finishing install workflow: " + err + " -- " + JSON.stringify(err));
throw normalizeError(err);
});
};
exports.finishInstallation = finishInstallation;
// Initiate uninstall workflow against a deployment, but don't wait for workflow to finish
-const launchUninstall = function(deploymentId) {
- logger.debug(null, "deploymentId: " + deploymentId + " starting uninstall workflow");
+const launchUninstall = function(req, deploymentId) {
+ logger.debug(req.dcaeReqId, "deploymentId: " + deploymentId + " starting uninstall workflow");
// Run uninstall workflow
- return cfy.initiateWorkflowExecution(deploymentId, 'uninstall')
+ return cfy.initiateWorkflowExecution(req, deploymentId, 'uninstall')
.then(function(result) {
return result;
})
.catch(function(err) {
- logger.debug(null, "Error initiating uninstall workflow: " + err + " -- " + JSON.stringify(err));
+ logger.debug(req.dcaeReqId, "Error initiating uninstall workflow: " + err + " -- " + JSON.stringify(err));
throw normalizeError(err);
- });
+ });
};
exports.launchUninstall = launchUninstall;
-const finishUninstall = function(deploymentId, executionId) {
- logger.debug(null, "finishUninstall: " + deploymentId + " -- executionId: " + executionId);
- return cfy.getWorkflowResult(executionId)
+const finishUninstall = function(req, deploymentId, executionId) {
+ logger.debug(req.dcaeReqId, "finishUninstall: " + deploymentId + " -- executionId: " + executionId);
+ return cfy.getWorkflowResult(req, executionId)
.then (function(result){
- logger.debug(null, "deploymentId: " + deploymentId + " uninstall workflow successfully executed");
+ logger.debug(req.dcaeReqId, "deploymentId: " + deploymentId + " uninstall workflow successfully executed");
// Delete the deployment
- return delay(DELAY_DELETE_DEPLOYMENT).then(function() {return cfy.deleteDeployment(deploymentId);});
+ return delay(DELAY_DELETE_DEPLOYMENT).then(function() {
+ return cfy.deleteDeployment(req, deploymentId);
+ });
})
.then (function(result){
- logger.debug(null, "deploymentId: " + deploymentId + " deployment deleted");
+ logger.debug(req.dcaeReqId, "deploymentId: " + deploymentId + " deployment deleted");
// Delete the blueprint
- return delay(DELAY_DELETE_BLUEPRINT).then(function() {return cfy.deleteBlueprint(deploymentId);});
+ return delay(DELAY_DELETE_BLUEPRINT).then(function() {
+ return cfy.deleteBlueprint(req, deploymentId);
+ });
})
.then (function(result){
return result;
@@ -228,19 +234,19 @@ const finishUninstall = function(deploymentId, executionId) {
.catch (function(err){
throw normalizeError(err);
});
-
+
};
exports.finishUninstall = finishUninstall;
// Get the status of a workflow execution
-exports.getExecutionStatus = function (exid) {
- return cfy.getWorkflowExecutionStatus(exid)
+exports.getExecutionStatus = function (req, exid) {
+ return cfy.getWorkflowExecutionStatus(req, exid)
.then(function(res){
-
+
var result = {
operationType: res.json.workflow_id
};
-
+
// Map execution status
if (res.json.status === "terminated") {
result.status = "succeeded";
@@ -254,11 +260,11 @@ exports.getExecutionStatus = function (exid) {
else {
result.status = "processing";
}
-
+
if (res.json.error) {
result.error = res.json.error;
}
- logger.debug(null, "getExecutionStatus result: " + JSON.stringify(result));
+ logger.debug(req.dcaeReqId, "getExecutionStatus result: " + JSON.stringify(result));
return result;
})
.catch(function(error) {
@@ -267,37 +273,37 @@ exports.getExecutionStatus = function (exid) {
};
// Go through the Cloudify API call sequence to do a deployment
-exports.deployBlueprint = function(id, blueprint, inputs) {
+exports.deployBlueprint = function(req, id, blueprint, inputs) {
+
+ // Upload blueprint, create deployment, and initiate install workflow
+ return launchBlueprint(req, id, blueprint, inputs)
- // Upload blueprint, create deployment, and initiate install workflow
- return launchBlueprint(id, blueprint, inputs)
-
// Wait for the workflow to complete
.then(
-
+
// launchBlueprint promise fulfilled -- finish installation
function(result){
- return finishInstallation(result.deploymentId, result.executionId); // Will throw normalized error if it fails
+ return finishInstallation(req, result.deploymentId, result.executionId); // Will throw normalized error if it fails
},
-
+
// launchBlueprint promise rejected -- report error
function(err) {
- throw normalizeError(err);
+ throw normalizeError(err);
});
};
// Go through the Cloudify API call sequence to do an undeployment of a previously deployed blueprint
-exports.undeployDeployment = function(id) {
- logger.debug(null, "deploymentId: " + id + " starting uninstall workflow");
-
+exports.undeployDeployment = function(req, id) {
+ logger.debug(req.dcaeReqId, "deploymentId: " + id + " starting uninstall workflow");
+
// Run launch uninstall workflow
- return launchUninstall(id)
-
+ return launchUninstall(req, id)
+
// launchUninstall promise fulfilled -- finish uninstall
.then (function(result){
- return finishUninstall(result.deploymentId, result.executionId); // Will throw normalized error if it fails
+ return finishUninstall(req, result.deploymentId, result.executionId); // Will throw normalized error if it fails
},
-
+
// launchUninstall promise rejected -- report error
function(err){
throw normalizeError(err);
diff --git a/lib/info.js b/lib/info.js
index f6b37a8..1c15349 100644
--- a/lib/info.js
+++ b/lib/info.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -19,27 +19,27 @@ See the License for the specific language governing permissions and limitations
"use strict";
const router = require('express').Router();
-
-/* Pick up config exported by main */
-const config = process.mainModule.exports.config;
+const logger = require('./logging').getLogger();
/* Accept an incoming event */
router.get('/', function(req, res) {
- res.json(
- {
- "server" : {
- "name": config.name,
- "description": config.description,
- "version": config.version,
- "branch": config.branch,
- "commit": config.commit,
- "commit_datetime": config.commit_datetime
- },
- "apiVersion": config.apiVersion,
- "links": config.apiLinks
- }
- );
- require('./logging').getLogger().audit(req, 200);
+ /* Pick up config exported by main */
+ const config = process.mainModule.exports.config;
+ const info = {
+ "server" : {
+ "name": config.name,
+ "description": config.description,
+ "version": config.version,
+ "branch": config.branch,
+ "commit": config.commit,
+ "commit_datetime": config.commit_datetime,
+ "server_instance_uuid": config.server_instance_uuid
+ },
+ "apiVersion": config.apiVersion,
+ "links": config.apiLinks
+ };
+ res.json(info);
+ logger.audit(req, 200, JSON.stringify(info));
});
-module.exports = router; \ No newline at end of file
+module.exports = router;
diff --git a/lib/inventory.js b/lib/inventory.js
index c2e13c9..ecc790a 100644
--- a/lib/inventory.js
+++ b/lib/inventory.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -55,7 +55,7 @@ module.exports = function(options) {
return {
/* Add a DCAE service to the inventory. Done after a deployment.*/
- addService: function(deploymentId, serviceType, vnfId, vnfType, vnfLocation, outputs) {
+ addService: function(req, deploymentId, serviceType, vnfId, vnfType, vnfLocation, outputs) {
/* Create the service description */
var serviceDescription =
@@ -83,23 +83,23 @@ module.exports = function(options) {
json: serviceDescription
};
- return doRequest(reqOptions, null, INVENTORY);
+ return doRequest(req, reqOptions, null, INVENTORY);
},
/* Remove a DCAE service from the inventory. Done after an undeployment. */
- deleteService: function(serviceId) {
- return doRequest({method: "DELETE", uri: url + INV_SERVICES + "/" + serviceId}, null, INVENTORY);
+ deleteService: function(req, serviceId) {
+ return doRequest(req, {method: "DELETE", uri: url + INV_SERVICES + "/" + serviceId}, null, INVENTORY);
},
/* Find running/deploying instances of services (with a given type name, if specified) */
- getServicesByType: function(query) {
+ getServicesByType: function(req, query) {
var options = {
method: 'GET',
uri: url + INV_SERVICES,
- qs: query || {}
+ qs: query
};
- return doRequest(options, null, INVENTORY)
+ return doRequest(req, options, null, INVENTORY)
.then (function (result) {
var services = [];
var content = JSON.parse(result.body);
@@ -113,8 +113,8 @@ module.exports = function(options) {
},
/* Find a blueprint given the service type ID -- return blueprint and type ID */
- getBlueprintByType: function(serviceTypeId) {
- return doRequest({
+ getBlueprintByType: function(req, serviceTypeId) {
+ return doRequest(req, {
method: "GET",
uri: url + INV_SERV_TYPES + '/' + serviceTypeId
}, null, INVENTORY)
@@ -138,8 +138,8 @@ module.exports = function(options) {
* deployment ID as service name. If it doesn't exist, the function
* resolves its promise. If it *does* exist, then it throws an error.
*/
- verifyUniqueDeploymentId: function(deploymentId) {
- return doRequest({
+ verifyUniqueDeploymentId: function(req, deploymentId) {
+ return doRequest(req, {
method: "GET",
uri: url + INV_SERVICES + "/" + deploymentId
}, null, INVENTORY)
diff --git a/lib/logging.js b/lib/logging.js
index a21f37e..cfd987d 100644
--- a/lib/logging.js
+++ b/lib/logging.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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,6 +130,7 @@ const DEBUG_MARKER = '^';
const formatAuditRecord = function(req, status, extra) {
var rec = new Array(AUDIT_NFIELDS);
const end = new Date();
+ rec[AUDIT_INSTUUID] = (process.mainModule.exports.config || {}).server_instance_uuid || "";
rec[AUDIT_END] = end.toISOString();
rec[AUDIT_BEGIN] = req.startTime.toISOString();
rec[AUDIT_REQID] = req.dcaeReqId;
@@ -161,6 +162,7 @@ const formatAuditRecord = function(req, status, extra) {
const formatMetricsRecord = function(req, opInfo, extra) {
var rec = new Array(METRICS_NFIELDS);
const end = new Date();
+ rec[METRICS_INSTUUID] = (process.mainModule.exports.config || {}).server_instance_uuid || "";
rec[METRICS_END] = end.toISOString();
rec[METRICS_BEGIN] = opInfo.startTime.toISOString();
diff --git a/lib/policy.js b/lib/policy.js
index 482650a..89e5b6a 100644
--- a/lib/policy.js
+++ b/lib/policy.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -324,6 +324,13 @@ app.set('x-powered-by', false);
app.set('etag', false);
app.use(require('./middleware').checkType('application/json'));
app.use(require('body-parser').json({strict: true}));
+app.use(function(req, res, next) {
+ logger.debug(req.dcaeReqId,
+ "new req: " + req.method + " " + req.originalUrl +
+ " from: " + req.ip + " body: " + JSON.stringify(req.body)
+ );
+ next();
+});
app.post('/', policyUpdate);
app.get('/components', getComponentPoliciesFromCloudify);
diff --git a/lib/promise_request.js b/lib/promise_request.js
index 0572ac4..975f12d 100644
--- a/lib/promise_request.js
+++ b/lib/promise_request.js
@@ -1,5 +1,5 @@
/*
-Copyright(c) 2017 AT&T Intellectual Property. All rights reserved.
+Copyright(c) 2018 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.
@@ -31,11 +31,11 @@ const url = require('url');
const querystring = require('querystring');
const logger = require('./logging').getLogger();
-exports.doRequest = function(options, body, targetEntity, mainReq) {
-
+exports.doRequest = function(mainReq, options, body, targetEntity) {
+
/* Defense: for now, some callers don't provide mainReq */
mainReq = mainReq || {};
-
+
var opInfo = {"startTime":new Date(), "targetEntity": targetEntity};
return new Promise(function(resolve, reject) {
@@ -56,10 +56,12 @@ exports.doRequest = function(options, body, targetEntity, mainReq) {
options.hostname = parsed.hostname;
options.port = parsed.port;
options.path = parsed.path;
+ opInfo.targetService = options.method + " " + options.uri;
if (options.qs) {
- options.path += ('?' + querystring.stringify(options.qs));
+ const qry = ('?' + querystring.stringify(options.qs));
+ options.path += qry;
+ opInfo.targetService += qry;
}
- opInfo.targetService = options.method + " " + options.uri;
}
try {