Name
global.CSDMCMDBUtil
Description
Generic utilities for CSDM specific interactions with CMDB
Script
var CSDMCMDBUtil = Class.create();
CSDMCMDBUtil.prototype = {
initialize: function() {
},
getDynamicCIGroupsFromTSO: function (TSOSysId) {
var groups = [];
if(!this.isTechnicalService(TSOSysId))
return groups;
var grRel = new GlideRecord('cmdb_rel_ci');
grRel.addEncodedQuery('parent.sys_class_name=service_offering^child.sys_class_name=cmdb_ci_query_based_service^parent=' + TSOSysId);
grRel.query();
while (grRel.next()) {
if (this.isTechnicalService(grRel.getValue('child')))
groups.push(grRel.getValue('child'));
}
return groups;
},
// Dynamic ci groups are mapped to their associated technical service offering
// Mapping is one to many
getAssocTSOsFromDCG : function (dcgIds) {
var grRel = new GlideRecord("cmdb_rel_ci");
grRel.addQuery("child", "IN", dcgIds);
grRel.addQuery("parent.sys_class_name", "service_offering");
grRel.query();
var groupsMappedToTso = {};
while (grRel.next()) {
var serviceId = grRel.getValue("parent");
if (!groupsMappedToTso[serviceId]) {
groupsMappedToTso[serviceId] = [];
}
groupsMappedToTso[serviceId].push(grRel.getValue("child"));
}
return groupsMappedToTso;
},
// Gets a gliderecord of technical service offerings, sorting by create date from most recent created to last
getTSOs : function (tsoIds) {
var grTso = new GlideRecord("service_offering");
grTso.addQuery("service_classification", "Technical Service");
grTso.addQuery("sys_id", "IN", tsoIds);
grTso.orderByDesc("sys_created_on");
grTso.query();
return grTso;
},
getCIsFromDCG: function(dcgSysIds) {
var cis = {};
var ciArr = [];
if (JSUtil.nil(dcgSysIds))
return cis;
var grAssoc = new GlideRecord('svc_ci_assoc');
grAssoc.addQuery('service_id','IN', dcgSysIds);
grAssoc.addQuery("service_id.service_classification", "Technical Service");
grAssoc.query();
while(grAssoc.next()) {
ciArr.push(grAssoc.getValue('ci_id'));
}
var grCiCmdb = new GlideRecord("cmdb_ci");
grCiCmdb.addQuery('sys_id', 'IN', ciArr);
grCiCmdb.query();
while (grCiCmdb.next()) {
var className = grCiCmdb.getValue("sys_class_name");
if (!cis[className]) {
cis[className] = [];
}
cis[className].push(grCiCmdb.getValue('sys_id'));
}
return cis;
},
// Queries for associated dynamic CI groups given a list of CIs and returns an object
// such that each DCG -> array of associated CIs
getCisMappedToDCG : function (ciSysIds) {
if (JSUtil.nil(ciSysIds))
return {};
var grAssoc = new GlideRecord("svc_ci_assoc");
grAssoc.addQuery("ci_id","IN", ciSysIds);
grAssoc.addQuery("service_id.service_classification", "Technical Service");
grAssoc.query();
var cisMappedToGroup = {};
while(grAssoc.next()) {
var dcgId = grAssoc.getValue("service_id");
if (!cisMappedToGroup[dcgId]) {
cisMappedToGroup[dcgId] = [];
}
cisMappedToGroup[dcgId].push(grAssoc.getValue("ci_id"));
}
return cisMappedToGroup;
},
// Updates a list of sysIds using an updates object containing the column -> value mapping
updateRecords: function(tableName, sysIds, updates) {
if(JSUtil.nil(sysIds) || JSUtil.nil(updates) || Object.keys(updates).length == 0 || JSUtil.nil(tableName))
return;
var gr = new GlideRecord(tableName);
gr.addQuery('sys_id', 'IN', sysIds);
gr.query();
for(var columnName in updates) {
if (updates.hasOwnProperty(columnName) && GlideTableDescriptor.fieldExists(tableName, columnName))
gr.setValue(columnName, JSUtil.nil(updates[columnName])? 'NULL' : updates[columnName]);
}
gr.updateMultiple();
},
// service_classification is at cmdb_ci_service level so it would be generic function
// that works for all classes inherited from cmdb_ci_service
isTechnicalService: function(sysId) {
var grTech = new GlideRecord('cmdb_ci_service');
return (grTech.get(sysId) && grTech.getValue('service_classification') == 'Technical Service');
},
isDynamicCiGroup: function(sysId) {
var grDcg = new GlideRecord('cmdb_ci_query_based_service');
return grDcg.get(sysId) && grDcg.getValue('service_classification') == 'Technical Service';
},
// Gets CIs for a specific class and ignores inherited CIs
getCisForClass : function(className) {
var ciRecords = new GlideRecord(className);
ciRecords.addQuery("sys_class_name", className);
ciRecords.query();
if (ciRecords.getRowCount() == 0) {
// The CI Class has no individual CIs
return {};
}
var ciSysIds = {};
while (ciRecords.next()) {
ciSysIds[ciRecords.getValue("sys_id")] = "";
}
return ciSysIds;
},
// expects a map of ciClass to many ci sys_ids, optional second parameter is a managed_by_group value to apply to all cis
revertMBGToClassValueOrNull : function(cis, tsoMbgValue) {
var newMbgValue = "NULL";
if (!Object.keys(cis) || Object.keys(cis).length == 0)
return;
Object.keys(cis).forEach(function (ciClass) {
if (!new TableUtils(ciClass).tableExists())
return;
var grUpdate = new GlideRecord(ciClass);
grUpdate.addQuery("sys_id", "IN", cis[ciClass]);
grUpdate.query();
if (!tsoMbgValue || tsoMbgValue === "NULL") {
var grCci = new GlideRecord("cmdb_class_info");
grCci.addQuery("class", ciClass);
grCci.query();
if (grCci.next() && grCci.getValue("managed_by_group")) {
// set managed by group to the cmdb class info value
newMbgValue = grCci.getValue("managed_by_group");
}
} else {
newMbgValue = tsoMbgValue;
}
grUpdate.setValue("managed_by_group", newMbgValue);
gs.log("Reverting Managed by group to " + newMbgValue + " for " + cis[ciClass].length + " CIs from class " + ciClass, "CSDMCMDBUtil");
grUpdate.updateMultiple();
});
},
// expects a dynamic ci group sys_id
updateOnTsoRelDelete : function(dcgString) {
var startTime = new GlideTime();
if (!dcgString || dcgString.length == 0)
return;
// revert DCG back to another TSOs values if still has a relationship or null if not
var tsoMbgValue;
var groupTsoMap = this.getAssocTSOsFromDCG(dcgString);
if (Object.keys(groupTsoMap).length > 0) {
var soArray = [];
Object.keys(groupTsoMap).forEach(function (serviceOffering) {
soArray.push(serviceOffering);
});
var tsos = this.getTSOs(soArray);
while (tsos.next()) {
if (tsos.getValue("managed_by_group")) {
// the most recently created technical service offering with a relationship to this dcg has a managed by group value
tsoMbgValue = tsos.getValue("managed_by_group");
break;
}
}
}
// update the dcg to the new mbg value from another tso or set to empty
var grDcg = new GlideRecord("cmdb_ci_query_based_service");
if (!grDcg.get(dcgString))
return;
grDcg.setValue("managed_by_group", tsoMbgValue ? tsoMbgValue : "NULL");
grDcg.update();
gs.log("Updated Dynamic CI group with Managed by group: " + grDcg.getValue("managed_by_group"), "CSDMCMDBUtil");
// get the CIs from the DCG and revert mbg to class manager or to new tso value
cis = this.getCIsFromDCG(dcgString);
this.revertMBGToClassValueOrNull(cis, tsoMbgValue);
var dur = GlideDate.subtract(startTime, new GlideTime());
gs.log("Completed reverting Managed by group values for CIs in " + dur.getDurationValue(), "CSDMCMDBUtil");
},
// reverts a string comma separated list of CIs to MBG values. Optional "::" is used to pass a dcg sys id to exclude from searches
updateCiOnAssocDelete : function(ciSysIds) {
var startTime = new GlideTime();
if (!ciSysIds || ciSysIds.length == 0)
return;
var dcgToExclude;
var ciSysIdArr;
if (ciSysIds.indexOf("::") > 0) {
var temp = ciSysIds.split("::");
ciSysIdArr = temp[0].split(",");
dcgToExclude = temp[1];
} else {
ciSysIdArr = ciSysIds.split(",");
}
// check if ci is still associated to another dcg
var grAssoc = new GlideRecord("svc_ci_assoc");
grAssoc.addQuery("ci_id", "IN", ciSysIdArr);
grAssoc.addQuery("service_id.service_classification", "Technical Service");
grAssoc.addQuery("service_id.sys_class_name", "cmdb_ci_query_based_service");
if (dcgToExclude) {
grAssoc.addQuery("service_id", "!=", dcgToExclude);
}
grAssoc.query();
var dcgs = {};
while (grAssoc.next()) {
if (!dcgs[grAssoc.getValue("service_id")]) {
dcgs[grAssoc.getValue("service_id")] = [];
}
dcgs[grAssoc.getValue("service_id")].push(grAssoc.getValue("ci_id"));
ciSysIdArr = ciSysIdArr.filter(function (sysId) {
return sysId != grAssoc.getValue("ci_id");
});
}
// check to see if a TSO has a MBG value
if (Object.keys(dcgs).length > 0) {
Object.keys(dcgs).forEach(function(dcg) {
var sos = this.getAssocTSOsFromDCG([dcg]);
if (Object.keys(sos).length > 0) {
var grTso = this.getTSOs(Object.keys(sos));
while (grTso.next()) {
if (grTso.getValue("managed_by_group")) {
this.revertMBGToClassValueOrNull(dcgs[dcg], grTso.getValue("managed_by_group"));
delete dcgs[dcg];
break;
}
}
}
});
}
// combine all CIs not reverted to a TSO value
Object.keys(dcgs).forEach(function(dcg) {
ciSysIdArr = ciSysIdArr.concat(dcgs[dcg]);
});
// get all classes associated with the CIs
var grCiCmdb = new GlideRecord("cmdb_ci");
var cisAndClass = {};
grCiCmdb.addQuery('sys_id', 'IN', ciSysIdArr);
grCiCmdb.query();
while (grCiCmdb.next()) {
var className = grCiCmdb.getValue("sys_class_name");
if (!cisAndClass[className]) {
cisAndClass[className] = [];
}
cisAndClass[className].push(grCiCmdb.getValue('sys_id'));
}
this.revertMBGToClassValueOrNull(cisAndClass);
var dur = GlideDate.subtract(startTime, new GlideTime());
gs.log("Completed reverting Managed by group values for CIs in " + dur.getDurationValue(), "CSDMCMDBUtil");
},
type: 'CSDMCMDBUtil'
};
Sys ID
1bafe8897382101061b79c0c6df6a738