var DiscoveryFunctions = Class.create();
(function() {
var relTypes = { };
DiscoveryFunctions.prototype = {
initialize: function() {
},
getDiscoverySource: function() {
var gr = new GlideRecord("sys_properties");
if(gr.get("name", "glide.discovery.source_name"))
return gr.getValue('value');
return "";
},
getScheduleRecord: function() {
var statusGR = this.getStatusRecord();
if (!statusGR)
return;
var gr = new GlideRecord('discovery_schedule');
if (statusGR.dscheduler)
gr.get('sys_id', statusGR.dscheduler);
return gr;
},
getStatusRecord: function() {
var statusSysId = g_probe.getCorrelator();
if (gs.nil(statusSysId)) {
if (typeof agent_correlator != 'string' && agent_correlator)
statusSysId = agent_correlator;
else if (current) {
if (current.agent_correlator)
statusSysId = current.agent_correlator;
else if (current.getTableName() == "discovery_status")
return current;
}
}
if (!statusSysId)
return null;
var gr = new GlideRecord('discovery_status');
if (statusSysId)
gr.get('sys_id', statusSysId);
return gr;
},
getDiscoveryType: function(statusID) {
var statusGR = new GlideRecord('discovery_status');
statusGR.get(statusID);
var schedGR = new GlideRecord('discovery_schedule');
schedGR.get(statusGR.dscheduler);
return schedGR.discover;
},
getService: function(port) {
var gr = new GlideRecord("cmdb_ip_service");
if (!gr.get("port", port)) {
gr.initialize();
gr.setValue("port", port);
gr.setValue("name", "unknown - port(" + port + ")");
gr.insert();
}
return gr;
},
isInRange: function(ip) {
var gr = this.getStatusRecord();
if (gr != null) {
var hostList = gr.scratchpad.host_list;
if (hostList) {
var hosts = StringUtil.split(hostList, ",");
if (hosts.contains(ip))
return true;
}
return SncDiscoveryRangesDB.inRanges(ip, gr.dscheduler);
}
return false;
},
getXMLMemoryTable: function(tableName, doc, path) {
var result = null;
try {
result = GlidesoftXMLMemoryTable.getFromDocAndXPath(tableName, doc, path);
} catch (iae) {
// do nothing; we'll return a null...
}
return result;
},
getFieldsThatChanged: function(gr) {
var changes = [];
if (gr == null || !gr.isValid())
return changes;
var gru = GlideScriptRecordUtil.get(gr);
var ignoreables = new Packages.java.util.ArrayList();
ignoreables.add("last_discovered");
var whatChanged = gru.getChangedFields(ignoreables);
for (var i = 0; i < whatChanged.size(); i++) {
var f = whatChanged.get(i);
changes.push(f);
}
return changes;
},
updatedHistory: function(gr, sensor, eccID) {
var fieldsChanged = this.getFieldsThatChanged(gr);
if (fieldsChanged.length > 0)
g_device.log("Updated device fields " + fieldsChanged.join(", "), sensor, eccID);
},
/*
* Return the sys_id of the relationship created. Otherwise return null or undefined.
*/
createRelationshipFromSysIds: function(parentId, childId, pDescription, cDescription) {
if (JSUtil.nil(parentId) || JSUtil.nil(childId))
return;
if (!this.validCISysId(parentId) || !this.validCISysId(childId)) {
return;
}
if (!cDescription && pDescription.indexOf("::") > -1) {
var parts = pDescription.split("::");
pDescription = parts[0];
cDescription = parts[1];
}
var ECMDBUtil = SncECMDBUtil;
return ECMDBUtil.createCIRelationship('cmdb_rel_ci', parentId, childId, pDescription, cDescription);
},
// Validate sysid
validCISysId: function(sysID) {
// Case 1: Check for null sys id
if (gs.nil(sysID)) {
gs.log('Invalid Rel CI Record :: Null SysID');
return false;
}
//extracting only alphanumeric and comparing 32 chars
if (sysID.match(/[0-9a-f]{32}/) == sysID) {
return true;
} else {
// Case 3:SysID is not null
// but it is not a valid sysID by its strig format [Alphanumeric and exactly 32 chars]
gs.log('Invalid Rel CI Record :: Invalid SysID(Regex only) :SysID ' + sysID);
return false;
}
},
//
// Args: parent <pDescription> child / child <cDescription> parent
// Example: vmware Runs on sanops / sanops Runs vmware
// parent, child input can either be GlideRecord or sys_id
//
createRelationship: function(parent, child, pDescription, cDescription) {
if (JSUtil.nil(parent) || JSUtil.nil(child))
return;
var parentId = parent;
var childId = child;
//If parent or child is a GlideRecord object, we need to extract the sys_id
if (parent instanceof GlideRecord)
parentId = parent.sys_id;
if (child instanceof GlideRecord)
childId = child.sys_id;
return this.createRelationshipFromSysIds(parentId, childId, pDescription, cDescription);
},
/*
* Return the sys_id of the relationship if found or created. Otherwise return null or undefined.
*/
createRelationshipIfNotExists: function(parent, child, descriptor, ensureUnique) {
var result = this.relationshipExists(parent, child, descriptor);
if (JSUtil.notNil(result))
return result;
var createdRelationship = this.createRelationship(parent, child, descriptor);
//checking unique for the newly created relationship
if (ensureUnique)
this.deleteRelationshipIfMultipleExists(parent, child, descriptor);
return createdRelationship;
},
/*
* Checks to see if a relationship already exists
*/
relationshipExists: function(parent, child, descriptor) {
if (JSUtil.nil(parent) || JSUtil.nil(child) || JSUtil.nil(descriptor))
return;
var parentId = parent;
var childId = child;
//If parent or child is a GlideRecord object, we need to extract the sys_id
if (parent instanceof GlideRecord)
parentId = parent.sys_id;
if (child instanceof GlideRecord)
childId = child.sys_id;
var relationType = this.findCIRelationshipType("cmdb_rel_type", descriptor);
var gr = new GlideRecord("cmdb_rel_ci");
gr.addQuery("parent", parentId);
gr.addQuery("child", childId);
gr.addQuery("type", relationType);
gr.query();
if (gr.next())
return gr;
return;
},
/*
* Deleted duplicate relationship from cmdb_rel_ci
*/
deleteRelationshipIfMultipleExists: function (parent, child, relTypeName) {
var gr = new GlideRecord('cmdb_rel_ci');
var relTypeId = this.findCIRelationshipType('cmdb_rel_type', relTypeName);
gr.addQuery('parent', parent);
gr.addQuery('child', child);
gr.addQuery('type', relTypeId);
gr.orderBy('sys_id');
gr.query();
if (gr.getRowCount() > 1) {
gs.info('Duplicate relationship %% ' + relTypeName + ' exists between the parent ' + parent + ' and child ' + child);
// Don't allow exact duplicates. We'll keep the one with the lowest sys_id
// to avoid a race condition where two threads insert a record at the same
// time and both decide to delete it.
gr.next();
// Delete duplicate record
while (gr.next()) {
gr.deleteRecord();
gs.info('Deleted Duplicate relationship %% ' + relTypeName + ' between the parent ' + parent + ' and child ' + child);
}
}
},
/**
* get a child of this parent of type matched by the descriptor
*
* Descriptor is of form <Parent Relationship>::<Child Relationship>
* so, for example calling this method on a web server with descriptor "RunsOn::Runs"
* returns the computer it runs on. Thus, web server is the parent and computer is the child
*/
getChildCI: function(parent, descriptor) {
var gr = new GlideRecord("cmdb_rel_ci");
gr.addQuery("parent", parent.sys_id);
if (descriptor) {
var relationType = this.findCIRelationshipType("cmdb_rel_type", descriptor);
if (relationType)
gr.addQuery("type", relationType);
}
gr.query();
if (gr.next()) {
var cigr = new GlideRecord("cmdb_ci");
if (gr.child && cigr.get('sys_id', gr.child)) {
return cigr;
}
}
return null;
},
reclassify: function(gr, newClassName, reason) {
// we are already that class, just return
if (gr.sys_class_name == newClassName)
return gr;
var rci = SncReclassifyCI.createFromGlideRecord(gr, newClassName);
rci.setApplyDefaults(false);
rci.setReason(reason);
return rci.reclassify();
},
deleteCIBySysId: function(sysId, workflow) {
var gr = new GlideRecord("cmdb_ci");
if (!sysId || !gr.get('sys_id', sysId))
return;
this.deleteCI(gr, workflow);
},
deleteCI: function(gr, workflow) {
var al = [];
al.push(gr.getValue("sys_id"));
//Check to see if it matches these two criteria
if (!(gr.instanceOf("cmdb_ci_computer") || gr.instanceOf("cmdb_ci_appl"))) {
gr.deleteRecord();
return;
}
if (workflow && workflow != "false") {
this.deleteCIAndRelationshipsRecursive(al);
return;
}
try {
var oldWorkflow = session.getWorkflow();
this.deleteCIAndRelationshipsRecursive(al);
} finally {
session.setWorkflow(oldWorkflow);
}
},
/*
* This is where the heavy lifting of traversing through the relationship tree is done
* We only traverse through the relatinoships that have RUNS_ON and HOSTED_ON relationships at this point
*
* We basically look for all the parent CIs that runs on or is hosted on the child CI(s) and delete them.
*/
deleteCIAndRelationshipsRecursive: function(appList) {
if (appList.length == 0)
return appList;
var appListNew = [];
var tempSysId;
var sysID;
for (var i = 0; i < appList.length; i++) {
sysID = appList[i];
var gr = new GlideRecord("cmdb_rel_ci");
gr.addQuery("child", sysID);
var qc = gr.addQuery("type", this.findCIRelationshipType("cmdb_rel_type", "Runs on::Runs"));
qc.addOrCondition("type", this.findCIRelationshipType("cmdb_rel_type", "Hosted on::Hosts"));
gr.query();
while (gr.next()) {
tempSysId = gr.getValue("parent");
//Check to see if same CI could runs-on or be hosted on same child (maybe possible?)
if (!contains(appListNew, tempSysId))
appListNew.push(tempSysId);
gr.deleteRecord(); //delete the relationship entry
}
var cigr = new GlideRecord("cmdb_ci");
if (sysID && cigr.get('sys_id', sysID))
cigr.deleteRecord();
}
return this.deleteCIAndRelationshipsRecursive(appListNew);
function contains(arr, value) {
for (var i=0; i<arr.length; i++)
if (arr[i] == value)
return true;
return false;
}
},
findOrCreateRelationshipType: function(refTable, descriptor) {
var result = this.findCIRelationshipType(refTable, descriptor);
if (JSUtil.notNil(result))
return result;
var al = descriptor.split("::");
var gr = new GlideRecord(refTable);
gr.parent_descriptor = al[0];
gr.child_descriptor = al[1];
return gr.insert();
},
findCIRelationshipType: function(refTable, descriptor) {
// refTable should be an optional parameter (because we always pass the
// same value). I can't change the function signature, so this is the
// only way to make it optional.
if (!descriptor)
return this.findCIRelationshipTypeByDesc('cmdb_rel_type', refTable);
return this.findCIRelationshipTypeByDesc(refTable, descriptor);
},
findCIRelationshipTypeByDesc: function(refTable, pDescriptor, cDescriptor) {
var descriptor = pDescriptor;
if (cDescriptor)
descriptor += '::' + cDescriptor;
relTypes[descriptor] = relTypes[descriptor] || getRelType();
return relTypes[descriptor];
function getRelType() {
if (pDescriptor && !cDescriptor) {
pDescriptor = pDescriptor.split('::');
cDescriptor = pDescriptor[1];
pDescriptor = pDescriptor[0];
}
var gr = new GlideRecord(refTable);
gr.addQuery("parent_descriptor", pDescriptor);
gr.addQuery("child_descriptor", cDescriptor);
gr.query();
if (gr.next())
return '' + gr.getValue("sys_id");
return "";
}
},
/* Manage the PIDs creation and update */
insertPIDs: function(pids, app_sys_id, ci_sys_id) {
if (StringUtil.nil(pids))
return;
var pid_array = pids.match(/\d+/g);
var gr = new GlideRecord("cmdb_pid");
gr.initialize();
for (var i=0; i<pid_array.length; i++) {
gr.pid = pid_array[i];
gr.application = app_sys_id;
gr.cmdb_ci = ci_sys_id;
gr.insert();
}
},
updatePIDs: function(pids, app_sys_id, ci_sys_id) {
if (StringUtil.nil(pids))
return;
var gr = new GlideRecord("cmdb_pid");
gr.addQuery("application", app_sys_id);
gr.query();
gr.deleteMultiple();
this.insertPIDs(pids, app_sys_id, ci_sys_id);
},
/**********************************************
* Manage the Windows installed software xml
*
* Example payload:
* <results probe_time="6313">
* <result>
* <Registry>
* <entry key="HKEY_LOCAL_MACHINE">
* <entry key="Software">
* <entry key="Microsoft">
* <entry key="Windows">
* <entry key="Name">
* <value>Just a name</value>
* </entry>
* </entry>
* </entry>
* </entry>
* </entry>
* </Registry>
* </entry>
* </results>
*
* // To find the value of the key called "name", here's how these methods can be used.
* // registry is a variable representing the payload
* var node = findRegistryNode(registry, "HKEY_LOCAL_MACHINE.Software.Microsoft");
* var name = findNodeValueWithAttribute(node, "Name");
*********************************************/
findRegistryNode: function(currNode, regName){
var node = currNode;
var names = regName.split(".");
for (var i=0; i<names.length; i++) {
node = this.findNodeWithAttribute(node, names[i]);
if (!node)
return null;
}
return node;
},
findNodeWithAttribute: function(currNode, attrName) {
if (JSUtil.nil(currNode))
return "";
var nodeArray = g_array_util.ensureArray(currNode.entry);
for (var i=0; i<nodeArray.length; i++)
if (nodeArray[i]['@key'] == attrName)
return nodeArray[i];
return null;
},
findNodeValueWithAttribute: function(currNode, attrName) {
if (JSUtil.nil(currNode))
return "";
var nodeArray = g_array_util.ensureArray(currNode.entry);
for (var i=0; i<nodeArray.length; i++)
if (nodeArray[i]['@key'] == attrName)
return nodeArray[i].value;
return "";
},
type: "DiscoveryFunctions"
};
}());
No comments:
Post a Comment