Name
sn_cimaf.CIActionEngineSNC
Description
No description available
Script
var CIActionEngineSNC = Class.create();
CIActionEngineSNC.prototype = {
CI_AVAILABILITY_EXT_POINT: "sn_cimaf.CIAvailabilityHandler",
TABLES: {
CI_ACTION: "sn_cimaf_action",
CMDB_CI: "cmdb_ci",
ACTION_CONFIG: "sn_cimaf_action_config",
ACTION_PARAMETER: "sn_cimaf_action_parameter",
ACTION_REQUEST: "sn_cimaf_action_request",
ACTION_OUTPUT: "sn_cimaf_action_output",
ACTION_ROLE: "sn_cimaf_action_role",
USER_CRITERIA_ACTION_INCLUSION: "sn_cimaf_action_user_criteria_mtom",
USER_CRITERIA_ACTION_EXCLUSION: "sn_cimaf_action_user_criteria_no_mtom"
},
FIELDS: {
SYS_ID: "sys_id",
SYS_DOMAIN: "sys_domain",
ACTION_CONFIG: {
action: "action",
execution_flow: "execution_flow",
execution_script: "execution_script",
order: "order"
},
ACTION_PARAMETER: {
model: "model",
element: "element",
mandatory: "mandatory",
default_value: "default_value"
},
ACTION_REQUEST: {
state: "state",
action_config: "action_config",
configuration_item: "configuration_item",
action_parameters: "action_parameters",
sys_created_on: "sys_created_on"
},
ACTION_OUTPUT: {
action_command: "action_command",
action_request: "action_request",
payload: "payload",
state: "state",
request_id: "request_id"
},
ACTION_ROLE: {
ACTION: "action",
ROLE: "role"
},
USER_CRITERIA_ACTION_INCLUSION: {
ACTION: "action",
USER_CRITERIA: "user_criteria"
},
USER_CRITERIA_ACTION_EXCLUSION: {
ACTION: "action",
USER_CRITERIA: "user_criteria"
}
},
STATE: {
ACTION_REQUEST: {
in_progress: "in_progress",
completed: "completed",
failed: "failed"
}
},
EXECUTE_ACTION_TYPE: {
FLOW: "flow",
SCRIPT: "script"
},
USER_CRITERIA: "user_criteria",
PROPERTIES: {
ACTION_REQUEST_DUPLICATE_REQUEST_TIME: {
name: "sn_cimaf.action_request.duplicate_request_time_limit",
defaultValue: 5
}
},
initialize: function() {
this.ciActionHelper = new CIActionHelper();
},
execute: function(ciAction, ci, actionParams) {
if (!ci) {
gs.error("[CIActionEngine]: provide either the GlideRecord reference or sys_id of the CI item");
return;
}
if (!ciAction) {
gs.error("[CIActionEngine]: provide either the GlideRecord reference or sys_id of the Action Definition record");
return;
}
if (typeof ciAction === 'string') {
if (this.ciActionHelper.isSysId(ciAction)) {
ciAction = this.ciActionHelper._getGlideRecord(this.TABLES.CI_ACTION, ciAction);
} else {
ciAction = this.ciActionHelper._getGlideRecordByInternalName(this.TABLES.CI_ACTION, ciAction);
}
}
if (typeof ci === 'string') {
ci = this._getGlideRecord(ciAction.ci_class, ci);
}
if (typeof actionParams === 'string') {
try {
actionParams = JSON.parse(actionParams);
} catch (e) {
gs.error("[CIActionEngine - execute]: Invalid actionParams");
return;
}
} else {
actionParams = actionParams || {};
}
if (!ci || !ci.isValidRecord()) {
gs.error("[CIActionEngine]: Provided CI is not a valid record");
return;
}
if (!ciAction || !ciAction.isValidRecord()) {
gs.error("[CIActionEngine]: Provided Action is not a valid record");
return;
}
if (!this.isAuthorized(ciAction)) {
gs.error("[CIActionEngine]: User is not authorized to perform provided Action");
return;
}
var actionRequestId = this._checkDuplicateRequestInProgress(ciAction.getUniqueValue(), ci.getUniqueValue(), actionParams);
if (actionRequestId) {
return actionRequestId;
}
var actionConfig = this._getActionConfig(ciAction, ci);
if (!actionConfig) {
gs.error("[CIActionEngine]: Did not find any matching Action config record for the CI item " + ci.getDisplayValue());
return;
}
if (!this._isActionParamsValid(actionConfig, actionParams)) {
gs.error("[CIActionEngine]: Action parameters missing or not valid for action config " + actionConfig.getDisplayValue());
return;
}
var ciDomain = ci.getValue(this.FIELDS.SYS_DOMAIN);
try {
var createActionRequestInputs = {};
createActionRequestInputs['action_config_sys_id'] = actionConfig.getUniqueValue();
createActionRequestInputs['ci_sys_id'] = ci.getUniqueValue();
createActionRequestInputs['action_params'] = actionParams;
var result = sn_fd.FlowAPI.getRunner()
.action('sn_cimaf.create_action_request_record')
.inForeground()
.inDomain(ciDomain)
.withInputs(createActionRequestInputs)
.run();
var outputs = result.getOutputs();
actionRequestId = outputs['action_request_sys_id'];
} catch (ex) {
gs.error("[CIActionEngine]: Error while creating action request record with inputs " + JSON.stringify(createActionRequestInputs) + ". Error: " + ex);
return;
}
if (!actionRequestId) {
gs.error("[CIActionEngine]: Could not create action request record for action config " + actionConfig.getDisplayValue() + " and CI item " + ci.getDisplayValue());
return;
}
var ciActionExecutionInputs = {};
ciActionExecutionInputs['skip_pre_request_checks'] = false;
ciActionExecutionInputs['action_request_sys_id'] = actionRequestId;
ciActionExecutionInputs['action_config_sys_id'] = actionConfig.getUniqueValue();
ciActionExecutionInputs['action_params'] = actionParams;
ciActionExecutionInputs['ci_sys_id'] = ci.getUniqueValue();
try {
sn_fd.FlowAPI.getRunner()
.subflow('sn_cimaf.ci_action_execution')
.inBackground()
.inDomain(ciDomain)
.withInputs(ciActionExecutionInputs)
.run();
} catch (ex) {
var actionHelper = new CIActionHelper();
actionHelper.updateActionRequestById(actionRequestId, this.STATE.ACTION_REQUEST.failed);
gs.error("[CIActionEngine]: Error while initiating ci action execution subflow with inputs " + JSON.stringify(ciActionExecutionInputs) + ". Error: " + ex.getMessage());
return;
}
return actionRequestId;
},
/**
* @param Object ciAction - GlideRecord reference to the the Action record
* @return Boolean value indicating if current logged-in user is authorized to perform given action
**/
isAuthorized: function(ciAction) {
var isUserRoleAllowed = this._isUserRoleAllowed(ciAction);
var isUserCriteriaIncluded = this._isUserCriteriaIncluded(ciAction);
var isUserCriteriaExcluded = this._isUserCriteriaExcluded(ciAction);
if (!isUserRoleAllowed['isConfigured'] && !isUserCriteriaIncluded['isConfigured'] && !isUserCriteriaExcluded['isConfigured'])
return false;
if (!isUserRoleAllowed['status'] || !isUserCriteriaIncluded['status'] || isUserCriteriaExcluded['status'])
return false;
return true;
},
getActionRequestOutputById: function(actionRequestSysId) {
if (!actionRequestSysId) {
gs.error("[CIActionEngine - getActionRequestOutputById]: Invalid action request sys id");
return;
}
var actionRequestGr = this._getGlideRecord(this.TABLES.ACTION_REQUEST, actionRequestSysId);
if (actionRequestGr) {
return this.getActionRequestOutput(actionRequestGr);
}
},
getActionRequestOutput: function(actionRequestGr) {
if (!this._isValidGr(actionRequestGr)) {
gs.error("[CIActionEngine - getActionRequestOutput]: Invalid action request record");
return;
}
var actionOutputFields = this.FIELDS.ACTION_OUTPUT;
var requiredActionOutputFields = [this.FIELDS.SYS_ID, actionOutputFields.action_command, actionOutputFields.payload,
actionOutputFields.state, actionOutputFields.request_id];
var actionOutputGr = new GlideRecord(this.TABLES.ACTION_OUTPUT);
actionOutputGr.addQuery(actionOutputFields.action_request, actionRequestGr.getUniqueValue());
actionOutputGr.query();
var actionOutputs = [];
while (actionOutputGr.next()) {
var actionOutput = {};
for (var i = 0; i < requiredActionOutputFields.length; i++) {
var field = requiredActionOutputFields[i];
actionOutput[field] = actionOutputGr.getValue(field);
}
actionOutputs.push(actionOutput);
}
var actionRequestOutput = {};
actionRequestOutput[this.FIELDS.SYS_ID] = actionRequestGr.getUniqueValue();
actionRequestOutput[this.FIELDS.ACTION_REQUEST.state] = actionRequestGr.getValue(this.FIELDS.ACTION_REQUEST.state);
actionRequestOutput[this.TABLES.ACTION_OUTPUT] = actionOutputs;
return actionRequestOutput;
},
getExecutingActionsByCI: function(ciGrOrSysId) {
var ciSysId = this._isValidGr(ciGrOrSysId) ? ciGrOrSysId.getUniqueValue() : ciGrOrSysId;
if (!ciSysId) {
gs.error("[CIActionEngine - getRunningActionsByCI]: Invalid CI");
return;
}
var result = [];
var actionRequestGr = new GlideRecord(this.TABLES.ACTION_REQUEST);
actionRequestGr.addQuery(this.FIELDS.ACTION_REQUEST.configuration_item, ciSysId);
actionRequestGr.addQuery(this.FIELDS.ACTION_REQUEST.state, this.STATE.ACTION_REQUEST.in_progress);
actionRequestGr.query();
while (actionRequestGr.next()) {
result.push(this.getActionRequestOutput(actionRequestGr));
}
return result;
},
_isUserRoleAllowed: function(ciAction) {
var actionRoleGr = new GlideRecord(this.TABLES.ACTION_ROLE);
actionRoleGr.addQuery(this.FIELDS.ACTION_ROLE.ACTION, ciAction.getUniqueValue());
actionRoleGr.addNotNullQuery(this.FIELDS.ACTION_ROLE.ROLE);
actionRoleGr.query();
if (!actionRoleGr.hasNext()){
return {
"isConfigured": false,
"status": true
};
}
while (actionRoleGr.next()){
if (gs.hasRole(actionRoleGr.role.name)){
return {
"isConfigured": true,
"status": true
};
}
}
return {
"isConfigured": true,
"status": false
};
},
_isUserCriteriaIncluded: function(ciAction) {
var includedUCs = this._fetchAssociatedUCs(this.TABLES.USER_CRITERIA_ACTION_INCLUSION,
this.FIELDS.USER_CRITERIA_ACTION_INCLUSION.ACTION,
ciAction.getUniqueValue());
if (!includedUCs.length){
return {
"isConfigured": false,
"status": true
};
}
return {
"isConfigured": true,
"status": sn_uc.UserCriteriaLoader.userMatches(gs.getUserID(), includedUCs)
};
},
_isUserCriteriaExcluded: function(ciAction) {
var excludedUCs = this._fetchAssociatedUCs(this.TABLES.USER_CRITERIA_ACTION_EXCLUSION,
this.FIELDS.USER_CRITERIA_ACTION_EXCLUSION.ACTION,
ciAction.getUniqueValue());
if (!excludedUCs.length){
return {
"isConfigured": false,
"status": false
};
}
return {
"isConfigured": true,
"status": sn_uc.UserCriteriaLoader.userMatches(gs.getUserID(), excludedUCs)
};
},
_fetchAssociatedUCs: function(tableName, columnName, columnValue) {
var gr = new GlideRecord(tableName);
gr.addQuery(columnName, columnValue);
gr.addNotNullQuery(this.USER_CRITERIA);
gr.query();
var ucs = [];
while (gr.next())
ucs.push(gr.getValue(this.USER_CRITERIA));
return ucs;
},
_getActionConfig: function(ciActionGr, cmdbCiGr) {
var actionConfigGr = new GlideRecord(this.TABLES.ACTION_CONFIG);
actionConfigGr.addQuery(this.FIELDS.ACTION_CONFIG.action, ciActionGr.getUniqueValue());
actionConfigGr.orderBy(this.FIELDS.ACTION_CONFIG.order);
actionConfigGr.query();
while (actionConfigGr.next()) {
if (
(
(actionConfigGr.action_type == this.EXECUTE_ACTION_TYPE.FLOW && global.JSUtil.notNil(actionConfigGr.execution_flow)) ||
(actionConfigGr.action_type == this.EXECUTE_ACTION_TYPE.SCRIPT && global.JSUtil.notNil(actionConfigGr.execution_script)) ||
(global.JSUtil.notNil(actionConfigGr.provider) && global.JSUtil.notNil(actionConfigGr.provider.default_action_execution_flow))
) &&
this._isActionConfigApplicable(actionConfigGr, cmdbCiGr))
return actionConfigGr;
}
return null;
},
_isProviderApplicable: function(provider, cmdbCiGr) {
var extPoints = new GlideScriptedExtensionPoint().getExtensions(this.CI_AVAILABILITY_EXT_POINT);
if (!extPoints.length) {
gs.info("[_isProviderApplicable]: Did not find any extension point defined");
return false;
}
for (var i = 0; i < extPoints.length; i++) {
var extPointSI = extPoints[i];
if (typeof extPointSI.getProvider == "function" && extPointSI.getProvider() === provider && extPointSI.isProviderApplicable(cmdbCiGr)) {
return true;
}
}
return false;
},
_isActionConfigApplicable: function(actionConfigGr, cmdbCiGr) {
if (!this._isProviderApplicable(actionConfigGr.getValue("provider"), cmdbCiGr)) {
return false;
}
var isCiConditionMatching;
if (actionConfigGr.match_ci_extensions + "" === 'true') {
var tableExtension = new GlideTableHierarchy(actionConfigGr.ci_class + "").getTableExtensions();
tableExtension.push(actionConfigGr.ci_class + "");
isCiConditionMatching = tableExtension.indexOf(cmdbCiGr.sys_class_name + "") > -1;
} else {
isCiConditionMatching = (actionConfigGr.ci_class + "" === cmdbCiGr.sys_class_name + "");
}
isCiConditionMatching = isCiConditionMatching && GlideFilter.checkRecord(cmdbCiGr, actionConfigGr.ci_conditions + "");
return isCiConditionMatching;
},
_isActionParamsValid: function(actionConfig, actionParams) {
var actionParamsGr = new GlideRecord(this.TABLES.ACTION_PARAMETER);
actionParamsGr.addActiveQuery();
actionParamsGr.addQuery(this.FIELDS.ACTION_PARAMETER.model, actionConfig.getUniqueValue());
actionParamsGr.query();
var activeParams = [];
while (actionParamsGr.next()) {
var paramName = actionParamsGr.getValue(this.FIELDS.ACTION_PARAMETER.element);
if(typeof actionParams[paramName] === 'undefined')
actionParams[paramName] = actionParamsGr.getValue(this.FIELDS.ACTION_PARAMETER.default_value) || "";
var isParamMandatory = actionParamsGr.getValue(this.FIELDS.ACTION_PARAMETER.mandatory) == "1";
if(isParamMandatory && actionParams[paramName] === "")
return false;
activeParams.push(paramName);
}
var actionParamsKeys = Object.keys(actionParams);
for(var i = 0; i < actionParamsKeys.length; i++) {
var param = actionParamsKeys[i];
if(activeParams.indexOf(param) == -1) {
gs.info("[CIActionEngine]: Action parameter - " + param + " is inactive or not configured for the Action configuration");
delete actionParams[param];
}
}
return true;
},
_getGlideRecord: function(tableName, sysId) {
var gr = new GlideRecord(tableName);
if (gr.get(sysId))
return gr;
},
_checkDuplicateRequestInProgress:function(ciActionSysId, ciSysId, ciActionParams) {
var actionRequestGr = new GlideRecord(this.TABLES.ACTION_REQUEST);
actionRequestGr.addQuery(this.FIELDS.ACTION_REQUEST.state, this.STATE.ACTION_REQUEST.in_progress);
actionRequestGr.addQuery(this.FIELDS.ACTION_REQUEST.configuration_item, ciSysId);
actionRequestGr.addQuery(this.FIELDS.ACTION_REQUEST.action_config + '.' + this.FIELDS.ACTION_CONFIG.action, ciActionSysId);
var timeLimit = gs.getProperty(this.PROPERTIES.ACTION_REQUEST_DUPLICATE_REQUEST_TIME.name, this.PROPERTIES.ACTION_REQUEST_DUPLICATE_REQUEST_TIME.defaultValue);
actionRequestGr.addQuery(this.FIELDS.ACTION_REQUEST.sys_created_on + "RELATIVEGT@minute@ago@" + timeLimit);
actionRequestGr.query();
while (actionRequestGr.next()) {
var result = this.compareJSON(this.getActionParams(actionRequestGr), ciActionParams);
if (result) {
return actionRequestGr.getUniqueValue();
}
}
},
getActionParams: function(actionRequestGr) {
var actionParamGr = new GlideRecord(this.TABLES.ACTION_PARAMETER);
actionParamGr.addActiveQuery();
actionParamGr.addQuery(this.FIELDS.ACTION_PARAMETER.model, actionRequestGr.getValue(this.FIELDS.ACTION_REQUEST.action_config));
actionParamGr.query();
var actionParams = {};
var execParams = actionRequestGr[this.FIELDS.ACTION_REQUEST.action_parameters];
while (actionParamGr.next()) {
var paramName = actionParamGr.getValue(this.FIELDS.ACTION_PARAMETER.element);
if (execParams[paramName])
actionParams[paramName] = execParams[paramName] + "";
}
return actionParams;
},
compareJSON: function(param1, param2) {
var keys = Object.keys(param1);
for(var i = 0; i < keys.length; i++) {
if (!param2.hasOwnProperty(keys[i]) || param1[keys[i]] !== param2[keys[i]]) {
return false;
}
}
return true;
},
_isValidGr: function(gr) {
return gr && gr instanceof GlideRecord && gr.isValidRecord();
},
type: 'CIActionEngineSNC'
};
Sys ID
f368bdee77211110a3f706e57b5a997d