Name
global.CloudWizardDiscovery
Description
This class contains all common methods that are used for the Discovery scheduler Wizard Configuration
Script
var CloudWizardDiscovery = Class.create();
CloudWizardDiscovery.prototype = Object.extendsObject(CloudDiscovery, {
initialize: function() {
this._isAllowed(this.type);
},
validateAccount: function(obj,midServer) {
this._debug("validateAccount-> Start configObj-" , obj);
var configObj = this._createEmptyConfigObj();
configObj.service_account.name = String(obj.accountName);
configObj.service_account.account_id = String(obj.accountId);
configObj.service_account.discovery_credentials = String(obj.accountCredentialsId);
configObj.service_account.datacenter_url = String(obj.accountUrl);
configObj.service_account.datacenter_type = String(obj.accountType);
configObj.service_account.parent_account = String(obj.parentAccount);
configObj.service_account.accessor_account = String(obj.accessorAccount);
configObj.service_account.existing_access_role_name = String(obj.existingAccessRoleName);
configObj.service_account.existing_accessor_account_ref = String(obj.existingAccessorAccountRef);
configObj.service_account.existing_credentials_ref = String(obj.existingCredentialsRef);
var probeParams = {};
var probeValues = {"ecc_high_priority" : true};
var nextPatternId = this._getPatternId( obj.accountType, this.SPECIAL_PATTERNS.ACCOUNT_VALIDATION);
var invocationContext = {};
invocationContext['service_account_id'] = configObj.service_account.account_id;
var midName = midServer ? midServer : this._getAutoMid(configObj.service_account.datacenter_type, JSON.stringify(invocationContext));
//Create dummay service account table(just for validation)
var SA = {
"discovery_credentials": String(obj.accountCredentialsId),
"discovery_source": "ServiceNow",
"datacenter_url": String(obj.accountUrl),
"object_id": String(obj.accountId),
"name": String(obj.accountName),
"sys_class_name": "cmdb_ci_cloud_service_account",
"datacenter_type": String(obj.accountType),
"account_id": String(obj.accountId),
"is_master_account": "false", //Should be changed if needed by validation
"parent_account": String(obj.parentAccount),
"accessor_account": String(obj.accessorAccount),
"existing_access_role_name": String(obj.existingAccessRoleName),
"existing_accessor_account_ref": String(obj.existingAccessorAccountRef),
"existing_credentials_ref": String(obj.existingCredentialsRef)
};
// Before we trigger pattern lets check if user has provided any form fields data.
// Form Fields data is something which is a fixed data which cloud resources discovery pattern(s) needs them
// and each field is the field in cloud service account needs so we pass that data to the patterns as they're
// responsible for inserting/updating cloud service account
if (obj.hasOwnProperty('formFieldsData'))
SA['formFieldsData'] = obj['formFieldsData'];
var ppe = new SNC.PrePatternExecutionData();
ppe.addTableEntry('service_account', SA);
//In case of Validation don't create auto relations
ppe.addString('build_relation_from_host_sys_id','false'); // Don't take the host from the real CI table instead of the computerSystem
ppe.addString('no_relation','true'); //Refrain of creating auto relation (all the relation will be done by the pattern itself)
this.statusId = this._createDiscoveryStatus("Perform validation account-"+obj.accountId, this.type);
this._invokePhase(configObj, nextPatternId, midName, probeParams, probeValues, ppe, 'Account Validation');
this._debug("validateAccount->invoke validateAccount Phase end-" , configObj);
return this.statusId;
},
refreshMemberAccounts: function(accountSysId, midServer) {
this._debug("refreshMemberAccounts-> Start accountSysId" , accountSysId);
var res = this._refreshData(accountSysId, this.SPECIAL_PATTERNS.ACCOUNTS_DISCOVERY, midServer);
this._debug("refreshMemberAccounts-> End accountSysId" , accountSysId);
return res;
},
refreshDatacenters: function(accountSysId,midServer, memberAccounts) {
this._debug("refreshDatacenters-> Start accountSysId" , accountSysId);
var SA = this._getAccountGR(String(accountSysId)),
serviceAccountGR = new GlideRecord("cmdb_ci_cloud_service_account"),
masterAndMembersAccount = {};
masterAndMembersAccount[String(accountSysId)] = true;
if(typeof memberAccounts !== 'undefined') {
memberAccounts.forEach(function(o){
masterAndMembersAccount[String(o.sysId)] = true;
});
} else {
if (String(SA.datacenter_type) == 'cmdb_ci_google_datacenter' && SA.organization_id) {
serviceAccountGR.addQuery("organization_id", String(SA.organization_id));
serviceAccountGR.addQuery("sys_id","!=", String(accountSysId));
} else
serviceAccountGR.addQuery("parent_account", accountSysId);
serviceAccountGR.addQuery('install_status','!=','7'); // We should only add those member accounts whose install_status is not retiered
serviceAccountGR.query();
while (serviceAccountGR.next()) {
masterAndMembersAccount[String(serviceAccountGR.getUniqueValue())] = true;
}
}
var res = this._refreshDataCenter(masterAndMembersAccount, this.SPECIAL_PATTERNS.LDCS_DISCOVERY, midServer);
this._debug("refreshDatacenters-> End accountSysId" , accountSysId);
return res;
},
getDiscoveryResult: function(statusSysId) {
var myError = new sn_ws_err.ServiceError();
var obj = {
"state": "processing",
"message" : "",
"ci_list" : []
};
if (gs.nil(statusSysId)){
gs.error("getDiscoveryResult- Missing mandatory input statusSysId");
myError.setStatus(500);
myError.setMessage("getDiscoveryResult- Missing mandatory input statusSysId parameters" );
myError.setDetail("Here are the details of the arguments passed to this script " + JSON.stringify(statusSysId, null, 2));
return myError;
}
var statsGr = new GlideRecord('discovery_status');
if (!statsGr.get( String(statusSysId) )) {
gs.error("getDiscoveryResult- can't find statusSysId[{0}]", statusSysId);
myError.setStatus(500);
myError.setMessage("Can't find statusSysId-" + statusSysId);
return myError;
}
var state = statsGr.getValue("state");
if (state != "Completed"){
return obj; //Meaning still processing ...
}
var gr = new GlideRecord("discovery_device_history");
gr.addQuery("status", statusSysId);
gr.query();
var ciSysIdList=[];
while (gr.next()){
if (!gs.nil(gr.getValue("cmdb_ci")))
ciSysIdList.push(gr.getValue("cmdb_ci"));
}
gr = new GlideRecord("cmdb_ci");
gr.addQuery("sys_id", "IN", ciSysIdList);
gr.query();
var tmpl = {};
while (gr.next()){
tmpl = {
"sys_id": gr.getValue("sys_id"),
"sys_class_name": gr.getValue("sys_class_name"),
"name": gr.getValue("name")
};
var grSA = new GlideRecord(tmpl.sys_class_name);
grSA.get(tmpl.sys_id);
tmpl.object_id = grSA.getValue("object_id");
if (tmpl.sys_class_name == "cmdb_ci_cloud_service_account"){
tmpl.is_master_account = JSUtil.getBooleanValue(grSA, "is_master_account");
tmpl.datacenter_url = grSA.getValue("datacenter_url");
tmpl.datacenter_type = grSA.getValue("datacenter_type");
tmpl.parent_account = grSA.getValue("parent_account");
tmpl.account_id = grSA.getValue("account_id");
tmpl.discovery_credentials = grSA.getValue("discovery_credentials");
tmpl.sys_updated_on = grSA.getValue("sys_updated_on");
tmpl.organization_id = grSA.getValue("organization_id");
tmpl.exclude_from_discovery = (grSA.getValue("exclude_from_discovery") == 1);
}
obj.ci_list.push(tmpl);
}
if (ciSysIdList.length > 0 ){
obj.state = "success";
} else {
//Grab the error if exists
//Pick up the error message from automation_error_instance_msg based on the discovery status if exists.
var errorMessage = '';
var errInstanceGr = new GlideRecord('automation_error_instance_msg');
errInstanceGr.query('instance_key', statusSysId);
if (errInstanceGr.next())
errorMessage = String(errInstanceGr.err_msg.message);
else {
//Pick up the error message from discovery_log only if automation_error_instance_msg doesn't exist for the status. This happens when cmdb_ci is empty in the device_history.
errorMessage = this._getErrorOrInfoForDiscoveryStatusFromDiscoveryLog(statusSysId,2); // check for errors in discovery_log table
if (!errorMessage)
errorMessage = this._getErrorOrInfoForDiscoveryStatusFromDiscoveryLog(statusSysId,0); // check for information in discovery_log table
//Send this error message if we can't figure out the exact message based on the above two tables.
if (!errorMessage)
errorMessage = "An error occurred while trying to discover";
}
obj.message = errorMessage;
obj.state = "error";
}
return obj;
},
_getErrorOrInfoForDiscoveryStatusFromDiscoveryLog: function(statusSysId, logLevel) {
if (!statusSysId)
return;
var discoveryLogGr = new GlideRecord('discovery_log');
discoveryLogGr.addQuery('status', statusSysId);
discoveryLogGr.setLimit(1);
if (logLevel == 2) { //check for error
discoveryLogGr.addQuery('level', 2);
discoveryLogGr.query();
if (!discoveryLogGr.next())
return;
if (!discoveryLogGr.message)
return;
var errorMsg = discoveryLogGr.message + '';
var isThisNotPatternErrorMsg = (errorMsg.indexOf('To Check Pattern Log Press') == -1);
return isThisNotPatternErrorMsg ? errorMsg : this._extractHTMLTagsFromPatternErrorMsg(errorMsg);
}
discoveryLogGr.addQuery('level', 0);
discoveryLogGr.addQuery('message', 'CONTAINS', 'To Check Pattern Log Press');
discoveryLogGr.addQuery('source', 'DiscoverySensor');
discoveryLogGr.query();
if (!discoveryLogGr.next())
return;
return this._extractHTMLTagsFromPatternErrorMsg(discoveryLogGr.message + '');
},
_extractHTMLTagsFromPatternErrorMsg: function (errorMessage) {
var regexToRemoveHTMLTags = /(<|\[)(.|\n)*?(>|\])/g;
var message = errorMessage.split(',');
if (message[0] && message[1])
return (message[0].replace(regexToRemoveHTMLTags, "") + " " + message[1].replace(regexToRemoveHTMLTags, ""));
return null;
},
_refreshData: function( accountSysId, patternType, midServer) {
var msg = (patternType === this.SPECIAL_PATTERNS.LDCS_DISCOVERY) ? 'Refresh Datacenters' : 'Refresh Member Accounts' ;
this._debug("_refreshData-> Start -"+ msg , accountSysId);
var SA = this._getAccountGR(String(accountSysId));
var configObj = this._createEmptyConfigObj();
configObj.service_account.sys_id = String(accountSysId);
configObj.service_account.datacenter_type = String(SA.datacenter_type);
configObj.service_account.account_id = String(SA.account_id);
configObj.service_account.is_master_account = SA.getValue("is_master_account");
this.statusId = this._createDiscoveryStatus("Perform "+ msg + " for account-"+configObj.service_account.account_id, this.type);
var probeParams = {};
var probeValues = {"computer": configObj.service_account.sys_id, "ecc_high_priority" : true};
var ppe = this._buildPPE(configObj.service_account.sys_id);
var nextPatternId = this._getPatternId( configObj.service_account.datacenter_type , patternType);
var invocationContext = {};
invocationContext['service_account_id'] = configObj.service_account.account_id;
var midName = midServer ? midServer : this._getAutoMid(configObj.service_account.datacenter_type, JSON.stringify(invocationContext));
if (nextPatternId && probeParams && ppe && probeValues){
this._invokePhase(configObj, nextPatternId, midName, probeParams, probeValues, ppe, msg);
} else {
this._handleError("_refreshData-> Error invocation of next phase missing mandatory parms -", { "configObj": configObj,
"nextPatternId": nextPatternId,
"probeParams": probeParams,
"probeValues": probeValues,
"ppe" : ppe
}, {});
return null;
}
this._debug("_refreshData->Phase end-" + msg , configObj);
return this.statusId;
},
_refreshDataCenter: function(listAccountSysId , patternType, midServer) {
var msg = (patternType === this.SPECIAL_PATTERNS.LDCS_DISCOVERY) ? 'Refresh Datacenters' : 'Refresh Member Accounts' ;
this.statusId = this._createDiscoveryStatus("Perform "+ msg + " for accounts", this.type);
var configObj ={};
for (var item in listAccountSysId){
this._debug("_refreshDataCenter-> Start -"+ msg , String(item) );
var SA = this._getAccountGR(String(item));
configObj = this._createEmptyConfigObj();
configObj.service_account.sys_id = String(item);
configObj.service_account.datacenter_type = String(SA.datacenter_type);
configObj.service_account.account_id = String(SA.account_id);
configObj.service_account.is_master_account = SA.getValue("is_master_account");
var probeParams = {};
var probeValues = {"computer": configObj.service_account.sys_id, "ecc_high_priority" : true };
var ppe = this._buildPPE(configObj.service_account.sys_id);
var nextPatternId = this._getPatternId( configObj.service_account.datacenter_type , patternType);
var invocationContext = {};
invocationContext['service_account_id'] = configObj.service_account.account_id;
var midName = midServer ? midServer : this._getAutoMid(configObj.service_account.datacenter_type, JSON.stringify(invocationContext));
if (nextPatternId && probeParams && ppe && probeValues){
this._invokePhase(configObj, nextPatternId, midName, probeParams, probeValues, ppe, msg+ "-" +configObj.service_account.account_id );
} else {
this._handleError("_refreshDataCenter-> Error invocation of next phase missing mandatory parms -", { "configObj": configObj,
"nextPatternId": nextPatternId,
"probeParams": probeParams,
"probeValues": probeValues,
"ppe" : ppe
}, {});
return null;
}
}
this._debug("_refreshDataCenter->Phase end-" + msg , configObj);
return this.statusId;
},
type: 'CloudWizardDiscovery'
});
Sys ID
4b4c7dd0c75423000a1123622b976351