Name
sn_agent.AgentNowSetup
Description
No description available
Script
var AgentNowSetup = Class.create();
AgentNowSetup.prototype = Object.extendsObject(global.AbstractAjaxProcessor, {
setup: function() {
var mid = this.getParameter('sysparm_mid');
var port = this.getParameter('sysparm_port');
var ip_address = this.getParameter('sysparm_ip_address');
return this.setupExt(mid, port, ip_address);
},
setupExt: function(mid, port, ip_address) {
var retObj = {
"msg": "",
"extToPoll": []
};
var errorMsg = this.validateParams(port, ip_address);
if (!gs.nil(errorMsg)) {
retObj.msg = errorMsg;
return new global.JSON().encode(retObj);
}
var midGr = this.getMidGr(mid);
if (midGr) {
// if this method is activated, then we should setup both extensions from scratch using the given parameters.
// Stop and delete/modify existing extensions
var webserverGr = this.getWebServer(midGr);
if (webserverGr != null) {
if ((webserverGr.getValue("status") + "").toLowerCase() != "started") {
// apply the changes required and start as we can't delete because web server table doesn't allow deletion from different scope
webserverGr.setValue("port_number", port);
webserverGr.update();
new global.MIDExtensionContext(webserverGr).start();
retObj.extToPoll.push(webserverGr.getUniqueValue());
}
} else {
webserverGr = this.createWebServer(midGr, port);
if (webserverGr == null) {
retObj.msg = gs.getMessage("Error. Failed to setup Agent Client Collector. MID Web Server creation didn't succeed.");
return new global.JSON().encode(retObj);
}
retObj.extToPoll.push(webserverGr.getUniqueValue());
}
var websocketGr = this.getWebSocket(midGr);
if (websocketGr != null) {
if ((websocketGr.getValue("status") + "").toLowerCase() == "started")
new global.MIDExtensionContext(websocketGr).stop();
websocketGr.setWorkflow(false); // BR prevents deletion while stopping
websocketGr.deleteRecord();
}
websocketGr = this.createWebSocket(midGr, ip_address);
if (websocketGr == null) {
retObj.msg = gs.getMessage("Error. Failed to setup Agent Client Collector. WebSocket Endpoint creation didn't succeed.");
return new global.JSON().encode(retObj);
}
retObj.extToPoll.push(websocketGr.getUniqueValue());
retObj.msg = this.getEndpointUrl(midGr, websocketGr, webserverGr);
} else {
retObj.msg = gs.getMessage("Error. Failed to setup Agent Client Collector on this MID (sys_id == {0}).", mid);
}
return new global.JSON().encode(retObj);
},
getMidName: function(midId) {
var midGr = new GlideRecord("ecc_agent");
if (midGr.get(midId))
return midGr.getValue("name");
return "";
},
multiSetup: function() {
var createExtToMidIdsList = this.getParameter('sysparm_createExtToMidIdsList').split(",");
var port = this.getParameter('sysparm_port');
var extSetupList = {};
for (var i = 0; i < createExtToMidIdsList.length; i++) {
var midId = createExtToMidIdsList[i];
var setUpJson = JSON.parse(this.setupExt(midId, port, null));
setUpJson["name"] = this.getMidName(midId);
extSetupList[midId] = setUpJson;
}
return encodeURIComponent(JSON.stringify(extSetupList));
},
validateParams: function(port, ip_address) {
var message = "";
var portMsg = "";
var portNum = parseInt(port);
if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
portMsg = gs.getMessage("Invalid port. Valid range is 1-65535.");
}
var ipMsg = "";
if (ip_address && !this.validateIPaddress(ip_address)) {
ipMsg = gs.getMessage("Invalid IP address");
}
if (message != "" && portMsg != "") {
message = gs.getMessage("{0}. {1}", [message, portMsg]);
} else if (portMsg != "") { //message must be empty string
message = gs.getMessage("Error. {0}", portMsg);
}
if (message != "" && ipMsg != "") {
message = gs.getMessage("{0}. {1}", [message, ipMsg]);
} else if (ipMsg != "") { //message must be empty string
message = gs.getMessage("Error. {0}", ipMsg);
}
return message;
},
startExt: function(tableName, sysId) {
var gr = new GlideRecord(tableName);
gr.get(sysId);
context = new global.MIDExtensionContext(gr);
context.start();
},
createWebSocket: function(midGr, ip_address) {
var websocketGr = new GlideRecord("sn_agent_ext_context");
websocketGr.initialize();
websocketGr.setValue("name", "mid_websocket_" + midGr.getValue("name"));
websocketGr.setValue("mid_server", midGr.getUniqueValue());
if (ip_address)
websocketGr.setValue("ip_address", ip_address);
websocketGr.setValue("short_description", "Automatically created extension using the 'ACC Setup'");
var websocketId = websocketGr.insert();
if (gs.nil(websocketId))
return null;
this.startExt("sn_agent_ext_context", websocketId);
return websocketGr;
},
handleApiKey: function(midGr, webserverGr) {
var apiKeyCredGr = new GlideRecord("mid_webserver_api_key_credentials");
// pre San Diego flow. If San Diego and beyond then API Key creation is handled by business rule on web server table
if (!apiKeyCredGr.isValid()) {
var apiKey = new global.MidWebServerApiKey();
var midDomain = midGr.getValue("sys_domain");
var key = apiKey.getKey(midDomain);
if (key != "")
webserverGr.setValue("secret_key", key);
else
webserverGr.setValue("secret_key", apiKey.generate(midDomain));
}
},
createWebServer: function(midGr, port) {
var webserverGr = new GlideRecord("ecc_agent_ext_context_webserver");
webserverGr.initialize();
webserverGr.setValue("name", "mid_webserver_" + midGr.getValue("name"));
webserverGr.setValue("mid_server", midGr.getUniqueValue());
webserverGr.setValue("port_number", port);
webserverGr.setValue("execute_on", "Specific MID Server");
webserverGr.setValue("authentication_type", "3");
this.handleApiKey(midGr, webserverGr);
webserverGr.setValue("secure_connection", true);
webserverGr.setValue("short_description", "Automatically created extension using the 'ACC Setup'");
var webserverId = webserverGr.insert();
if (gs.nil(webserverId))
return null;
this.startExt("ecc_agent_ext_context_webserver", webserverId);
return webserverGr;
},
getEndpointUrl: function(midGr, websocketGr, webserverGr) {
// try using the calculated values
var endpoint = websocketGr.getValue('endpoint_url');
var endpoint_ip6;
var msg;
if (endpoint) {
msg = gs.getMessage("Endpoint is ready to use: {0}", endpoint);
endpoint_ip6 = websocketGr.getValue('endpoint_url_ipv6');
if (!endpoint_ip6)
return msg;
msg = gs.getMessage("Endpoints are ready for use: {0} and {1}", [endpoint, endpoint_ip6]);
return msg;
}
// otherwise, calculate it
endpoint = this.calculateEndpointUrlForIpVersion(websocketGr, 4);
endpoint_ip6 = this.calculateEndpointUrlForIpVersion(websocketGr, 6);
if (!endpoint_ip6)
msg = gs.getMessage("Endpoint is ready to use: {0}", endpoint);
else
msg = gs.getMessage("Endpoints are ready for use: {0} and {1}", [endpoint, endpoint_ip6]);
return msg;
},
validateIPaddress: function(inputText) {
var ipformat = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
if (inputText.match(ipformat))
return true;
return false;
},
buildMessage: function(msgArray) {
var message = "";
for (index in msgArray) {
message += msgArray[index];
}
return message;
},
// pre-San Diego release, only IPv4 values were stored in IP address fields and the logic to
// validate IP Addresses was not exposed to the ACC-F scoped app
shouldValidateIp: function() {
return (typeof global.ScopedIpUtils == 'function');
},
getIpFromWebSocket: function(extContextGr, ipVersion) {
var ip = extContextGr.getValue('ip_address');
if (!ip)
return '';
if (!this.shouldValidateIp())
return ip;
// the IP Address field can store either IPv4 or IPv6, so verify the version before returning
if (ipVersion == 4 && global.ScopedIpUtils.isV4(ip))
return ip;
if (ipVersion == 6 && global.ScopedIpUtils.isV6(ip))
return ip;
return '';
},
getIpFromMidRecord: function(midSysId, ipVersion) {
if (!midSysId || !ipVersion)
return '';
var midGr = new GlideRecord('ecc_agent');
midGr.addQuery('sys_id', midSysId);
midGr.query();
if (!midGr.next())
return ''; /*no associated MID - return empty string */
var ip = midGr.getValue('ip_address');
if (!this.shouldValidateIp())
return ip;
// the IP Address field can store either IPv4 or IPv6, so verify the version before returning
if (ipVersion == 4 && global.ScopedIpUtils.isV4(ip))
return ip;
if (ipVersion == 6 && global.ScopedIpUtils.isV6(ip))
return ip;
return '';
},
getIpFromMidIpAddressTable: function(midSysId, ipVersion) {
if (!midSysId || !ipVersion)
return '';
var midIpGr = new GlideRecord('ecc_agent_ip_address');
midIpGr.addQuery('mid_server', midSysId);
midIpGr.addQuery('ip_version', ipVersion);
midIpGr.query();
if (midIpGr.next())
return midIpGr.getValue('ip_address');
return '';
},
calculateEndpointUrlForIpVersion: function(extContextGr, ipVersion) {
var midSysId = extContextGr.getValue('mid_server');
var ip = this.getIpFromWebSocket(extContextGr, ipVersion);
if (!ip)
ip = this.getIpFromMidRecord(midSysId, ipVersion);
if (!ip)
ip = this.getIpFromMidIpAddressTable(midSysId, ipVersion);
if (!ip)
return '';
var gr = new GlideRecord('ecc_agent_ext_context_webserver');
gr.addQuery('mid_server', midSysId);
gr.query();
var port = '8800';
var protocol = 'ws';
if (gr.next()) {
port = gr.getValue('port_number');
if (gr.getValue('secure_connection') == '1') {
protocol += 's';
}
}
if (ipVersion == 6)
return gs.getMessage('{0}://[{1}]:{2}/ws/events', [protocol, ip, port]);
return gs.getMessage('{0}://{1}:{2}/ws/events', [protocol, ip, port]);
},
// current refers to the sn_agent_ext_context record
// called from the calculated field sn_agent_ext_context.endpoint_url
calculateEndpointUrl: function(current) {
return this.calculateEndpointUrlForIpVersion(current, 4);
},
// current refers to the sn_agent_ext_context record
// called from the calculated field sn_agent_ext_context.endpoint_url_ipv6
calculateIPv6EndpointUrl: function(current) {
// pre-San Diego release family doesn't know how to handle this field
if (!this.shouldValidateIp())
return '';
return this.calculateEndpointUrlForIpVersion(current, 6);
},
getMidGrIfMidIsAvailable: function(midId) {
var midGr = new GlideRecord("ecc_agent");
if (midGr.get(midId)) {
if (midGr.status == 'Up' && midGr.validated == 'true')
return midGr;
}
return null;
},
isSetupAlreadyConfiguredOnMids: function() {
var selectedMids = this.getParameter('sysparm_mids');
var isAccAlreadyConfiguredWrapper = function(midId) {
return this.isAccAlreadyConfigured(midId);
};
return this.setupMids(selectedMids, isAccAlreadyConfiguredWrapper.bind(this));
},
setupMids: function(selectedMidsStr, isAccAlreadyConfiguredFunc) {
var selectedMids = selectedMidsStr.split(',');
var maxSelectedMids = gs.getProperty("sn_agent.maximum_mids_to_select", 20);
if (selectedMids.length > maxSelectedMids) {
// Use toString() so that the (selectedMids.length) does not appear as a decimal number in the message
gs.addErrorMessage(gs.getMessage("The number of MIDs selected is {0}, but the maximum allowed is {1} according to the 'sn_agent.maximum_mids_to_select' property.", [(selectedMids.length).toString(), maxSelectedMids]));
return -1;
}
var retObjList = {};
for (var i = 0; i < selectedMids.length; i++) {
var midId = selectedMids[i];
var midGr = this.getMidGrIfMidIsAvailable(midId);
if (midGr != null) {
var isAccAlreadyConfigured;
//We allow setup Agent Client Collector only from domain leaf
var isDomainLeaf = new sn_agent.DomainInfo().isDomainLeaf(midGr.sys_domain);
if (!isDomainLeaf) {
isAccAlreadyConfigured = {
'isSetupConfigured': true,
'msg': gs.getMessage("Error. Failed to setup Agent Client Collector. The setup is allowed only for leaf domains."),
'extToPoll': []
};
} else if (!AccExtSetupUtil.isSetupEnabledForMid(midId)) {
isAccAlreadyConfigured = {
'isSetupConfigured': true,
'msg': gs.getMessage("Error. Failed to setup Agent Client Collector. Setup is allowed only when the user domain is identical to the MID Server domain, or when the mid is in a leaf domain and the user is in the global domain."),
'extToPoll': []
};
} else {
isAccAlreadyConfigured = isAccAlreadyConfiguredFunc(midId);
}
isAccAlreadyConfigured['name'] = midGr.getValue('name');
retObjList[midId] = isAccAlreadyConfigured;
}
}
return JSON.stringify(retObjList);
},
isSetupAlreadyConfigured: function() {
var mid = this.getParameter('sysparm_mid');
var retObj = this.isAccAlreadyConfigured(mid);
return new global.JSON().encode(retObj);
},
isAccAlreadyConfigured: function(midId) {
var retObj = {
'isSetupConfigured': true,
'msg': "",
"extToPoll": []
};
if (!GlidePluginManager.isActive('com.snc.sa.mid.webserver')) {
retObj.msg = gs.getMessage("Error. Install com.snc.sa.mid.webserver plugin before setting up ACC listener");
return retObj;
}
var midGr = this.getMidGr(midId);
if (midGr) {
var webServerGr = this.getWebServer(midGr);
var webSocketGr = this.getWebSocket(midGr);
// check which extensions are already present and if they are started or not
if (webServerGr || webSocketGr) {
if (!webSocketGr) { // webserver exists but websocket doesn't
if (webServerGr.getValue("authentication_type") == "1") { // 1 -> Keybased
retObj.msg = gs.getMessage("Error. MID Web Server associated with this MID uses Keybased authentication, which is not supported.");
return retObj;
}
if ((webServerGr.getValue("status") + "").toLowerCase() != "started") {
var webserverId = webServerGr.getUniqueValue();
this.startExt("ecc_agent_ext_context_webserver", webserverId);
retObj.extToPoll.push(webserverId);
}
webSocketGr = this.createWebSocket(midGr);
if (gs.nil(webSocketGr)) {
retObj.msg = gs.getMessage("Error. Failed Creating WebSocket Endpoint extension on this MID ({0}).", midGr.getValue("name"));
return retObj;
}
retObj.extToPoll.push(webSocketGr.getUniqueValue());
} else if (!webServerGr) { // websocket exists but webserver doesn't
// in this case let's make sure that the websocket extension is stopped and deleted
gs.warn(gs.getMessage("ACC Extensions Setup: Found WebSocket Endpoint extension on a MID Server that doesn't have a MID Web Server extension. Making sure it is stopped and deleted..."));
// send the MID a command to stop the extension if it started
if ((webSocketGr.getValue("status") + "").toLowerCase() == "started")
new global.MIDExtensionContext(webSocketGr).stop();
webSocketGr.setWorkflow(false); // BR prevents deletion while stopping
webSocketGr.deleteRecord();
retObj.isSetupConfigured = false; // now the given MID has no extensions at all so setup is not configured...
return retObj;
} else { // both extensions exist
if ((webServerGr.getValue("status") + "").toLowerCase() != "started") {
webserverId = webServerGr.getUniqueValue();
this.startExt("ecc_agent_ext_context_webserver", webserverId);
retObj.extToPoll.push(webserverId);
}
if ((webSocketGr.getValue("status") + "").toLowerCase() != "started") {
var websocketId = webSocketGr.getUniqueValue();
this.startExt("sn_agent_ext_context", websocketId);
retObj.extToPoll.push(websocketId);
}
}
retObj.msg = this.getEndpointUrl(midGr, webSocketGr, webServerGr);
} else
retObj.isSetupConfigured = false;
} else {
retObj.msg = gs.getMessage("Error. Failed to setup Agent Client Collector on this MID (sys_id == {0}).", midId);
}
return retObj;
},
getMidGr: function(midId) {
var gr = new GlideRecord("ecc_agent");
if (gr.get(midId)) {
return gr;
}
return null;
},
getWebSocket: function(midGr) {
var websocketGr = new GlideRecord("sn_agent_ext_context");
websocketGr.addQuery("mid_server", midGr.getUniqueValue());
websocketGr.query();
if (websocketGr.next())
return websocketGr;
return null;
},
getWebServer: function(midGr) {
var webserverGr = new GlideRecord("ecc_agent_ext_context_webserver");
webserverGr.addQuery("mid_server", midGr.getUniqueValue());
webserverGr.query();
if (webserverGr.next())
return webserverGr;
return null;
},
type: 'AgentNowSetup'
});
Sys ID
69494d79532e730034b8ddeeff7b1251