Name
sn_agent.MonitoringConfig
Description
Monitoring helper functions
Script
var MonitoringConfig = Class.create();
MonitoringConfig.prototype = {
CI_PARAM_KEY: '{{.labels.params_ci_',
CI_PARAMS_TO_CHECK_PLACE_HOLDER: 'CI_PARAMS_TO_CHECK_PLACE_HOLDER',
ENTRYPOINT_METRIC_RESOURCE_PARAM: "entrypoint_resource",
ENTRYPOINT_METRIC_RESOURCE_USE_LOCATION_PROPERTY: "sn_itmon.entrypoint.monitoring.use_location",
ENTRYPOINT_METRIC_RESOURCE_USE_HOSTNAME_PROPERTY: "sn_itmon.entrypoint.monitoring.use_hostname",
IS_PROXY_CHECK: "is_proxy_check",
PROXY_CHECK_CI_PARAM: ['ep_service_name', 'target_ip'],
FORCE_SYNC_TIMESTAMP: "2000-01-01 00:00:00",
currentPolicy: {},
initialize: function() {
this.agenstIdList = [];
this.chunk_size = 100;
this.forceMidConfigSync = false;
this.domainInfo = new DomainInfo();
this.policyStateUtil = new PolicyStateUtil();
this.policyUpdateDomainSeparation = new PolicyUpdateDomainSeparation();
},
/*
* split clients into those that should be newClients, full update, or update timestamp and status only.
*/
classifyClientsAndUpdate: function(clients, mid, newClients, updateTimestamp, updateUpSince) {
var clientsMap = {};
var reCalcPolicyClients = false;
// Build map of client names in the payload we got
var i = 0;
for (i = 0; i < clients.length; i++) {
clientsMap[clients[i].agent_id] = clients[i];
clients[i].name = "Agent_" + clients[i].name;
this.agenstIdList.push(clients[i].agent_id);
}
var chunked = MonitoringUtils.chunkArray(this.agenstIdList, this.chunk_size);
gs.debug('classifyClientsAndUpdate - number of chunks: ' + chunked.length);
var existingAgents = {};
var agentsInNewUpState = [];
var numOfIpUpdates = 0;
var timestamp = new GlideDateTime().getNumericValue();
for (var chunk_index = 0; chunk_index < chunked.length; chunk_index++) {
var chunkOfAgentIDs = chunked[chunk_index];
var gr = new GlideRecord('sn_agent_ci_extended_info');
gr.addQuery('agent_id', 'IN', chunkOfAgentIDs);
gr.query();
while (gr.next()) {
//in case mid was changed, resend all configuration to the new mid
if (gr.mid != mid) {
this.forceMidConfigSync = true;
}
//in case agent changed status from down to up, recalc policyClients, to include it in the relevant polices
if (gr.status == 2) {
reCalcPolicyClients = true;
}
var agentId = '' + gr.agent_id;
var agentInfoToUpdate = {};
var agentKeepAlive = clientsMap[gr.agent_id];
if (clientsMap[agentId]) {
/*Valdidation for backward compitability*/
if (agentKeepAlive.hasOwnProperty('version')) {
var currentAgentVersion = agentKeepAlive.version;
if (gr.agent_version != currentAgentVersion)
agentInfoToUpdate['agent_version'] = currentAgentVersion;
}
if (gr.ip_address != agentKeepAlive.address)
agentInfoToUpdate['ip_address'] = this.getPreferredIPAddress(agentKeepAlive);
if (gr.name != agentKeepAlive.name)
agentInfoToUpdate['name'] = agentKeepAlive.name;
// Check for param in payload to handle legacy MIDs
if (agentKeepAlive.hasOwnProperty('use_cloud_services')) {
var currentUseCloudServices = agentKeepAlive.use_cloud_services;
if (global.JSUtil.getBooleanValue(gr, "use_cloud_services") != currentUseCloudServices)
agentInfoToUpdate['use_cloud_services'] = currentUseCloudServices;
} else {
// If the agent is already marked as cloud services, but payload doesn't send the field
// it means it has now connected to an older MID, and we should mark it as non-cloud-services.
if (global.JSUtil.getBooleanValue(gr, "use_cloud_services") != false)
agentInfoToUpdate['use_cloud_services'] = false;
}
// update name,ip,version and mid
if (Object.keys(agentInfoToUpdate).length > 0)
this.updateAgentInfo(gr, agentInfoToUpdate);
var infoSysId = '' + gr.sys_id;
if (gr.status != '0') {
updateUpSince.push(infoSysId); // update upSince for agents that came alive
agentsInNewUpState.push(agentId); // agents that were not up and now are back up.
// handle a case where status changes from upgrad->up
if (gr.status == AgentKeepAlive.AGENT_UPGRADING) {
var acc = new AgentUpgradeUtil();
acc.agentUpgradeToUp(agentId, gr.is_windows);
}
} else {
updateTimestamp.push(infoSysId); //standart keepAlive
}
existingAgents[agentId] = true;
} else
gs.debug('Agent ' + agentId + ' not found in map');
}
}
// find agents which should be newClients
for (i = 0; i < clients.length; i++) {
var insert_client = clients[i];
if (!existingAgents[insert_client.agent_id]) {
agentsInNewUpState.push(insert_client.agent_id);
newClients.push(insert_client);
}
}
// If there are new agents or agents that came back online, generate Event Up
if (agentsInNewUpState.length > 0) {
AgentKeepAlive.chunkAndSendEvents(agentsInNewUpState, 'up');
}
if (reCalcPolicyClients) {
(new PolicyClientsGeneratorNG()).getAndUpdateReCalcFilterFlag(true);
}
},
handleDeltaUpdate: function(newConnections, expiredConnections, midSysId, useCloudServices) {
if (!midSysId)
gs.error('Unknown MID Server to update agents');
// Baseline offset of 100 seconds. By default, keepalives comes every 60 seconds, add 40 second buffer for latency.
var timeOffsetLength = 100;
// Handle getting proper offset for Cloud Services agents
if (useCloudServices) {
// Time offset of the last KeepAlive payload; this should be aligned
// with the "KafkaConsumerJob" sys_trigger repeat interval.
var CLOUD_SERVICES_KEEPALIVE_BUFFER = parseInt(gs.getProperty('sn_itom_cloud_serv.cloud_services_keepalive_buffer', 30), 10);
// Cloud services always sends keepalives every 60 seconds. Add an extra 15 seconds of buffer for Kafka latency.
timeOffsetLength = 75 + CLOUD_SERVICES_KEEPALIVE_BUFFER;
}
// Handle proper configured offset for MID server case.
else {
// Time offset of the last KeepAlive payload; should be aligned with MID Property "sn_agent.sync.interval.sec"
var BASE_KEEPALIVE_OFFSET = parseInt(gs.getProperty('sn_agent.agent_keep_alive.offset', 60), 10); // in seconds
// Add some default buffer in the case of latency.
timeOffsetLength = BASE_KEEPALIVE_OFFSET + 30;
}
var timeOffset = new GlideDateTime();
timeOffset.addSeconds(-(timeOffsetLength)); // with some buffer
// update last_refreshed for all currently Up agents that are not in the delta payload
var gr = new GlideRecord('sn_agent_ci_extended_info');
if (expiredConnections)
gr.addQuery('agent_id', 'NOT IN', expiredConnections);
gr.addQuery('last_refreshed', '>', timeOffset.getValue()); // handle case where agent disconnected in the full payload
gr.addQuery('status', AgentKeepAlive.AGENT_UP);
gr.addQuery('mid', midSysId);
gr.setValue('last_refreshed', new GlideDateTime());
gr.updateMultiple();
// handle any new connections, just as with the full payload
if (newConnections)
this.updateClients(newConnections, midSysId);
},
getPreferredIPAddress: function(objMap) {
var preferredVersion = AgentDiscoverySharedUtils.getPreferredIPVersion();
// get IPv6 if it is preferred and exists
if (preferredVersion == 6 && objMap.addressV6)
return objMap.addressV6;
// get IPv4
if (objMap.address)
return objMap.address;
// if only IPv6 is available, get IPv6
if (objMap.addressV6)
return objMap.addressV6;
return null;
},
//agent name or ip is found on both sn_agent_cmdb_ci_agent and sn_agent_ci_extended_info
updateAgentInfo: function(extendedInfoRecord, agentInfoToUpdate) {
var agentRecord = new GlideRecord("sn_agent_cmdb_ci_agent");
agentRecord.addQuery("agent_extended_info", extendedInfoRecord.sys_id);
agentRecord.query();
agentRecord.next();
Object.keys(agentInfoToUpdate).forEach(
function(name) {
if (name == '$objectName$' || name == '$objectNameNew$')
return;
var val = agentInfoToUpdate[name];
// Skip if we got null values
if (val == null || val == undefined || val == 'undefined')
return;
if (name == "ip_address") {
agentRecord.setValue("ip_address", val);
extendedInfoRecord.setValue("ip_address", val);
} else if (name == "name") {
agentRecord.setValue("name", val);
extendedInfoRecord.setValue("name", val);
extendedInfoRecord.setValue("cmdb_ci", "");
} else {
extendedInfoRecord.setValue(name, val);
}
});
extendedInfoRecord.update();
agentRecord.update();
},
updateClients: function(clients, mid) {
//var startUpdateClients = (new Date()).getTime();
var number_of_clients = 0;
if (clients) {
var newClients = [];
var updateTimestamp = [];
var updateUpSince = [];
numOfIpUpdates = this.classifyClientsAndUpdate(clients, mid, newClients, updateTimestamp, updateUpSince);
this.updateClientKeepAlive(updateTimestamp, updateUpSince, mid);
//var endClassifications = (new Date()).getTime();
//var endUpdate = (new Date()).getTime();
//gs.debug("!!PERF!! Keep Alive update" + (endUpdate - endClassifications));
this.insertNewClients(newClients, mid);
//var endUpdateClients = (new Date()).getTime();
//gs.debug("!!PERF!! Keep Alive insert" + (endUpdateClients - endUpdate));
//gs.debug("!!PERF!! Keep Alive total" + (endUpdateClients - startUpdateClients));
}
},
updateClientKeepAlive: function(updateTimestamp, updateUpSince, mid) {
if (updateTimestamp.length == 0 && updateUpSince.length == 0)
return;
this.forceUpdateMidIfCacheExpired(updateUpSince, mid);
var now = new GlideDateTime();
gs.debug('updateTimestamp size to update: ' + updateTimestamp.length);
var chunked = MonitoringUtils.chunkArray(updateTimestamp, this.chunk_size);
gs.debug('number of chunks to updateTimestamp: ' + chunked.length);
for (var i = 0; i < chunked.length; i++) {
var chunk = chunked[i];
var agentStatusGr = new GlideRecord('sn_agent_ci_extended_info');
agentStatusGr.addQuery('sys_id', 'IN', chunk);
agentStatusGr.setValue('mid', mid);
agentStatusGr.setValue('sys_updated_on', now);
agentStatusGr.setValue('last_refreshed', now);
agentStatusGr.setWorkflow(false); //disable business rules so updateMultiple will work in bulk
agentStatusGr.updateMultiple();
}
//update Status and up Since
gs.debug('updateUpSince size to update: ' + updateUpSince.length);
chunked = MonitoringUtils.chunkArray(updateUpSince, this.chunk_size);
gs.debug('number of chunks to updateUpSince: ' + chunked.length);
for (i = 0; i < chunked.length; i++) {
chunk = chunked[i];
agentStatusGr = new GlideRecord('sn_agent_ci_extended_info');
agentStatusGr.addQuery('sys_id', 'IN', chunk);
agentStatusGr.setValue('mid', mid);
agentStatusGr.setValue('status', '0');
agentStatusGr.setValue('up_since', now);
agentStatusGr.setValue('sys_updated_on', now);
agentStatusGr.setValue('last_refreshed', now);
agentStatusGr.setWorkflow(false); //disable business rules so updateMultiple will work in bulk
agentStatusGr.updateMultiple();
}
},
forceUpdateMidIfCacheExpired: function(upAgents, midSysId) {
var midInfoGr = new GlideRecord('sn_agent_mid_info');
if (!midInfoGr.get('mid', midSysId)) {
return;
}
var midAgentCacheExperationSec = 259200; // Default for 3 days.
// If this is a MID and not a POD - try and take the MID property
if (!global.JSUtil.getBooleanValue(midInfoGr, "use_cloud_services")) {
var gr = new GlideRecord('ecc_agent_property');
gr.addQuery('name', 'sn_agent.mid.agent_expiration_sec');
gr.orderBy('ecc_agent');
gr.query();
while (gr.next()) {
var midFound = gr.getValue('ecc_agent') == midSysId;
if (!gr.getValue('ecc_agent') || midFound) {
midAgentCacheExperationSec = Number(gr.getValue('value'));
if (midFound)
break; // found the mid we wanted;
}
}
if (!midAgentCacheExperationSec || midAgentCacheExperationSec <= 0)
midAgentCacheExperationSec = 259200;
} else {
// If this is a cloud services POD, set expiration to three minutes
// We want to cycle non-connected agent info out of memory quickly
// because agents are unlikely to connect to the same pod again.
midAgentCacheExperationSec = 180;
}
midAgentCacheExperationSec = midAgentCacheExperationSec - 10; // compensate for network lag. 10 seconds standard diviation for 3 days is ok
var cacheExpireTime = new GlideDateTime();
cacheExpireTime.addSeconds(-1 * midAgentCacheExperationSec);
var agentsGr = new GlideRecord('sn_agent_ci_extended_info');
agentsGr.addQuery('sys_id', upAgents);
agentsGr.addQuery('last_refreshed', '<=', cacheExpireTime);
agentsGr.setLimit(1);
agentsGr.query();
if (!agentsGr.hasNext()) {
return;
}
// We have at least 1 agents that is now up but the MID cache expired and this agent does NOT have its configuration cached - force update the MID.
// Forcinf the MID to get the configuration in order to restore the agent's cache
midInfoGr.setValue('force_config_sync', '1');
midInfoGr.update();
},
insertNewClients: function(clients, mid) {
if (clients.length == 0)
return;
for (var i = 0; i < clients.length; i++) {
var currentClient = clients[i];
var now = new GlideDateTime();
var gr = new GlideRecord('sn_agent_ci_extended_info');
gr.setValue("status", "0");
gr.setValue("mid", mid);
gr.setValue("up_since", now);
gr.setValue("name", currentClient.name);
gr.setValue("agent_id", currentClient.agent_id);
if (currentClient.address && currentClient.address != 'undefined')
gr.setValue("ip_address", currentClient.address);
gr.setValue("is_windows", currentClient.isWindows);
if (currentClient.use_cloud_services) {
gr.setValue("use_cloud_services", true);
gr.setValue("agent_registration", this.getAgentRegistration(currentClient.agent_id));
}
// DEF0220355 prevent immediately uninstalled agent from being "up" forever
gr.setValue('last_refreshed', now);
var infoSysId = gr.insert();
gr = new GlideRecord('sn_agent_cmdb_ci_agent');
gr.setValue("name", currentClient.name);
gr.setValue("agent_id", currentClient.agent_id);
if (currentClient.address && currentClient.address != 'undefined')
gr.setValue("ip_address", currentClient.address);
gr.setValue("agent_extended_info", infoSysId);
gr.insert();
}
},
splitIn: function(ids, callback, splitSize) {
splitSize = splitSize ? splitSize : 500;
for (var i = 0; i * splitSize < ids.length; i++) {
callback(ids.slice(i * splitSize, (i + 1) * splitSize));
}
},
sanitizeCommand: function(current) {
var agentSanitizeCheckCommand = new sn_agent.AgentSanitizeCheckCommand();
return agentSanitizeCheckCommand.sanitize(current, false);
},
addStatusChangeThresholds: function(chgr, check) {
var checkTypeId = chgr.check_script_type;
if (!checkTypeId) {
//if we get here it means this is check instance, so dot walk to check definition
checkTypeId = chgr.check_def.check_script_type;
}
if (checkTypeId == "a3a00b53532a330034b8ddeeff7b123d") {
if (chgr.getValue("event_status_change_threshold"))
check["event_status_change_threshold"] = chgr.getValue("event_status_change_threshold");
else
check["event_status_change_threshold"] = 1;
if (chgr.getValue("event_status_repair_threshold"))
check["event_status_repair_threshold"] = chgr.getValue("event_status_repair_threshold");
else
check["event_status_repair_threshold"] = 1;
}
},
createCheckInstance: function(polGr, checkDefSysId, params) {
var gr = new GlideRecord('sn_agent_check_def');
if (gr.get(checkDefSysId)) {
//handle check
var check_instance = new GlideRecord('sn_agent_check');
check_instance.initialize();
check_instance.name = gr.name;
check_instance.command = gr.command;
check_instance.check_def = gr.sys_id;
check_instance.monitoring_policy = polGr.sys_id;
check_instance.is_interval = gr.is_interval;
check_instance.interval = gr.interval;
check_instance.is_cron = gr.is_cron;
check_instance.cron_expressions = gr.cron_expressions;
check_instance.active = gr.active;
check_instance.timeout = gr.timeout;
check_instance.pre_condition = gr.pre_condition;
check_instance.check_json = gr.check_json;
check_instance.label = gr.label;
check_instance.command_prefix = gr.command_prefix;
check_instance.auto_generate = gr.auto_generate;
check_instance.cred_failure_regex = gr.cred_failure_regex;
check_instance.background = gr.background;
check_instance.exec_mode = gr.exec_mode;
if (gr.getValue("check_script_type") == "a3a00b53532a330034b8ddeeff7b123d") {
if (gr.getValue("event_status_change_threshold"))
check_instance.event_status_change_threshold = gr.getValue("event_status_change_threshold");
else
check_instance.event_status_change_threshold = 1;
if (gr.getValue("event_status_repair_threshold"))
check_instance.event_status_repair_threshold = gr.getValue("event_status_repair_threshold");
else
check_instance.event_status_repair_threshold = 1;
}
var checkId = check_instance.insert();
// Policy params
var pol_params = {};
var ppGr = new GlideRecord('sn_agent_policy_param');
ppGr.addQuery('policy', polGr.sys_id);
ppGr.query();
while (ppGr.next()) {
pol_params['' + ppGr.name] = '' + ppGr.value;
}
//handle params
var param_def = new GlideRecord('sn_agent_check_param_def');
param_def.addQuery('check_def', checkDefSysId);
param_def.query();
var param_instance;
var isCheckInstanceActive = true;
while (param_def.next()) {
param_instance = new GlideRecord('sn_agent_check_param');
param_instance.initialize();
param_instance.label = param_def.label;
param_instance.name = param_def.name;
param_instance.value = param_def.default_value;
if (params && params["" + param_def.name] != undefined) {
param_instance.value = params["" + param_def.name];
delete params["" + param_def.name];
} else if (!gs.nil(pol_params["" + param_def.name])) {
param_instance.value = pol_params["" + param_def.name];
}
param_instance.mandatory = param_def.mandatory;
param_instance.order = param_def.order;
param_instance.validation_regex = param_def.validation_regex;
param_instance.active = param_def.active;
param_instance.check = checkId;
param_instance.flag = param_def.flag;
param_instance.value_required = param_def.value_required;
isCheckInstanceActive = (param_instance.mandatory && param_instance.value == '') ? false : true;
param_instance.insert();
}
if (params) {
for (var k in params) {
param_instance = new GlideRecord('sn_agent_check_param');
param_instance.initialize();
param_instance.name = k;
param_instance.value = params[k];
param_instance.check = checkId;
param_instance.insert();
}
}
// handle secure parameters
var sec_param_def = new GlideRecord('sn_agent_check_secure_param_def');
sec_param_def.addQuery('check_def', checkDefSysId);
sec_param_def.query();
var sp_instance = new GlideRecord('sn_agent_check_secure_param');
while (sec_param_def.next()) {
sp_instance.initialize();
sp_instance.label = sec_param_def.label;
sp_instance.description = sec_param_def.description;
sp_instance.name = sec_param_def.name;
sp_instance.order = sec_param_def.order;
sp_instance.active = sec_param_def.active;
sp_instance.check = checkId;
sp_instance.insert();
}
}
if (!isCheckInstanceActive) {
check_instance = new GlideRecord('sn_agent_check');
if (check_instance.get(checkId)) {
check_instance.setValue('active', false);
check_instance.update();
gs.addErrorMessage(gs.getMessage("The check {0}:{1} has mandatory parameters which are missing values. Therefore, the check instance is set as inactive.", [check_instance.name, checkId]));
}
}
},
sendProbe: function(command, id, mid, payload, priority, agentCorrelator) {
mid = mid ? mid : "mid.server.*";
if (!mid.startsWith("mid.server.")) {
gs.error("invalid 'mid' (mid server name) argument passed to sn_agent.MonitoringConfig.sendProbe. got {0} which isn't prefixed by 'mid.server.'.", mid);
return;
}
midName = mid.substring("mid.server.".length); // 'mid' variable should is in the form of "mid.server.MID_NAME". we need "MID_NAME".
// fetch mid(s) domain(s) and set the domain of the ecc queue record we'll create with the mid's domain so he will be able to query for it.
// If we are launching probe for all MIDs (.*) or specifically for Cloud Services Agents (acc-cnc)
var launchCloudServices = midName == "*" || midName.startsWith("acc-cnc");
var midGr = new GlideRecord("ecc_agent");
if (midName == "*") { // all mids
midsWithAccSysIds = [];
var accExtGr = new GlideRecord("sn_agent_ext_context");
accExtGr.addQuery("status", "Started");
accExtGr.query();
while (accExtGr.next())
midsWithAccSysIds.push(accExtGr.getValue("executing_on"));
midGr.addQuery("sys_id", "IN", midsWithAccSysIds.join(","));
} else { // specific mid
midGr.addQuery("name", midName);
}
midGr.addQuery("status", "Up");
midGr.addQuery("validated", "true");
midGr.query();
if (!midGr.hasNext() && !launchCloudServices) {
gs.error("invalid 'mid' (mid server name) argument passed to sn_agent.MonitoringConfig.sendProbe. got {0} which doesn't match any existing up and validated mid server running an ACC WebSocket Extension.", mid);
return;
}
while (midGr.next()) {
this.launchMIDProbe(midGr, command, id, payload, priority, agentCorrelator);
}
if (launchCloudServices)
this.launchCloudServicesProbe(midName, command, id, payload, priority, agentCorrelator);
},
launchMIDProbe: function(midGr, command, id, payload, priority, agentCorrelator) {
var gr = new GlideRecord('ecc_queue');
gr.initialize();
gr.setValue("sys_domain", midGr.getValue("sys_domain"));
gr.setValue("agent", "mid.server." + midGr.getValue("name"));
gr.setValue('skip_sensor', true);
gr.setValue('source', command);
gr.setValue('name', id);
if (payload)
gr.setValue('payload', payload);
gr.setValue('topic', 'MonitoringProbe');
gr.setValue('queue', 'output');
gr.setValue('state', 'ready');
if (!priority)
priority = '2'; //Standard
gr.setValue('priority', priority);
if (!agentCorrelator)
agentCorrelator = '';
gr.setValue('agent_correlator', agentCorrelator);
gr.insert();
},
launchCloudServicesProbe: function(podName, command, id, payload, priority, agentCorrelator) {
var gr = new GlideRecord('ecc_queue');
gr.initialize();
// TODO: Deal with domain separation somehow
gr.setValue("sys_domain", "global");
gr.setValue("agent", "mid.server.acc-cnc");
gr.setValue('skip_sensor', true);
gr.setValue('source', command);
gr.setValue('name', id);
if (payload) {
if (podName == "" || podName == "*")
gr.setValue('payload', "pod: all_pods, " + payload);
else
gr.setValue('payload', "pod: " + podName.substring(ACCConstants.CLOUD_SERVICES_POD_PREFIX.length) + ", " + payload);
}
gr.setValue('topic', 'MonitoringProbe');
gr.setValue('queue', 'output');
gr.setValue('state', 'ready');
if (!priority)
priority = '2'; //Standard
gr.setValue('priority', priority);
if (!agentCorrelator)
agentCorrelator = '';
gr.setValue('agent_correlator', agentCorrelator);
gr.insert();
},
updateMidUpdateTime: function(lut, mid, useCloudServices) {
var midInfoGR = new GlideRecord("sn_agent_mid_info");
midInfoGR.addQuery("mid", mid);
midInfoGR.query();
if (!midInfoGR.next()) {
midInfoGR.setValue("mid", mid);
if (useCloudServices) {
midInfoGR.setValue("use_cloud_services", useCloudServices)
}
}
midInfoGR.setValue("last_update_time", lut);
//only if true update value, otherwise it overiddes the value if it was set to true by other flow
if (this.forceMidConfigSync) {
midInfoGR.setValue("force_config_sync", this.forceMidConfigSync);
}
midInfoGR.update();
},
updateDuplicatedAgents: function(agentIds, isDuplicate) {
if (agentIds.length > 0) {
var gr = new GlideRecord('sn_agent_ci_extended_info');
gr.addQuery('agent_id', 'IN', agentIds.join(","));
gr.addQuery('is_duplicate', !isDuplicate);
gr.setValue('is_duplicate', isDuplicate);
if (isDuplicate == true)
gr.setValue('cmdb_ci', "");
gr.setWorkflow(false);
gr.updateMultiple();
}
},
sendConfigPublishProbe: function(policies, midName) {
//send configuration probe only in case actual delta was detected
if (!policies || policies.length < 1 || !midName)
return;
var timestamp = "" + new GlideDateTime();
var updates = {
timestamp: timestamp,
policies: policies
};
var payload = (new MonitoringSync()).getPayload(JSON.stringify(updates));
this.sendProbe('config_publish', 'config_publish', "mid.server." + midName, payload);
},
getOrphanPolicy: function(agentsWithNoPolicies) {
var orphanAgentsPolicy = {
name: "",
id: ACCConstants.IDLE_POLICY_NAME,
interval: "",
"auto_binding": "false",
clients_cis: {}
};
for (var agent in agentsWithNoPolicies) {
var agentId = agentsWithNoPolicies[agent];
orphanAgentsPolicy['clients_cis'][agentId] = {};
}
return orphanAgentsPolicy;
},
handleMidParamsOnChecks: function(policies, mid, midLastConfigSyncTime) {
var uniqueCheckTypesSysIds = {};
for (var policyIdx in policies) {
var policy = policies[policyIdx];
var checks = policy["checks"];
for (var checkIdx in checks) {
var check = checks[checkIdx];
if (check["check_type_id"]) {
uniqueCheckTypesSysIds[check["check_type_id"]] = true; // mark as exist
}
}
}
var checksTypeIds = Object.keys(uniqueCheckTypesSysIds);
if (checksTypeIds.length < 1)
return;
var midEnrichGr = new GlideRecord("sn_agent_mid_enrichment_for_check");
midEnrichGr.addQuery("check_type", "IN", checksTypeIds);
midEnrichGr.query();
var checkTypesToValues = {};
var evaluator = new GlideScopedEvaluator();
evaluator.putVariable('midId', mid); //pass current mid id
evaluator.putVariable('midLastConfigSyncTime', midLastConfigSyncTime); //pass mid's acc last config sync time
while (midEnrichGr.next()) {
var midInfoContainer = evaluator.evaluateScript(midEnrichGr, 'mid_enrich_script');
if (midInfoContainer) {
var valuesToAdd = checkTypesToValues[midEnrichGr.check_type];
if (!valuesToAdd) {
valuesToAdd = [];
checkTypesToValues[midEnrichGr.check_type] = valuesToAdd;
}
valuesToAdd.push(midInfoContainer);
}
}
for (var policyIdx in policies) {
var policy = policies[policyIdx];
var checks = policy["checks"];
for (var checkIdx in checks) {
var check = checks[checkIdx];
for (var checkType in checkTypesToValues) {
if (check["check_type_id"] == checkType) {
if (!check["params"]) {
check["params"] = {};
}
var midValuesLst = checkTypesToValues[checkType];
for (var valIdx in midValuesLst) {
var infoContainer = midValuesLst[valIdx];
check["params"][infoContainer.key] = infoContainer.value;
check["command"] = check["command"] + " " + infoContainer.flag + " {{.labels.params_" + infoContainer.key + "}}";
}
}
}
}
}
},
syncPoliciesToMid: function() {
var p = new PolicyClientsGeneratorNG(this.policyStateUtil);
// Make sure all Policies are up to date.
p.syncClients();
// Send probes to MID servers / updates to C&C PODs.
this.syncPolicies();
this.runInitialHostDataCollection();
},
syncPolicies: function() {
// ensure we are in global domain before getting the leaf domains
var currentDomainId = this.domainInfo.getCurrentDomain();
if (this.policyUpdateDomainSeparation.isDomainSeparationPluginActive && currentDomainId != 'global')
this.policyUpdateDomainSeparation.changeSessionDomain('global');
var leafDomainIds = this.policyUpdateDomainSeparation.getAgentLeafDomains();
try {
for (var i = 0; i < leafDomainIds.length; i++) {
var leafDomainId = leafDomainIds[i];
gs.debug("Running syncClients for domain " + leafDomainId);
currentDomainId = this.domainInfo.getCurrentDomain();
if (this.policyUpdateDomainSeparation.isDomainSeparationPluginActive && leafDomainId != currentDomainId)
this.policyUpdateDomainSeparation.changeSessionDomain(leafDomainId);
var midInfoGr = new GlideRecord('sn_agent_mid_info');
midInfoGr.query();
var upStatusMids = 0;
while (midInfoGr.next()) {
/*
MID sends its last_update_time alongside the agents' keepalive
If a MID has 0 agents up - then we will not get the last_update_time of the mid and we will keep
Sending the policies to the MID.
At the first agent up for a MID - we will send the full policies configuration.
*/
if (!this.atLeastOneUpAgent(midInfoGr.getValue('mid'))) {
gs.debug('MonitoringConfig syncPolicies: no agents up for mid info record ' + midInfoGr.getUniqueValue() + ', skipping this mid info record');
continue;
}
var useCloudServices = global.JSUtil.getBooleanValue(midInfoGr, "use_cloud_services");
// handle MID case
if (!useCloudServices && midInfoGr.mid.status != 'Up') {
gs.debug('MonitoringConfig syncPolicies: mid info ' + midInfoGr.getUniqueValue() + ' is not using cloud services and not up, skipping this mid info record');
continue;
}
upStatusMids++;
var handlerLastUpdate = midInfoGr.getValue('last_update_time');
// this is a force sync if the mid info record is not marked as force sync, AND we have a last update time, AND that is not a reserved time for marking force (backward compatibility)
var isForcedSync = !(midInfoGr.getValue('force_config_sync') == '0' && handlerLastUpdate && handlerLastUpdate != this.FORCE_SYNC_TIMESTAMP);
var policyGr = new GlideRecord('sn_agent_policy');
// If this is not force sync only take the updated policies - otherwise take all policies for that mid.
if (!isForcedSync) {
/*
publish status = 5 is ready to publish.
Mostly the last_calc_time would be effected by the change to ready to publish, but in some cases we only want to sent
the policy to the MID server without changing the last_calc_time.
Example: adding a new proxy agents: we want to add more records to the table and send to the MID - but we would
not want to effect the detection of new CI
*/
var policyStateQuery = policyGr.addJoinQuery('sn_agent_policy_state', 'sys_id', 'policy');
policyStateQuery.addCondition('last_calc_time', '>', handlerLastUpdate).addOrCondition('publish_status', '5');
}
policyGr.addActiveQuery();
policyGr.addQuery('is_draft', '0');
policyGr.query();
if (useCloudServices) {
// handle Cloud Services case
var pod = midInfoGr.getValue('mid');
// this function handles sending the signed policies and signed agents,
// as well as sending the idle policy if needed (analogous to the orphan policy in the MID flow)
(new ConfigPublishPayload()).sendConfigPublishPayloadsForHandler(pod, this, policyGr, isForcedSync, handlerLastUpdate);
// Mark as done
this.disableForceSync(isForcedSync, midInfoGr);
continue;
}
var policies = [];
while (policyGr.next()) {
// If the MID does NOT have any agents for this policy, we will get an undefined object.
policy = this.getPolicyJson(policyGr, midInfoGr.getValue('mid'));
if (policy && policy.clients_cis && Object.keys(policy.clients_cis).length > 0)
policies.push(policy);
}
// Add MID argument to commands if they use check type with MID script.
this.handleMidParamsOnChecks(policies, midInfoGr.getValue('mid'), handlerLastUpdate);
// If this was a forced sync - put agents without a policy in idle policy
if (isForcedSync) {
var agentsForMidWithoutPolicies = [];
var agentsForMidWithPolicies = [];
for (var policyIndex = 0; policyIndex < policies.length; policyIndex++) {
var policy = policies[policyIndex];
for (var client in policy.clients_cis)
agentsForMidWithPolicies.push(client);
}
var agentsGr = new GlideRecord('sn_agent_ci_extended_info');
if (agentsForMidWithPolicies.length > 0)
agentsGr.addQuery('agent_id', 'NOT IN', agentsForMidWithPolicies);
agentsGr.addQuery('mid', midInfoGr.getValue('mid'));
agentsGr.query();
while (agentsGr.next()) {
agentsForMidWithoutPolicies.push(agentsGr.getValue('agent_id'));
}
if (agentsForMidWithoutPolicies.length > 0) {
var orphanPolicy = this.getOrphanPolicy(agentsForMidWithoutPolicies);
policies.push(orphanPolicy);
}
}
this.sendConfigPublishProbe(policies, midInfoGr.mid.name);
// Mark as done
this.disableForceSync(isForcedSync, midInfoGr);
}
this.setPoliciesToCurrectPublishedStatus();
}
if (this.policyUpdateDomainSeparation.isDomainSeparationPluginActive)
this.policyUpdateDomainSeparation.updatePolicies();
} finally {
// reset the domain to global if we changed domains during config synch
currentDomainId = this.domainInfo.getCurrentDomain();
if (this.policyUpdateDomainSeparation.isDomainSeparationPluginActive && currentDomainId != 'global')
this.policyUpdateDomainSeparation.changeSessionDomain('global');
}
},
/**
* Disables force sync on the passed the sn_agent_mid_info record
*
* Parameters:
* isForcedSync - true if the current policy sync is a force sync, false otherwise
* midInfoGr - a GlideRecord pointing to a sn_agent_mid_info record
*
* Return:
* none
*/
disableForceSync: function(isForcedSync, midInfoGr) {
if (!isForcedSync || !midInfoGr)
return;
midInfoGr.setValue('force_config_sync', '0');
midInfoGr.update();
},
setPoliciesToCurrectPublishedStatus: function() {
var policyGr = new GlideRecord('sn_agent_policy');
policyGr.setWorkflow(false);
policyGr.addActiveQuery();
policyGr.addQuery('is_draft', '0');
var policyStateQuery = policyGr.addJoinQuery('sn_agent_policy_state', 'sys_id', 'policy');
policyStateQuery.addCondition('publish_status', '5');
policyGr.query();
var draftUtil = new PolicyDraftUtils();
while (policyGr.next()) {
var publishStatus = "1"; // Published.
var draftPolicyGr = new GlideRecord('sn_agent_policy');
draftPolicyGr.addQuery('related_policy', policyGr.getUniqueValue());
draftPolicyGr.addQuery('is_draft', '1');
draftPolicyGr.addActiveQuery();
draftPolicyGr.query();
if (draftPolicyGr.next()) {
// Can be Published or Published* (diff between the published policy and the draft policy)
var draftPublishStatus = this.policyStateUtil.getPolicyStatePublishStatus(draftPolicyGr);
if (draftPublishStatus == '1' || draftPublishStatus == '2')
publishStatus = draftPublishStatus;
else {
if (draftUtil.isDraftDifferentFromPublished(draftPolicyGr))
publishStatus = "2"; // published but different from draft status.
this.policyStateUtil.updatePolicyStatePublishStatus(draftPolicyGr, publishStatus);
if (this.policyUpdateDomainSeparation.isDomainSeparationPluginActive)
this.policyUpdateDomainSeparation.updatePolicyStatusMap(draftPolicyGr, publishStatus);
else {
draftPolicyGr.setValue('publish_status', publishStatus);
draftPolicyGr.update();
}
}
}
this.policyStateUtil.updatePolicyStatePublishStatus(policyGr, publishStatus);
if (this.policyUpdateDomainSeparation.isDomainSeparationPluginActive)
this.policyUpdateDomainSeparation.updatePolicyStatusMap(policyGr, publishStatus);
else {
policyGr.setValue('publish_status', publishStatus);
policyGr.update();
}
}
},
atLeastOneUpAgent: function(mid) {
if (!mid)
return false;
var agentsGr = new GlideRecord('sn_agent_ci_extended_info');
agentsGr.addQuery('mid', mid);
agentsGr.addQuery('status', '0'); //up
agentsGr.setLimit(1);
agentsGr.query();
return agentsGr.hasNext();
},
/* This method loads to memory the policy structure as we will send it to the MID
Expected results:
{
"name": "<policy name>",
"interval": "60",
"cron_expressions": "0 0 0,1,2,3,4,5,6,7,17,18,19,20,21,22,23 ? * *|0 * 8-16 ? * *",
"id": "d3b9b2aed445d510e76096c40f8ab07c",
"auto_binding": "true",
"clients_cis": { (will be filled in later) },
"checks": [
{
"name": "<check name>",
"command": "echo {{.labels.params_ci_name}}",
"interval": "60",
"timeout": "60",
"id": "7afd37a2d489d510e76096c40f8ab09c",
"exec_mode": "execv",
"params_background": false,
"check_instance_id": "7afd37a2d489d510e76096c40f8ab09c",
"check_type_id": "a32f261967133300b7b72dbd2685eff9",
"params": {
"last_updated": "2022-08-04 21:51:29"
}
(THERE COULD BE MORE ATTRIBUTE NOT SHOWING HERE)
}
...
]
}
input : policy glide record that points to the policy record we are building
*/
loadPolicyToMemory: function(policyGr, payloadVersion) {
this.currentPolicy = {};
if (!policyGr.getUniqueValue()) {
gs.error(gs.getMessage("MonitoringConfig: in loadPolicyToMemory(): could not load policy to memory as there was a problem getting values from the policy glide record."));
return;
}
this.currentPolicy.name = policyGr.getValue('name');
this.currentPolicy.interval = policyGr.getValue('interval');
this.currentPolicy.cron_expressions = ""; // Will fill this later
this.currentPolicy.id = policyGr.getUniqueValue();
this.currentPolicy.auto_binding = policyGr.getValue('auto_binding') == '1';
// ci information is populated within the agent object instead of the policy object for payload version 2
// so only populate clients_cis for version 1 payload
if (!payloadVersion || payloadVersion < 2)
this.currentPolicy.clients_cis = {};
var grChecks = new GlideRecord('sn_agent_check');
grChecks.addQuery('monitoring_policy', policyGr.getUniqueValue());
grChecks.addActiveQuery();
grChecks.query();
this.currentPolicy.checks = [];
var credId, credAliasId = "";
if (policyGr.credential_alias)
credAliasId = "" + policyGr.credential_alias.id;
if (policyGr.cred_alias)
credId = MonitoringUtils.getCredIdFromCredName(policyGr.cred_alias);
var accUtils = new ACCConfigUtils();
var mc = new MonitoringConfig();
var allCronExp = [];
if (policyGr.getValue('cron_expressions'))
allCronExp = policyGr.getValue('cron_expressions').split(',');
while (grChecks.next()) {
try {
var checkObj = accUtils.getCheckJson(grChecks, credId, credAliasId, payloadVersion);
var command = grChecks.getValue('command');
checkObj["check_instance_id"] = "" + grChecks.sys_id;
if (grChecks.check_def && grChecks.check_def.check_script_type) {
checkObj["check_type_id"] = "" + grChecks.check_def.check_script_type;
//DO WE NEED to collect all check types uniquely here ???
if (grChecks.check_def.check_script_type.mid_script)
checkObj["mid_script"] = "" + grChecks.check_def.check_script_type.mid_script.name;
}
//try taking cron expressions from check
var cronExpressions = grChecks.cron_expressions;
if (cronExpressions)
allCronExp.push(cronExpressions);
//if cron expressions and interval are empty on check, try taking cron expressions from policy
if (gs.nil(cronExpressions) && gs.nil(checkObj["interval"])) {
cronExpressions = this.currentPolicy["cron_expressions"];
}
// Will go over this later and grab the cron expressions
if (!gs.nil(cronExpressions)) {
checkObj.cron_ref = cronExpressions;
} else {
//if we have no cron expressions on check and policy and interval on check is empty, take interval from policy
if (gs.nil(checkObj["interval"])) {
checkObj["interval"] = this.currentPolicy["interval"];
}
}
mc.addStatusChangeThresholds(grChecks, checkObj);
// if this check is using a CI parameter - keep it per policy, we will fill the
// only calculate ci params for the check if using payload version 1
if ((!payloadVersion || payloadVersion < 2) && command.indexOf(this.CI_PARAM_KEY) > 0) {
/* Structure will be
policy.clients_cis.CI_PARAMS_TO_CHECK_PLACE_HOLDER[<check sys id>] = array of ci param keys
*/
if (!this.currentPolicy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER]) {
this.currentPolicy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER] = {};
}
this.currentPolicy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER][grChecks.getUniqueValue()] = [];
var ciParams = this.currentPolicy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER][grChecks.getUniqueValue()];
// Get all ci params keys using regex
var myRegexp = new RegExp(this.CI_PARAM_KEY + "(.*?)}}", "gm");
var match = myRegexp.exec(command);
while (match != null) {
if (match[1]) {
ciParams.push(match[1]); // will be filled per CI later.
}
match = myRegexp.exec(command);
}
}
mc.addParam(checkObj, "last_updated", grChecks.getValue('sys_updated_on'));
this.currentPolicy.checks.push(checkObj);
} catch (e) {
gs.error(gs.getMessage("MonitoringConfig: Skipping check: {0} ({1}) invalid json, error: {2}", [grChecks.name, grChecks.sys_id, e]));
}
}
// If nothing to do with cron - return.
if (!allCronExp || allCronExp.length < 1) {
delete this.currentPolicy.cron_expressions;
return;
}
// Add cron expressions
var grCron = new GlideRecord("sn_agent_cron_expression");
grCron.addQuery("sys_id", allCronExp);
grCron.query();
var cronExpMap = {};
while (grCron.next()) {
cronExpMap[grCron.getUniqueValue()] = grCron.cron_expression;
}
// We could not create a cron expression map; nothing to replace with.
var isCronExpMap = Object.keys(cronExpMap).length != 0;
var p;
if (isCronExpMap)
p = new PolicyClientsGeneratorNG();
for (var i = 0; i < this.currentPolicy.checks.length; i++) {
var check = this.currentPolicy.checks[i];
if (!check.cron_ref)
continue;
if (isCronExpMap)
mc.addParam(check, "cron_expressions", p.replaceCronReferenceWithExpression(check.cron_ref, cronExpMap));
delete check.cron_ref; // No need for it now
}
if (isCronExpMap)
this.currentPolicy.cron_expressions = p.replaceCronReferenceWithExpression(policyGr.getValue('cron_expressions'), cronExpMap);
},
isProxyPolicy: function(policyGr) {
return policyGr.single_proxy_agent || policyGr.proxy_advanced || policyGr.proxy_script_advanced || policyGr.proxy_cluster;
},
/*
This method returns a policy structure with agents (policy.clients_cis) and CI params per check, if needed.
Input: policyGr - a GR point to the current policy
midId - the mid sys id to create the policy for (it will be sent as an ecc queue)
*/
getPolicyJson: function(policyGr, midId) {
if (!policyGr || !policyGr.sys_id)
return undefined;
var policyMonitoredCIsGr = new GlideRecord('sn_agent_policy_monitored_cis');
policyMonitoredCIsGr.addQuery('policy', policyGr.getValue('sys_id'));
policyMonitoredCIsGr.addNotNullQuery('monitored_ci');
policyMonitoredCIsGr.addNotNullQuery('agent_id');
if (midId)
policyMonitoredCIsGr.addQuery('agent_id.mid', midId);
policyMonitoredCIsGr.setCategory('acc-policy-calc');
policyMonitoredCIsGr.query();
if (!policyMonitoredCIsGr.hasNext())
return undefined;
this.loadPolicyToMemory(policyGr);
var ciParamsToPopulate = false;
var policy = this.currentPolicy;
if (!policy.clients_cis)
policy.clients_cis = {};
if (policy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER])
ciParamsToPopulate = true;
var isProxyPolicy = this.isProxyPolicy(policyGr);
while (policyMonitoredCIsGr.next()) {
var agentId = policyMonitoredCIsGr.getValue('agent_id');
var monitoredCi = policyMonitoredCIsGr.getValue('monitored_ci');
if (!policy.clients_cis[agentId])
policy.clients_cis[agentId] = {};
if (!policy.clients_cis[agentId][monitoredCi])
policy.clients_cis[agentId][monitoredCi] = {};
// If this policy does not contain any checks that has CI params - continue
if (!ciParamsToPopulate)
continue;
// Prepare a db CI param map ({key: value})
var dbCiParams = policyMonitoredCIsGr.getValue('ci_params');
if (!dbCiParams)
continue;
var arrDbCiParams = dbCiParams.split(',');
var dbCiParamsMap = {};
for (var i = 0; i < arrDbCiParams.length; i++) {
if (!arrDbCiParams[i])
continue;
var index = arrDbCiParams[i].indexOf('=');
// We had a string without the "=" sign; add it as a key with no value, if it does not exist
if (index < 0) {
if (!dbCiParamsMap[arrDbCiParams[i]])
dbCiParamsMap[arrDbCiParams[i]] = "";
continue;
}
var key = arrDbCiParams[i].substring(0, index);
var value = "";
if (index > 0) // check that we do have a value, otherwise we will have an empty string
value = arrDbCiParams[i].substring(index + 1);
dbCiParamsMap[key] = value;
}
// Per check find the correct CI Params
for (var checkSysId in policy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER]) {
// Create the structure for the CI Params
policy.clients_cis[agentId][monitoredCi][checkSysId] = {};
policy.clients_cis[agentId][monitoredCi][checkSysId]["ci"] = {};
// Go over the CI params for the current check
var arrCiParamsKeysForCheck = policy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER][checkSysId];
for (var j = 0; j < arrCiParamsKeysForCheck.length; j++) {
var ciParamKey = arrCiParamsKeysForCheck[j];
var ciParamValue = dbCiParamsMap[ciParamKey];
policy.clients_cis[agentId][monitoredCi][checkSysId]["ci"][ciParamKey] = ciParamValue;
}
if (isProxyPolicy) {
this.addProxyCheckCiParamsValues(policy.clients_cis[agentId][monitoredCi][checkSysId], dbCiParamsMap, agentId);
}
}
}
// No need for the place holder
delete policy.clients_cis[this.CI_PARAMS_TO_CHECK_PLACE_HOLDER];
return policy;
},
/*
* Query the agent registration table for certificate information. When agent is MID-less, agent should be registered
* with servicenow instance before reaching instance.
*/
getAgentRegistration: function(agentId) {
var regGr = new GlideRecord("sn_agent_agent_registration");
regGr.addQuery("agent_id", agentId);
regGr.addQuery("is_validated", true);
regGr.query();
if (!regGr.next())
return "";
return regGr.getUniqueValue();
},
addProxyCheckCiParamsValues: function(checkObj, valuesParamsMap, agentId) {
for (var i = 0; i < this.PROXY_CHECK_CI_PARAM.length; i++) {
var proxyParamVal = valuesParamsMap[this.PROXY_CHECK_CI_PARAM[i]];
if (proxyParamVal)
checkObj[this.PROXY_CHECK_CI_PARAM[i]] = proxyParamVal;
}
var entrypointMetricResourceName = this.getEntrypointMetricsResourceName(agentId);
// in case resource name is indeed nil (very unlikely...), MID should put the raw agent client name (which should resolve to the agent host name) as resource
if (!gs.nil(entrypointMetricResourceName))
checkObj[this.ENTRYPOINT_METRIC_RESOURCE_PARAM] = entrypointMetricResourceName;
// Mark this as proxy check
checkObj[this.IS_PROXY_CHECK] = true;
},
getEntrypointMetricsResourceName: function(agentId) {
var agentCiGr = new GlideRecord("sn_agent_cmdb_ci_agent");
if (!agentCiGr.get("agent_id", agentId)) {
gs.error(gs.getMessage("PolicyClientsGeneratorNG.getEntrypointMetricsResourceName: ERROR: no agent with agent_id == {0}", agentId));
return undefined;
}
var hostname = null;
var location = null;
var agentHostGr = new GlideRecord("cmdb_ci");
if (!agentHostGr.get(agentCiGr.agent_extended_info.cmdb_ci)) {
gs.error(gs.getMessage("PolicyClientsGeneratorNG.getEntrypointMetricsResourceName: ERROR: agent with agent_id == {0} doesn't have a valid host CI", agentId));
return undefined;
}
hostname = agentHostGr.getValue("name");
var useHostname = gs.getProperty(this.ENTRYPOINT_METRIC_RESOURCE_USE_HOSTNAME_PROPERTY, "true") === "true";
var useLocation = gs.getProperty(this.ENTRYPOINT_METRIC_RESOURCE_USE_LOCATION_PROPERTY, "true") === "true";
if (useLocation) {
// try taking location from agent host CI. Fallback to location on agent CI
if (!gs.nil(agentHostGr.getValue("location")))
location = agentHostGr.getElement("location").getDisplayValue();
else if (!gs.nil(agentCiGr.getValue("location")))
location = agentCiGr.getElement("location").getDisplayValue();
if (!gs.nil(location))
return useHostname ? "From host: " + hostname + ", location: " + location : "From location: " + location;
else {
gs.warn(gs.getMessage("PolicyClientsGeneratorNG.getEntrypointMetricsResourceName: WARNING: property specifies to use location but it is nil. Falling back to hostname"));
}
}
if (useHostname)
return "From host: " + hostname;
else {
gs.warn(gs.getMessage("PolicyClientsGeneratorNG.getEntrypointMetricsResourceName: WARNING: location is nil (becasue property specifies to not use it or because it is not present on agent and agent host CIs) and property specifies to not use hostname. Hostname reported by agent websocket connection will be used"));
}
// the metrics parser script on the MID will use the hostname returned by the agent websocket connection as the hostname
return undefined;
},
addParam: function(object, paramName, paramVal) {
if (!object["params"]) {
object["params"] = {};
}
object["params"][paramName] = paramVal;
},
runInitialHostDataCollection: function() {
var AGENTS_IDS = 'clients_cis';
// Get all agents that ...
var agentGr = new GlideRecord('sn_agent_ci_extended_info');
agentGr.addQuery('status', 'IN', '0,1'); // 0=Up, 1=Warning
// was never discovered
agentGr.addNullQuery('host_data'); // mimic old behavior.
agentGr.addNullQuery('cmdb_ci');
// And we have all the data needed
agentGr.addQuery('is_duplicate', 'false');
agentGr.addNotNullQuery('mid');
agentGr.addNotNullQuery('agent_id');
agentGr.orderBy('mid');
agentGr.query();
// Now that we have all new, undiscovered, agents - we need to arrange them per MID.
var agentsToRefreshPerMid = {};
var runDiscovery = false;
while (agentGr.next()) {
var midName;
if (global.JSUtil.getBooleanValue(agentGr, "use_cloud_services"))
midName = ACCConstants.CLOUD_SERVICES_POD_PREFIX + agentGr.mid;
else
midName = agentGr.mid.name;
if (!midName) {
gs.warn(gs.getMessage("ACC initial discovery: MID name is empty - will continue to next record. sn_agent_ci_extended_info sys id={0}", agentGr.getUniqueValue()));
continue;
}
// If there is no object for the specific MID name, create one.
if (!agentsToRefreshPerMid[midName]) {
agentsToRefreshPerMid[midName] = {};
agentsToRefreshPerMid[midName][AGENTS_IDS] = {};
}
agentsToRefreshPerMid[midName][AGENTS_IDS][agentGr.getValue('agent_id')] = {};
// put in the sn_agent_ci_extended_info sys_id as the "monitored ci" since we don't have one yet
agentsToRefreshPerMid[midName][AGENTS_IDS][agentGr.getValue('agent_id')][agentGr.getUniqueValue()] = {};
if (!runDiscovery)
runDiscovery = true;
}
if (!runDiscovery) {
gs.debug(gs.getMessage("ACC initial discovery: Found no agents to run host data collection."));
return;
}
var adsu = new AgentDiscoverySharedUtils();
// Run discovery and set the host_data status
adsu.runDiscoveryCheckForAgentPerMid(agentsToRefreshPerMid);
},
type: 'MonitoringConfig'
};
Sys ID
6c62a3f0c305130039a3553a81d3ae88