Name
global.InstanceCloneScheduler
Description
Utility methods for instance clone scheduling
Script
var InstanceCloneScheduler = Class.create();
InstanceCloneScheduler.prototype = {
initialize: function() {
this.clone_server_url = gs.getProperty("glide.db.clone.instance_clone_server");
this.className = "InstanceCloneScheduler";
},
type: 'InstanceCloneScheduler',
buildSOAPRequest: function(soapRequest, cloneGr, action) {
if(gs.nil(cloneGr) || gs.nil(action))
return;
if(gs.nil(soapRequest))
soapRequest = new SOAPMessage('Instance Clone Schedule', 'execute');
var endpoint = this.clone_server_url;
var primaryIP = GlideUtil.isDeveloperInstance() ? "localhost" : GlideHostUtil.getPublicIPAddress();
var standbyInstanceGr = this._getInstanceRecord(cloneGr.getValue('source_instance'));
var targetInstanceGr = this._getInstanceRecord(cloneGr.getValue('target_instance'));
var sourceInstanceId = gs.getProperty('instance_id');
var sourceName = SncCloneUtils.getSourceInstanceName();
var sourceUrl = SncCloneUtils.getSourceInstanceUrl();
soapRequest.setStringParameter('clone_id', cloneGr.getValue('sys_id'));
var password = gs.getProperty('glide.customurl.datacenter.instance.password', null);
soapRequest.setStringParameter('quebecPlus', 'true');
soapRequest.setStringParameter('user', sourceInstanceId);
soapRequest.setStringParameter('password', GlideStringUtil.base64Encode(password));
soapRequest.setStringParameter('source_instance_id', sourceInstanceId);
if(action.equalsIgnoreCase("rollback")) {
soapRequest.setStringParameter('request_for_rollback','true');
soapRequest.setStringParameter('action',cloneGr.getValue('state'));
soapRequest.setStringParameter('telemetry',cloneGr.getValue('telemetry'));
} else if(action.equalsIgnoreCase("cancel")) {
soapRequest.setStringParameter('action',cloneGr.getValue('state'));
soapRequest.setStringParameter('telemetry',cloneGr.getValue('telemetry'));
} else if(action.equalsIgnoreCase("getCloneStatus"))
soapRequest.setStringParameter('request_for_clone_status', 'true');
else if(action.equalsIgnoreCase("schedule")) {
soapRequest.setStringParameter('parent_clone_id', cloneGr.getValue('parent'));
soapRequest.setStringParameter('date', cloneGr.getValue('scheduled') || new GlideDateTime());
soapRequest.setStringParameter('state', cloneGr.getValue('state') || 'Draft');
soapRequest.setStringParameter('cluster_node', this._getSystemId(cloneGr.getValue('cluster_node')));
soapRequest.setStringParameter('user_name', cloneGr.getValue('sys_created_by'));
soapRequest.setStringParameter('user_maint', this._isMaint(cloneGr.getValue('sys_created_by')));
soapRequest.setStringParameter('user_email', cloneGr.getValue('email'));
soapRequest.setStringParameter('security_token', cloneGr.getValue('security_token') || '');
// instance details
soapRequest.setStringParameter('source_instance_name', gs.getProperty('instance_name') || sourceName);
soapRequest.setStringParameter('source_instance_url', sourceUrl);
soapRequest.setStringParameter('target_instance_id', targetInstanceGr.instance_id);
soapRequest.setStringParameter('target_instance_name', targetInstanceGr.instance_name);
soapRequest.setStringParameter('target_instance_url', targetInstanceGr.instance_url);
// version details
soapRequest.setStringParameter('source_version', this._formatVersion(gs.getProperty('glide.war')));
soapRequest.setStringParameter('target_version', this._formatVersion(targetInstanceGr.war_version));
// jdbc details
var primaryParms = GlideDBUtil.getPrimaryDBConfigurationParms();
var sourceJDBCUrl = primaryParms.getURL().replace("localhost", primaryIP);
var sourceDBName = primaryParms.getDatabaseName();
var targetJDBCUrl = targetInstanceGr.database_url.replace("localhost", primaryIP);
var targetDBName = targetInstanceGr.database_name;
var standbyJDBCUrl = standbyInstanceGr == null ? "" : standbyInstanceGr.database_url.replace("localhost", primaryIP);
var standbyDBName = standbyInstanceGr == null ? "" : standbyInstanceGr.database_name;
soapRequest.setStringParameter('source_jdbc_url', sourceJDBCUrl);
soapRequest.setStringParameter('source_db_server', this._formatDBServer(sourceJDBCUrl));
soapRequest.setStringParameter('source_db_name', sourceDBName);
soapRequest.setStringParameter('target_jdbc_url', targetJDBCUrl);
soapRequest.setStringParameter('target_db_server', this._formatDBServer(targetJDBCUrl));
soapRequest.setStringParameter('target_db_name', targetDBName);
soapRequest.setStringParameter('standby_jdbc_url', standbyJDBCUrl);
soapRequest.setStringParameter('standby_db_server', this._formatDBServer(standbyJDBCUrl));
soapRequest.setStringParameter('standby_db_name', standbyDBName);
soapRequest.setStringParameter('validation_error', targetInstanceGr.validation_error);
// timing and metric details
soapRequest.setStringParameter('mb_to_copy', cloneGr.getValue('megabytes_to_copy'));
soapRequest.setStringParameter('mb_copied', cloneGr.getValue('.megabytes_copied'));
soapRequest.setStringParameter('kb_per_second', cloneGr.getValue('kilobytes_per_second'));
soapRequest.setStringParameter('duration', cloneGr.getValue('duration'));
soapRequest.setStringParameter('started', cloneGr.getValue('started'));
soapRequest.setStringParameter('completed', cloneGr.getValue('completed'));
soapRequest.setStringParameter('cancelled', cloneGr.getValue('canceled'));
if(cloneGr.state != 'Draft'){
var telemetry = this._getTelemetryData();
soapRequest.setStringParameter('telemetry', telemetry);
}
//reservation details
soapRequest.setStringParameter('check_for_available_reservation','false');
// clone options
soapRequest.setStringParameter('exclude_tables_specified_in_exclusion_list', cloneGr.getValue('exclude_all_from_exclusion_list'));
soapRequest.setStringParameter('exclude_audit_and_log_data', cloneGr.getValue('exclude_large_data'));
soapRequest.setStringParameter('exclude_large_attachment_data', cloneGr.getValue('filter_attachment_data'));
soapRequest.setStringParameter('preserve_in_progress_update_sets', cloneGr.getValue('preserve_in_progress_update_sets'));
soapRequest.setStringParameter('amount_of_data_copied_from_large_tables', cloneGr.getValue('amount_of_data_copied_from_large_tables'));
soapRequest.setStringParameter('preserve_theme', cloneGr.getValue('preserve_theme'));
soapRequest.setStringParameter('clone_frequency', cloneGr.getValue('clone_frequency'));
soapRequest.setStringParameter('profile', cloneGr.getDisplayValue('profile'));
soapRequest.setStringParameter('lock_clone_config', cloneGr.getValue('lock_profile_settings'));
}
if (endpoint)
soapRequest.setSoapEndPoint(endpoint);
// use custom authorization
soapRequest.setRequestHeader("Authorization", "Clone " + gs.getProperty('instance_id') + ":" + primaryIP);
},
_checkForCloneStateChange: function(cloneRecord, doc) {
var state = this._getText(doc, 'state') + '';
var description = this._getText(doc, 'description') + '';
var oldState = cloneRecord.state;
var stateChanged = !gs.nil(state) && oldState != state;
if ( stateChanged ) {
gs.log("Schedule Server changed state from " + oldState + " to " + state + " (" + description + ")", this.className);
cloneRecord.state = state;
if (state == 'Hold')
cloneRecord.message = description;
}
},
_checkForCloneScheduleChange: function(cloneGr, doc) {
var cloneValidationRules = this._getText(doc,'clone_request_validation_rules')+'';
cloneGr.setValue('clone_request_validation_rules', cloneValidationRules);
var scheduled = cloneGr.scheduled;
if (!gs.nil(this._getText(doc, 'date')))
scheduled = new GlideDateTime(this._getText(doc, 'date')); // GMT
var dateChanged = cloneGr.scheduled.getDisplayValue() != scheduled.getDisplayValue();
if ( dateChanged ) {
var cloneEstimationMessage = this._getText(doc,'clone_estimation_message')+'';
var isReservationAvailableForCloning = this._getText(doc,'is_reservation_available')+'';
cloneGr.setValue("scheduled", scheduled); // GMT
cloneGr.setValue("clone_estimation_message", cloneEstimationMessage);
cloneGr.setValue("is_reservation_available", isReservationAvailableForCloning);
}
},
_updateCloneRespParams: function(cloneRecord, doc) {
var description = this._getText(doc, 'description') + '',
primaryIP = GlideUtil.isDeveloperInstance() ? "localhost" : GlideHostUtil.getPublicIPAddress();
var standbyInstanceGr = this._getInstanceRecord(cloneRecord.source_instance);
var standbyDBName = standbyInstanceGr == null ? "" : standbyInstanceGr.database_name;
var standbyJDBCUrl = standbyInstanceGr == null ? "" : standbyInstanceGr.database_url.replace("localhost", primaryIP);
var cloneType = this._getText(doc, 'clone_type')+'';
var newStandbyJDBCUrl = this._getText(doc, 'standby_jdbc_url')+'';
var newStandbyDBName = this._getText(doc, 'standby_db_name')+'';
var newClusterNode = this._getText(doc, 'cluster_node')+'';
var isCloneTypeChanged = !gs.nil(cloneType) && cloneRecord.clone_type != cloneType;
var standbyChanged = !gs.nil(newStandbyJDBCUrl) && (gs.nil(standbyJDBCUrl) || standbyJDBCUrl != newStandbyJDBCUrl);
var nodeChanged = !gs.nil(newClusterNode) && (gs.nil(cloneRecord.cluster_node) || cloneRecord.cluster_node != newClusterNode);
var oldScheduled = cloneRecord.scheduled;
var oldClusterNode = cloneRecord.cluster_node||'';
if ( nodeChanged && this._setClusterNode(cloneRecord, newClusterNode) )
gs.log("Schedule Server changed cluster node from " + oldClusterNode + " to " + newClusterNode + " (" + description + ")", this.className);
/*if ( standbyChanged && this._setStandbySource(cloneRecord, newStandbyJDBCUrl, newStandbyDBName) )
gs.log("Schedule Server changed standby db from " + standbyJDBCUrl + "." + standbyDBName + " to " + newStandbyJDBCUrl + "." + newStandbyDBName +
" (" + description + ")", this.className);*/
if ( isCloneTypeChanged ) {
gs.log("Clone Type changed from " + cloneRecord.clone_type + " to " + cloneType, this.className);
cloneRecord.setValue("clone_type", cloneType);
}
},
handleSOAPResponse: function(response, cloneGr) {
try {
var doc = new GlideXMLDocument();
doc.parse(response);
gs.log(cloneGr.getValue('clone_id') + " : Schedule Clone Response from server " + doc, this.className);
var isError = this._getText(doc,'isError')+'';
if (isError == 'true') {
this.logCloneMessage(cloneGr, /*error*/2, this._getText(doc, 'description'), '');
cloneGr.setValue('state', 'Error');
cloneGr.setWorkflow(false);//Don't trigger any BR
cloneGr.update();
return;
}
this._checkForCloneScheduleChange(cloneGr, doc);
this._checkForCloneStateChange(cloneGr, doc);
this._updateCloneRespParams(cloneGr, doc);
var cloudDetails = this._getText(doc,'cloud_details')+'';
if(!gs.nil(cloudDetails))
cloneGr.setValue("cloud_details", cloudDetails);
cloneGr.setValue('estimated_clone_duration', this._getText(doc,'estimatedCloneDuration'));
cloneGr.setWorkflow(false);
cloneGr.update();
} catch (e) {
throw e;
}
},
/** Notify instance clone schedule server by calling web service - response might cause the record to be updated */
notifyServer: function(cloneGr) {
var notified = false;
var targetInstanceGr = this._getInstanceRecord(cloneGr.target_instance);
var sourceName = SncCloneUtils.getSourceInstanceName();
// developer installs and localhost: source/target should not contact production url clone.service-now.com
if (this._shouldSkip(sourceName, targetInstanceGr.instance_name))
return notified;
try {
var soapRequest = new SOAPMessage('Instance Clone Schedule', 'execute');
this.buildSOAPRequest(soapRequest, cloneGr, 'schedule');
var response = soapRequest.post();
if (soapRequest.httpStatus != 200)
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.server.confirmation', '');
else {
this.handleSOAPResponse(response, cloneGr);
notified = true;
if(cloneGr.getValue("state") == CloneConstants.status.CLONE_STATUS_REQUESTED)
this.logCloneMessage(cloneGr, /*info*/0, 'clone.log.info.schedule.success', cloneGr.getValue('clone_id'));
}
} catch (e) {
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.schedule.request', e.toString());
}
return notified;
},
logCloneMessage: function(cloneGr, logLevel, msgKey, msgArgs) {
var argsArray = [];
if(gs.nil(cloneGr))
return;
if(!gs.nil(msgArgs))
argsArray.push(msgArgs);
if(!gs.nil(msgKey))
SncCloneLogger.log(this.className, cloneGr.getValue('sys_id'), null, logLevel, gs.getMessage(msgKey, argsArray));
},
// Piggy Back the same service Call with additional paramter for checking Reservation
notifySchedulingServerForCheckingReservation: function(cloneGr) {
var soapRequest = new SOAPMessage('Instance Clone Schedule', 'execute');
soapRequest.setStringParameter('clone_id', cloneGr.getValue('sys_id'));
soapRequest.setStringParameter('date', cloneGr.scheduled || new GlideDateTime());
soapRequest.setStringParameter('check_for_available_reservation','true');
var endpoint = this.clone_server_url;
gs.log("Calling instance clone scheduler server: " + endpoint, this.className);
var primaryIP = GlideUtil.isDeveloperInstance() ? "localhost" :
GlideHostUtil.getPublicIPAddress();
if (endpoint)
soapRequest.setSoapEndPoint(endpoint);
// use custom authorization
soapRequest.setRequestHeader("Authorization", "Clone " +
gs.getProperty('instance_id') + ":" + primaryIP);
var response = soapRequest.post();
if (soapRequest.httpStatus != 200)
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.server.confirmation', '');
else {
var doc = new GlideXMLDocument();
doc.parse(response);
var isReservationAvailableForCloning = this._getText(doc,'is_reservation_available');
var scheduled = new GlideDateTime(this._getText(doc, 'date')); // GMT
var cloneEstimationMessage = this._getText(doc,'clone_estimation_message');
cloneGr.setValue("scheduled", scheduled); // GMT
cloneGr.setValue("clone_estimation_message",cloneEstimationMessage);
cloneGr.setValue("is_reservation_available", isReservationAvailableForCloning);
cloneGr.setWorkflow(false); //Don't trigger any BR
cloneGr.update();
}
},
notifySchedulingServerForCancel: function(cloneGr) {
var schedule = new ScheduleOnce();
schedule.setLabel("Schedule Clone Cancel for " + cloneGr.getValue('clone_id'));
schedule.script = "new InstanceCloneScheduler()._notifyCloneServerForCancelByCloneId('" + cloneGr.getValue('sys_id') + "');";
return schedule.schedule();
},
/** Notify Clone Server for Clone Rollback in case of Backup Based Clones */
notifySchedulingServerForRollback: function(cloneGr){
var schedule = new ScheduleOnce();
schedule.setLabel("Schedule Clone Rollback for " + cloneGr.getValue('clone_id'));
schedule.script = "new InstanceCloneScheduler()._notifyCloneServerForRollbackByCloneId('" + cloneGr.getValue('sys_id') + "');";
return schedule.schedule();
},
/** Notify instance clone schedule server by calling web service - response might cause the record to be updated */
scheduleNotifyServer: function(cloneRecord) {
var schedule = new ScheduleOnce();
schedule.setLabel("Notify instance clone scheduler");
schedule.script = "new InstanceCloneScheduler()._notifyServerByCloneId('" +
cloneRecord.sys_id + "');";
return schedule.schedule();
},
/** Notify instance clone schedule server by calling web service - response might cause the record to be updated */
_notifyServerByCloneId: function(cloneId) {
var cloneRecord = new GlideRecord("clone_instance");
if (cloneRecord.get(cloneId))
this.notifyServer(cloneRecord);
},
checkCloneStatus: function(cloneSysId) {
var cloneGr = new GlideRecord("clone_instance");
if (!cloneGr.get(cloneSysId))
return;
var cloneState = cloneGr.getValue('state');
if(!cloneState.equalsIgnoreCase('Requested'))
return;
var cloneId = cloneGr.getValue('clone_id');
try {
var soapRequest = new SOAPMessage('Instance Clone Schedule', 'execute');
this.buildSOAPRequest(soapRequest, cloneGr, 'getCloneStatus');
var response = soapRequest.post();
if (soapRequest.httpStatus != 200) {
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.status.confirmation', '');
gs.logError(cloneId + ": Error in getting status from server : " + response, this.className);
cloneGr.setValue('state', 'Error');
} else {
var doc = new GlideXMLDocument();
doc.parse(response);
gs.log(cloneId + ": Check Clone Status Response: " + doc, this.className);
cloneState = this._getText(doc, 'state');
if(!gs.nil(cloneState))
cloneGr.setValue('state', cloneState);
this.logCloneMessage(cloneGr, /*info*/0, this._getText(doc, 'description'), '');
}
} catch (e) {
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.status.confirmation', '');
gs.logError(cloneId + ": Error in getting status from server : " + e.toString(), this.className);
cloneGr.setValue('state', 'Error');
}
cloneGr.setWorkflow(false);
cloneGr.update();
},
_notifyCloneServerForCancelByCloneId: function(cloneSysId) {
var cloneGr = new GlideRecord("clone_instance");
if (!cloneGr.get(cloneSysId))
return;
var cloneId = cloneGr.getValue('clone_id');
var soapRequest = new SOAPMessage('Instance Clone Schedule', 'execute');
this.buildSOAPRequest(soapRequest, cloneGr, 'cancel');
var response = soapRequest.post();
if (soapRequest.httpStatus != 200){
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.server.confirmation', '');
gs.logError(cloneId + " : Error in Response from server : " + response, this.className);
} else {
var doc = new GlideXMLDocument();
doc.parse(response);
var isError = this._getText(doc,'isError')+'';
if (isError == 'true') {
this.logCloneMessage(cloneGr, /*error*/2, this._getText(doc, 'description'), '');
return;
}
gs.log(cloneId + " : Cancel Clone Response from server " + doc, this.className);
SncCloneLogger.log(this.className, cloneGr.getValue('sys_id'), null, /*info*/0, this._getText(doc, 'description'));
}
},
_notifyCloneServerForRollbackByCloneId: function(cloneSysId) {
var cloneGr = new GlideRecord("clone_instance");
if (!cloneGr.get(cloneSysId))
return;
var cloneId = cloneGr.getValue('clone_id');
var soapRequest = new SOAPMessage('Instance Clone Schedule', 'execute');
this.buildSOAPRequest(soapRequest, cloneGr, 'rollback');
var response = soapRequest.post();
if (soapRequest.httpStatus != 200){
this.logCloneMessage(cloneGr, /*error*/2, 'clone.log.error.server.confirmation', '');
gs.logError(cloneId + " : Error in Response from server : " + response, this.className);
} else {
var doc = new GlideXMLDocument();
doc.parse(response);
var isError = this._getText(doc,'isError')+'';
if (isError == 'true') {
this.logCloneMessage(cloneGr, /*error*/2, this._getText(doc, 'description'), '');
return;
}
var state = this._getText(doc, 'state')+'';
cloneGr.setValue('state', state);
cloneGr.setWorkflow(false);//Don't trigger any BR
cloneGr.update();
gs.log(cloneId + " : Rollback Clone Response from server " + doc, this.className);
SncCloneLogger.log("InstanceCancelClone", cloneGr.getValue('sys_id'), null, /*info*/0, this._getText(doc, 'description'));
}
},
_isMaint: function(user_id) {
if (gs.hasRole('maint'))
return true;
var gr = new GlideRecord("sys_user");
gr.addQuery("user_name", user_id);
gr.query();
if (gr.next()) {
var user = GlideUser.getUserByID(gr.sys_id);
return user != null ? user.hasRole("maint") : false;
}
return false;
},
_formatVersion: function(version) {
if (gs.nil(version))
return "";
if (version == 'null')
return "";
if (version.length > 4 && version.indexOf('.') > -1)
return version.substring(0, version.length-4);
return version;
},
_formatDBServer: function(jdbcUrl) {
if (gs.nil(jdbcUrl))
return "";
// jdbc:mysql://servername:port/
// jdbc:sqlserver://servername:portnum/
var answer = jdbcUrl;
var idx = answer.indexOf('://');
if (idx > -1) {
answer = answer.substring(idx+3).replace('/', '');
idx = answer.indexOf(':');
if (idx > -1)
answer = answer.substring(0, idx);
}
// jdbc:oracle:thin:@host.com:1521:sidname
idx = jdbcUrl.indexOf(':@');
if (idx > -1) {
answer = answer.substring(idx+2).replace('/', '');
idx = answer.indexOf(':');
if (idx > -1)
answer = answer.substring(0, idx);
}
return answer;
},
_getText: function(doc, tag) {
var el = doc.getElementByTagName(tag);
if (el && el != null)
return el.getTextContent();
return "";
},
_getSystemId: function(clusterStateSysId) {
if (gs.nil(clusterStateSysId))
return "";
var gr = new GlideRecord("sys_cluster_state");
if (gr.get(clusterStateSysId))
return gr.system_id;
return "";
},
_setClusterNode: function(cloneRecord, clusterNode) {
if (gs.nil(clusterNode))
return false;
var gr = new GlideRecord("sys_cluster_state");
gr.addQuery("status", "online"); // only allow change to online nodes
// we can receive cluster node input in three variations
var qc = gr.addQuery("sys_id", clusterNode);
qc.addOrCondition("node_id", clusterNode);
qc.addOrCondition("system_id", clusterNode);
gr.query();
if ( gr.next() && (gs.nil(cloneRecord.cluster_node) ||
cloneRecord.cluster_node != gr.sys_id) ) {
cloneRecord.cluster_node = gr.sys_id;
return true;
}
return false;
},
_getInstanceRecord: function(instanceSysId) {
if (gs.nil(instanceSysId))
return null;
var gr = new GlideRecord('instance');
if (gr.get(instanceSysId) && gr.primary == false) // don't return the primary setup record
return gr;
return null;
},
_setStandbySource: function(cloneRecord, jdbcUrl, dbName) {
if (gs.nil(jdbcUrl) || gs.nil(dbName))
return false;
// First validate db connection
var primaryParms = GlideDBUtil.getPrimaryDBConfigurationParms();
var user = primaryParms.getUser();
var clearPassword = primaryParms.getPassword();
var encryptedPassword = this._encrypt(clearPassword);
var rdbms = primaryParms.getRDBMS();
var tablespace = null;
try {
var instance = new SncCloneInstance(dbName, user, encryptedPassword,
jdbcUrl, rdbms, tablespace);
// verify that the database exists
if (!instance.instanceDatabaseExists()) {
SncCloneLogger.log("InstanceClone", cloneRecord.sys_id,
null,
/*error*/2,
"Source cannot be cloned from: database does not "+
"exist");
return false;
}
// verify that the alternative source can be cloned from
if (!instance.canCloneFrom()) {
SncCloneLogger.log("InstanceClone",
cloneRecord.sys_id, null,
/*error*/2,
"Source cannot be cloned from: instance_id "+
"does not match primary database "+
"(it appears to be a different database)");
return false;
}
} catch(e) {
SncCloneLogger.log("InstanceClone",
cloneRecord.sys_id,
null,
/*error*/2,
"Source cannot be cloned from: unable "+
"to connect to database and verify instance_id: "+
e.toString());
return false;
}
var isNew = false;
var gr = new GlideRecord("instance");
gr.addQuery("source", true);
gr.addQuery("primary", false);
gr.query();
if (!gr.next()) {
isNew = true;
gr.initialize();
gr.setValue("source", true);
gr.setValue("primary", false);
}
gr.database_url = jdbcUrl;
gr.database_name = dbName;
gr.database_tablespace = tablespace;
gr.database_type = rdbms;
gr.database_user = user;
gr.database_password = encryptedPassword;
gr.instance_id = gs.getProperty("instance_id")+"";
if (gs.nil(gr.instance_name))
gr.instance_name = "Standby Database";
if (gs.nil(gr.instance_url))
gr.instance_url = gs.getProperty("glide.servlet.uri")+"";
gr.production = gs.getProperty("glide.installation.production");
gr.war_version = gs.getProperty("glide.war")+"";
if (isNew)
gr.insert();
else
gr.update();
cloneRecord.source_instance = gr.sys_id;
return true;
},
/* developer installs and localhost: source/target should not contact production url clone.service-now.com */
_shouldSkip: function(sourceName, targetName) {
var answer = false;
var url = this.clone_server_url; // eg https://clone.service-now.com/InstanceCloneSchedule.do?SOAP
if (gs.nil(url))
return answer;
var productionUrl = "https://clone.service-now.com/";
var isDeveloper = GlideUtil.isDeveloperInstance() &&
!GlideUtil.isProductionInstance();
var isLocalHost = sourceName.indexOf("localhost") > -1 ||
targetName.indexOf("localhost") > -1;
// if we're trying to contact the production url and we're a local installation, do not pass go
if (url.indexOf(productionUrl) > -1 && (isDeveloper || isLocalHost)) {
answer = true;
gs.print("InstanceCloneScheduler - this is a developer "+
"or localhost instance, production scheduling service is not "+
"supported: to resolve, change property "+
"glide.db.clone_server_url");
}
return answer;
},
_getTelemetryData: function(){
var gr = new GlideRecord("clone_instance");
gr.orderByDesc('sys_created_on');
//Each clone request sends three SOAP requests with states - Draft,Draft,Requested
gr.setLimit(3);
gr.query();
var telemetry = {};
while (gr.next()) {
// security_token value is null for first Draft request in which we store the telemetry data
if (!gr.getValue('security_token')) {
telemetry = gr.getValue('telemetry');
}
}
return telemetry;
},
_encrypt: function(unencryptedString) {
if (gs.nil(unencryptedString))
return "";
var encryptor = new GlideEncrypter();
return encryptor.encrypt(unencryptedString);
}
};
Sys ID
9141db8e1b10200081599e3bcc07135b