Name
sn_agent.AgentNowHandler
Description
Sends a request to agents to perform a given check. the main API method is runCheckForCis
Script
var AgentNowHandler = Class.create();
AgentNowHandler.REQUEST_STATUS = {
PROCESSING: "processing",
DONE: "done",
FAILURE: "failure",
TIMEOUT: "timeout",
MID_FLOW: "mid_flow"
};
AgentNowHandler.REQUEST_NOT_FOUND_MSG = "no request with given id";
AgentNowHandler.TEST_RESULT_NOT_FOUND_MSG = "no test result with given id";
AgentNowHandler.TEST_RESULT_TIMEOUT_MSG = "request timeout";
AgentNowHandler.BACKGROUND_REQUEST_NOT_FOUND_MSG = "no background check request with given id";
AgentNowHandler.TEST_RESULT_STATUS = {
PENDING: 0,
IN_PROGRESS: 1,
COMPLETE: 2,
ERROR: 3,
CANCELED: 4
};
AgentNowHandler.prototype = {
initialize: function() {},
// 1. CIs – Glide record of any cmdb table (can be any application, host, or agent). Those are the elements that the check is working against
// 2. A check object containing the check ID and optionally params. Example:
// check = {
// "checkDefId": "c143ab237f705300f128134f8dfa9168",
// "params": {
// "warning": "80",
// "critical": "90",
// }
//
// 3. Priority: Priority of the request to be set on the ECC queue (0 - interactive, 1 - expedited , 2 - standard)
// 4. Timeout (s): The request defined timeout, if timeout pass mark the status as timeout
//
// the method will return the request ID
runCheckForCis: function(cis, check, priority, timeout) {
var clientsGenerator = new PolicyClientsGeneratorNG();
var mc = new MonitoringConfig();
var checkJson = this.buildCheckJson(check);
checkJson = this.injectCommandSuffixBasedOnCheckType(checkJson);
var command = checkJson['command'];
var clientsParams = clientsGenerator.getClientsByCisForCheckNoPolicy(cis, checkJson['id'], command);
return this.runCheck(cis, checkJson, this.getPolicyPerMid(clientsParams), priority, timeout);
},
injectCommandSuffixBasedOnCheckType: function(checkJson) {
// For Upgrade check types, we would like to add the version flag and is debug mode automatically
if (checkJson.check_type_id == "b69143c853a901100112ddeeff7b125b") {
var agentVer = AgentVersionFieldStyle.getAgentVersionFinal();
// add version
checkJson.command = checkJson.command + ' -v ' + agentVer;
// Add dev mode flag
if (gs.getProperty('sn_agent.dev_mode', 'false') == 'true')
checkJson.command = checkJson.command + ' -d true';
} else if (checkJson.check_type_id == "754f5f84532d01100112ddeeff7b1248" && checkJson.command == "read-file.rb") {
// For Upgrade log file check type, include the label in the command for the file_path check parameter
checkJson.command = "read-file.rb -f {{.labels.params_file_path}}";
}
return checkJson;
},
// Kills background checks that were started by running a request with the given request ID
stopBackgroundCheck: function(requestId) {
// reconstruct an array containing all ids of agents which were relevant for the request with the given id
var agentIds = [];
var gr = new GlideRecord("sn_agent_flags");
gr.addQuery("name", "STARTSWITH", ["back_req", requestId, ""].join("_"));
gr.query();
if (!gr.hasNext()) {
gs.error(gs.getMessage("background check with request id [ {0} ] was never created or already stopped", requestId));
return AgentNowHandler.BACKGROUND_REQUEST_NOT_FOUND_MSG;
}
while (gr.next()) {
var agentIdsOfFlag = JSON.parse(gr.getValue("hash"));
for (var i = 0; i < agentIdsOfFlag.length; i++)
agentIds.push(agentIdsOfFlag[i]);
gr.deleteRecord();
}
var agentsGr = new GlideRecord("sn_agent_cmdb_ci_agent");
agentsGr.addQuery("agent_id", agentIds);
agentsGr.query();
var killCheck = {
name: "kill_" + requestId,
kill_background: true,
background_requestId: requestId
};
this.runCheck(agentsGr, killCheck, this.getPolicyPerMid(new PolicyClientsGeneratorNG().getClientsByCisForCheckNoPolicy(agentsGr)), 0, 0);
return null;
},
// Given a request id returned by runCheckForCis, return a JSON containing the request status and error message if the status indicates a failure
getRequestStatus: function(requestId) {
var retJson = {
status: "",
err_msg: null
};
var gr = new GlideRecord("sn_agent_request");
if (!gr.get(requestId)) {
retJson.status = AgentNowHandler.REQUEST_STATUS.FAILURE;
retJson.err_msg = AgentNowHandler.REQUEST_NOT_FOUND_MSG;
} else {
retJson.status = gr.getValue("status");
if (retJson.status == AgentNowHandler.REQUEST_STATUS.FAILURE)
retJson.err_msg = gr.getValue("error_message");
}
return retJson;
},
// given a test result id for a test check execution, return a JSON containing the test status and output message
getTestResultStatus: function(testResultId) {
var retJson = {
status: AgentNowHandler.TEST_RESULT_STATUS.PENDING,
output: null
};
var testResultGr = new GlideRecord("sn_agent_test_result");
if (!testResultGr.get(testResultId)) {
retJson.status = AgentNowHandler.TEST_RESULT_STATUS.ERROR;
retJson.output = AgentNowHandler.TEST_RESULT_NOT_FOUND_MSG;
return retJson;
}
retJson.status = parseInt(testResultGr.getValue("status"));
if (retJson.status == AgentNowHandler.TEST_RESULT_STATUS.PENDING)
retJson.output = "test result is still pending";
else if (retJson.status == AgentNowHandler.TEST_RESULT_STATUS.IN_PROGRESS) {
retJson.output = "test result is still in progress";
} else if (retJson.status == AgentNowHandler.TEST_RESULT_STATUS.COMPLETE) {
retJson.output = testResultGr.getValue("output");
} else if (retJson.status == AgentNowHandler.TEST_RESULT_STATUS.CANCELED) {
retJson.output = testResultGr.getValue("output");
} else { // retJson.status == AgentNowHandler.TEST_RESULT_STATUS.ERROR
retJson.output = testResultGr.getValue("error_msg");
}
return retJson;
},
runCheckForAgentPerMid: function(check, policyPerMid, priority, timeout) {
var checkJson = this.buildCheckJson(check);
return this.runCheck("", checkJson, policyPerMid, priority, timeout);
},
getPolicyPerMid: function(clientsParams) {
var midToPolicy = {};
var agentsGr = new GlideRecord("sn_agent_ci_extended_info");
agentsGr.addQuery("agent_id", Object.keys(clientsParams));
agentsGr.addEncodedQuery("status!=2");
agentsGr.query();
while (agentsGr.next()) {
var midName = global.JSUtil.getBooleanValue(agentsGr, "use_cloud_services") ? ACCConstants.CLOUD_SERVICES_POD_PREFIX + agentsGr.mid : "" + agentsGr.mid.name;
var agent_id = agentsGr.agent_id;
var policyPerMid = midToPolicy[midName];
if (!policyPerMid) {
policyPerMid = {};
policyPerMid["auto_binding"] = true;
policyPerMid["clients_cis"] = {};
midToPolicy[midName] = policyPerMid;
}
policyPerMid["clients_cis"][agent_id] = clientsParams[agent_id];
}
return midToPolicy;
},
runCheck: function(cis, checkJson, midToPolicy, priority, timeout) {
var agentsFromAllMids = [];
for (var mid in midToPolicy) {
var agentsForSpecificMid = Object.keys(midToPolicy[mid]["clients_cis"]);
for (var i = 0; i < agentsForSpecificMid.length; i++)
agentsFromAllMids.push(agentsForSpecificMid[i]);
}
var numberOfActualAgents = agentsFromAllMids.length;
if (priority == null)
priority = '2'; //if no priority was provided - use Standard
//don't rely on the timeout in the check definition, use the one from api
if (timeout)
checkJson["timeout"] = "" + timeout;
else
timeout = checkJson["timeout"]; //if no timeout, grab it from the check def
checkJson["priority"] = priority;
var requestId = this.createAgentRequest(cis, checkJson, numberOfActualAgents, priority, timeout);
var background = checkJson["params_background"];
if (numberOfActualAgents > 0 && !gs.nil(background) && background)
this.createBackgroundRequestFlags(requestId, agentsFromAllMids);
checkJson["requestId"] = requestId;
//only in case type is not test check and not check discover and not null (e.g. when killing background check the request will not have a check type id)
if (!gs.nil(checkJson["check_type_id"]) && checkJson["check_type_id"] != "a32f261967133300b7b72dbd2685eff9" && checkJson["check_type_id"] != "4048774567633300b7b72dbd2685efa1") {
//when sending multiple requests with same check def and ci, the agent will refuse to run a check if it already
//running (identified by <check def id>_<ci id>). To avoid that situation, we will prefix the check def id with
//the request id, thus each request will be identified (<request_id>_<check_def_id>_<ci_id>) uniquely.
//for discovery we don't want to allow executing more than one request at a time
//in test check we relay on the "id" to be the check id, otherwise ci params will not be passed
checkJson["id"] = requestId + '_' + checkJson["id"];
}
var checksWrapper = [];
checksWrapper.push(checkJson);
for (mid in midToPolicy) {
var policy = midToPolicy[mid];
policy["checks"] = checksWrapper;
var payload;
if (mid.startsWith(ACCConstants.CLOUD_SERVICES_POD_PREFIX)) {
// cloud services case, convert V1 check request policy to a V2 configuration object then sign it to generate the payload
payload = (new ConfigPublishPayload()).convertOnDemandPolicyToSignedPayload(policy);
} else
payload = (new MonitoringSync()).getPayload(JSON.stringify(policy));
new MonitoringConfig().sendProbe('on_demand_request', 'on_demand_request', "mid.server." + mid, payload, priority, requestId);
}
return requestId;
},
buildCheckJson: function(check) {
var gr = new GlideRecord("sn_agent_check_def");
if (!gr.get(check.checkDefId))
return {};
var accUtils = new ACCConfigUtils();
var checkJson = accUtils.getCheckJson(gr);
if (check.check_type_id) // if we got a check type - use it
checkJson["check_type_id"] = check.check_type_id;
else {
checkJson["check_type_id"] = gr.getValue("check_script_type");
if (gr.check_script_type) {
var midScriptRef = gr.check_script_type.mid_script;
if (midScriptRef)
checkJson["mid_script"] = midScriptRef.name + "";
checkJson["instance_script"] = gr.check_script_type.enable_instance_script + "";
}
}
if (check.params) {
if (!checkJson["params"])
checkJson["params"] = {};
for (var key in check.params) {
checkJson["params"][key] = check.params[key];
}
}
return checkJson;
},
createAgentRequest: function(cis, check, numberOfAgents, priority, timeout) {
var gr = new GlideRecord("sn_agent_request");
gr.setValue("check", JSON.stringify(check));
gr.setValue("check_def", check.id);
gr.setValue("timeout", timeout + "");
gr.setValue("priority", priority + "");
gr.setValue("num_of_requested_checks", numberOfAgents);
if (cis) {
gr.setValue("table", cis.getTableName());
gr.setValue("encoded_query", cis.getEncodedQuery());
var cisCount = cis.getRowCount();
if (numberOfAgents == 0) {
gr.setValue("status", "failure");
gr.setValue("error_message", "no agents found for relevant CIs");
} else {
if (numberOfAgents < cisCount) {
gr.setValue("error_message", "cis count is: " + cisCount + ", but number of found agents is: " + numberOfAgents);
}
if (check.instance_script == "false" && check.mid_script) {
gr.setValue("status", "mid_flow"); //mid flow only without instance script - the request record will not be updated anymore
} else {
gr.setValue("status", "processing");
}
}
}
return gr.insert();
},
processEccRecord: function(current) {
var xmlDoc = new XMLDocument2();
var payload = this.getEccPayload(current);
xmlDoc.parseXML(payload);
var output = xmlDoc.getFirstNode("//results/result/output");
// Check for errors
var results = xmlDoc.getFirstNode("//results");
// clear variable values
payload = 0;
xmlDoc = 0;
if (results.hasAttribute("error")) {
var errMsg = "Found error on main results node - cannot process the payload";
if (!output)
throw errMsg;
else
gs.error("AgentNowHandler: " + errMsg + ". Error found on ECC queue=" + current.sys_id + ". Error=" + results.getAttribute("error"));
}
// clear variable holdings
results = 0;
// track the agent ids
var agentIds = [];
var isAttachment = current.payload == "<see_attachment/>";
if (output) {
var priorityToCheckTypeToResults = {};
var requestIdToNumberOfChecks = {};
//in case we are grabbing log, we don't have check results and the name will be file name
if (current.name == "on_demand_request") {
var checkResults = JSON.parse(output.getTextContent());
output = 0;
for (var index = 0; index < checkResults.length; index++) {
var checkResult = checkResults[index];
if (isAttachment)
// track the agent ids that we see while processing so we can add the agent ids to the input payload
agentIds.push("\"" + checkResult["agent_id"] + "\"");
// if agent is connecting without MID and the registration has been invalidated ignore incoming payload
if (checkResult["use_cloud_services"] && this.isAgentValidated(checkResult["agent_id"]))
continue;
var check = checkResult["check"];
if (!this.isBackgroundFlow(check)) {
//the default is the non interactive priority
var priority = 2;
//things coming from policy, don't have priority
if (check["priority"])
priority = check["priority"];
var typeId = check["check_type_id"];
var checkTypeToResults = priorityToCheckTypeToResults[priority];
if (!checkTypeToResults) {
checkTypeToResults = {};
priorityToCheckTypeToResults[priority] = checkTypeToResults;
}
var checkTypeResults = checkTypeToResults[typeId];
if (!checkTypeResults) {
checkTypeResults = [];
checkTypeToResults[typeId] = checkTypeResults;
}
checkTypeResults.push(checkResult);
}
var requestId = check["requestId"];
if (requestId) {
var numberOfChecks = requestIdToNumberOfChecks[requestId];
if (!numberOfChecks) {
numberOfChecks = 0;
}
requestIdToNumberOfChecks[requestId] = numberOfChecks + 1;
}
}
// clear variable
checkResults = 0;
var scriptIdToTypeId = {};
//iterate over the priorities
for (priority = 0; priority < 3; priority++) {
checkTypeToResults = priorityToCheckTypeToResults[priority];
if (checkTypeToResults) {
var checkTypeGr = new GlideRecord("sn_agent_check_type");
checkTypeGr.addQuery("sys_id", Object.keys(checkTypeToResults));
checkTypeGr.query();
while (checkTypeGr.next()) {
if (checkTypeGr.instance_script) {
var evaluator = new GlideScopedEvaluator();
evaluator.putVariable("checkResults", checkTypeToResults[checkTypeGr.getValue("sys_id")]);
//in case there is an exception inside the script its caught in glide level and written to logs...
evaluator.evaluateScript(checkTypeGr, 'instance_script');
}
}
}
}
this.updateProcessedChecks(current.sys_id + "", requestIdToNumberOfChecks);
} else {
//just need the key of agent correlator to switch the state of the output record to "done"
requestIdToNumberOfChecks[current.agent_correlator] = "";
}
var time = new GlideDateTime();
var hoursAgo = gs.getProperty("sn_agent.time_ago_in_seconds_to_query_ecc_queue", 43200); //12 hours in seconds by default
time.addSeconds(-1 * hoursAgo);
//set the ouptut ecc queue records in processed state
var outputRequestRecords = new GlideRecord("ecc_queue");
outputRequestRecords.addQuery("agent_correlator", Object.keys(requestIdToNumberOfChecks));
//update only the record of current mid
outputRequestRecords.addQuery("agent", current.agent);
outputRequestRecords.addQuery("state", "processing");
outputRequestRecords.addQuery("sys_created_on", ">", time); //improve the query performance by querying only the current shard table
outputRequestRecords.setValue("state", "processed");
outputRequestRecords.updateMultiple();
}
current.processed = new GlideDateTime();
current.state = 'processed';
if (isAttachment && agentIds.length > 0)
// DEF0253876: add the agent ids to the input payload so that this ecc queue record
// gets associated with the agent ids in the "Recent ECC queues" UI action
current.payload = current.payload + "\nAgent IDs: " + agentIds.join(',');
current.update();
},
markAgentsForCollectionFailedForDiscoveryTypeCheck: function(eccQueueSysId) {
return this.markAgentsHostDataForDiscoTypeChecks(eccQueueSysId, '2'); // 2=Collection Failed
},
markAgentsHostDataForDiscoTypeChecks: function(eccQueueSysId, hostDataStatus) {
if (!eccQueueSysId) {
gs.error("AgentNowHandler: Did not get an ecc queue sys id");
return;
}
var eccGr = new GlideRecord('ecc_queue');
if (!eccGr.get('sys_id', eccQueueSysId)) {
gs.error("AgentNowHandler: Cannot locate ecc queue with sys id = " + eccQueueSysId);
return;
}
var payload = eccGr.getValue('payload');
// First validate this is a discovery type check
var checkTypeRegEx = /\"check_type_id\"\s*:\s*"(.*?)"/g;
var matchCheck = checkTypeRegEx.exec(payload);
if (!matchCheck || !matchCheck[1]) {
gs.warn("AgentNowHandler: Could not locate check type, return");
return;
}
var checkTypeId = matchCheck[1];
if (!AgentDiscoverySharedUtils.isDiscoveryCheckType(checkTypeId)) {
gs.debug("AgentNowHandler: This is NOT a discovery check type, return");
return;
}
if (hostDataStatus == '')
gs.warn("AgentNowHandler: We need to retry to Collect host data");
var agentIds = [];
/* This regex will catch the client_cis as a JSON string representation
Input: <output>{"auto_binding":true,"clients_cis":{"d8c726724c3bbb91":{"a9f0a61d539a85100112ddeeff7b12fb":...}</output>
Catch groups: {"auto_binding":true,"clients_cis":{"d8c726724c3bbb91":{"a9f0a61d539a85100112ddeeff7b12fb":...}
*/
var clientsCisRegEx = /\{(.*)\}/g;
var match = clientsCisRegEx.exec(payload);
// need to get the clients_cis
if (!match || !match[1]) {
gs.error("AgentNowHandler: Could not catch clients_cis from payload: " + payload);
return;
}
// match[1] now hold clients_cis as JSON string representation
var clientCisAsStr = "{" + match[1] + "}"; // Add {} to make the root object
var clientCisObj = JSON.parse(clientCisAsStr);
for (var key in clientCisObj.clients_cis) {
agentIds.push(key);
}
if (!agentIds || agentIds.length < 1) {
gs.warn("AgentNowHandler: no agents to retry, we should had at least 1");
return;
}
AgentDiscoverySharedUtils.setAgentsHostDataStatus(agentIds, hostDataStatus);
},
updateProcessedChecks: function(sys_id, requestIdToNumberOfChecks) {
var agentRequestGr;
for (requestId in requestIdToNumberOfChecks) {
agentRequestGr = new GlideRecord("sn_agent_request");
agentRequestGr.addQuery("sys_id", requestId);
agentRequestGr.query();
agentRequestGr.next();
var numberOfRequested = agentRequestGr.getValue("num_of_requested_checks");
if (numberOfRequested == requestIdToNumberOfChecks[requestId]) {
//in case num of requested is equal to the number of checks on the ecc queue record - can handle directly
agentRequestGr.setValue("num_of_processed_checks", parseInt(requestIdToNumberOfChecks[requestId]));
agentRequestGr.setValue("status", "done");
agentRequestGr.update();
} else {
this.updateRequestChecksTable(sys_id, requestId, parseInt(requestIdToNumberOfChecks[requestId]));
}
}
},
updateRequestChecksTable: function(eccId, requestId, numberOfProcessedChecks) {
var gr = new GlideRecord("sn_agent_request_checks");
gr.setValue("ecc_queue", eccId);
gr.setValue("request", requestId);
gr.setValue("num_of_processed_checks", numberOfProcessedChecks);
gr.insert();
},
handleRequestChecksTable: function() {
var processedRecords = [];
var requestIdToNumberOfChecks = {};
var gr = new GlideRecord("sn_agent_request_checks");
gr.addQuery("status", "pending");
gr.query();
while (gr.next()) {
var request = gr.getValue("request");
var numberOfChecks = requestIdToNumberOfChecks[request];
if (!numberOfChecks) {
numberOfChecks = 0;
}
requestIdToNumberOfChecks[request] = numberOfChecks + parseInt(gr.getValue("num_of_processed_checks"));
processedRecords.push(gr.getUniqueValue());
}
for (requestId in requestIdToNumberOfChecks) {
agentRequestGr = new GlideRecord("sn_agent_request");
agentRequestGr.addQuery("sys_id", requestId);
agentRequestGr.query();
agentRequestGr.next();
var numberOfRequested = agentRequestGr.getValue("num_of_requested_checks");
var numOfProcessed = parseInt(agentRequestGr.getValue("num_of_processed_checks")) || 0;
numOfProcessed += parseInt(requestIdToNumberOfChecks[requestId]);
agentRequestGr.setValue("num_of_processed_checks", numOfProcessed);
if (numberOfRequested == numOfProcessed)
agentRequestGr.setValue("status", "done");
agentRequestGr.update();
}
//update processedRecords status to done in bulk
gr = new GlideRecord('sn_agent_request_checks');
gr.addQuery("sys_id", "IN", processedRecords);
gr.setValue("status", "done");
gr.updateMultiple();
//go over all records that are still in 'processing' status and haven't been updated
//in the last 2 minutes + their timeout value, and set their status to timeout
gr = new GlideRecord("sn_agent_request");
gr.addQuery("status", "processing");
gr.query();
var gdt1 = new GlideDateTime();
var gdt2 = new GlideDateTime();
while (gr.next()) {
//safely call parseInt becuase "timeout" is guarenteed to be integer
gdt1.subtract(2 * 60 * 1000 + parseInt(gr.getValue("timeout")) * 1000);
gdt2.setValue(gr.getValue("sys_updated_on"));
if (gdt2.compareTo(gdt1) < 0) {
gr.setValue("status", "timeout");
gr.update();
this.markTestResultsInTimeout(gr.getUniqueValue());
}
gdt1 = new GlideDateTime();
}
},
markTestResultsInTimeout: function(requestId) {
var testResultGr = new GlideRecord("sn_agent_test_result");
testResultGr.addQuery("agent_request", requestId);
testResultGr.addQuery("status", "IN", "0,1");
testResultGr.setValue("status", "3");
testResultGr.setValue("error_msg", AgentNowHandler.TEST_RESULT_TIMEOUT_MSG);
testResultGr.updateMultiple();
},
getEccPayload: function(ecc) {
if (ecc.payload != "<see_attachment/>") {
return ecc.payload;
}
var attachmentGr = new GlideRecord("sys_attachment");
attachmentGr.addQuery("table_sys_id", ecc.sys_id);
attachmentGr.addQuery("table_name", "ecc_queue");
attachmentGr.query();
attachmentGr.next();
var attachmentHandler = new GlideSysAttachment();
return attachmentHandler.getContent(attachmentGr);
},
//
// Check if the payload is an attachment, and if so, that it does not exceed the max payload size property value.
//
canProcessPayload: function(ecc) {
if (ecc.payload != "<see_attachment/>") {
return true;
}
var aggregateGr = new GlideAggregate("sys_attachment");
aggregateGr.addAggregate("COUNT", "table_sys_id");
aggregateGr.addQuery("table_sys_id", ecc.sys_id);
aggregateGr.addQuery("table_name", "ecc_queue");
aggregateGr.addQuery("size_bytes", "<=", gs.getProperty("sn_agent.ecc_queue.max_payload_size", 5000000));
aggregateGr.query();
aggregateGr.next();
return aggregateGr.getAggregate("COUNT", "table_sys_id") > 0;
},
// Decide if the given CI class is an agent (sn_agent_cmdb_ci_agent), a host (extends cmdb_ci_hardware), or an application
classifyClass: function(tableName) {
//gs.debug('classify ' + tableName);
if (tableName == 'cmdb' || tableName == 'cmdb_ci')
return 'host';
if (tableName == "sn_agent_cmdb_ci_agent")
return 'agent';
var baseTables = new GlideTableHierarchy(tableName).getTables();
for (var i = 0; i < baseTables.length; i++) {
var currTable = baseTables[i];
if (currTable == "cmdb_ci_hardware")
return 'host';
if (currTable == "cmdb_ci_appl")
return 'app';
}
return 'unknown';
},
//
// check if CI as associated live agent. The CI can be the CI of the agent itself (sn_agent_cmdb_ci_agent), a host associated
// with an agent, or application running on host associated with an agent
//
hasAgent: function(ci) {
// Validity check
if (!ci || ci == '')
return false;
// First we need to find the class of the CI
var cmdbCi = new GlideRecord('cmdb_ci');
if (!cmdbCi.get(ci)) {
return false;
}
var ciClass = cmdbCi.getValue('sys_class_name') + '';
var agentCiType = this.classifyClass(ciClass);
//gs.debug('agentCiType = ' + agentCiType);
// Handle the case the CI is the agent itself
var agentGr;
if (agentCiType == 'agent') {
agentGr = new GlideRecord('sn_agent_cmdb_ci_agent');
agentGr.addQuery('sys_id', ci);
agentGr.addQuery('agent_extended_info.status', '0');
agentGr.query();
return (agentGr.next());
}
// Handle the case the CI is host
if (agentCiType == 'host') {
agentGr = new GlideRecord('sn_agent_cmdb_ci_agent');
agentGr.addQuery('agent_extended_info.cmdb_ci', ci);
agentGr.addQuery('agent_extended_info.status', '0');
agentGr.query();
return (agentGr.next());
}
// In case the CI is an application
if (agentCiType == 'app') {
// Find the host
var relGr = new GlideRecord('cmdb_rel_ci');
relGr.addQuery('parent', ci);
relGr.addQuery('type', '60bc4e22c0a8010e01f074cbe6bd73c3'); // Runs-on relation type
relGr.query();
if (relGr.next())
return this.hasAgent(relGr.child);
return false;
}
return false;
},
createBackgroundRequestFlags: function(requestId, agentIds) {
// max length of the hash field on sn_agent_flags is 4,000. length of each agent id is 16.
// to be on the safe side lets limit the size of the array to include 200 agent ids.
// 200 * 16 = 3,200. 3,200 + overhead of formatting into json array < 4,000.
var maxAgentIdsPerFlag = 200;
var flagIndex = 0;
while (agentIds.length > 0) {
var numAgentIdsLeft = agentIds.length;
var flagAgentIdsArr = [];
for (var i = 0; i < numAgentIdsLeft && i < maxAgentIdsPerFlag; i++)
flagAgentIdsArr.push(agentIds.shift());
var gr = new GlideRecord("sn_agent_flags");
gr.initialize();
gr.setValue("name", ["back_req", requestId, flagIndex].join("_"));
gr.setValue("hash", JSON.stringify(flagAgentIdsArr));
gr.insert();
flagIndex++;
}
},
// determine if the check response is part of a background flow check - start a background check or kill one
isBackgroundFlow: function(check) {
var background = check["background_response"];
var killBackground = check["kill_background"];
return (!gs.nil(background) && background == "true") || (!gs.nil(killBackground) && killBackground == "true");
},
// Determine if the agent connecting via Cloud Services is validated or not
isAgentValidated: function(agentId) {
var regGr = new GlideRecord("sn_agent_agent_registration");
regGr.addQuery("agent_id", agentId);
regGr.query();
regGr.next();
return regGr.getValue("is_validated") == '0'; // '0' representation of false
},
type: 'AgentNowHandler'
};
Sys ID
158279505372b30034b8ddeeff7b1270