- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
on 08-01-2022 10:17 PM
Recently, we had the requirement to create the default CSDM Lifecycle mappings for all CI classes. There are more than 713 OOTB CI classes on fresh PDI. Which means there is no way we would do it manually, so we did create this fix script. The Script creates the mapping (same as the parent table) based on existing or default (OOTB) mappings. In order to create the mappings for all the child classes you need to provide the base class name. E.g. providing "cmdb_ci" as base class will create the mappings for all CMDB classes of it, if not already exist. This can be further optimized, but I preferred to post it as is. Any suggestions or improvements are welcomed, We rely on your feedback.
(NOTE: if your instance have custom choices create the mappings for them manually for base class, prior to running this script)
//To get an existing mappings
var grLCM = new GlideAggregate("life_cycle_mapping");
grLCM.groupBy("table");
grLCM.addAggregate("COUNT");
grLCM.query();
var existingMappedRecords = [];
while (grLCM.next()) {
existingMappedRecords.push(grLCM.getDisplayValue("table"));
}
//Provide the BASE_CLASS_NAME as parameter here
var table = new TableUtils("cmdb_ci");
// var table = new TableUtils("ast_contract");
// var table = new TableUtils("alm_asset");
// var table = new TableUtils("cmdb_model");
var ciTables = table.getAllExtensions();
gs.include("j2js");
var ciTablesArr = j2js(ciTables);
for (var i = 0; i < ciTablesArr.length; i++) {
if (existingMappedRecords.indexOf(String(ciTablesArr[i])) === -1) {
//CI classes not having mappings - Get closest parent class having mappings
var parentMapClass = getMappingsClassParent(ciTablesArr[i]);
//Apply Parent mappings to child class
setMappings(ciTablesArr[i], parentMapClass);
}
}
//Script for Mappings
function setMappings(childToApplyMap, parentToFetchMap) {
//Get parent mappings
try {
var rParentMap = new sn_ws.RESTMessageV2();
rParentMap.setEndpoint('https://' + gs.getProperty('instance_name') + '.service-now.com/api/now/table/life_cycle_mapping?sysparm_query=active%3Dtrue%5Etable%3D' + String(parentToFetchMap) + '&sysparm_display_value=false&sysparm_exclude_reference_link=true&sysparm_fields=active%2Clegacy_field_name%2Clegacy_field_value%2Clegacy_field_and_value%2Clegacy_subfield_name%2Clegacy_subfield_value%2Clegacy_subfield_and_value%2Clife_cycle_control%2Cpriority%2Clegacy_field_and_value%2Clegacy_subfield_and_value');
rParentMap.setHttpMethod('GET');
//Eg. UserName="admin", Password="admin" for this code sample.
var user = 'admin';
var password = 'admin_password';
rParentMap.setBasicAuth(user, password);
rParentMap.setRequestHeader("Accept", "application/json");
var responseParentMap = rParentMap.execute();
var httpParentMapStatus = responseParentMap.getStatusCode();
if (httpParentMapStatus === 200) {
var responseParentMapBody = responseParentMap.getBody();
var parentMapObjResult = JSON.parse(responseParentMapBody);
var parentMapObj = parentMapObjResult['result'];
//set child mappings
parentMapObj.forEach(function(singleObjParent) {
singleObjParent["table"] = String(childToApplyMap);
try {
var grLCMCreate = new GlideRecord("life_cycle_mapping");
grLCMCreate.newRecord();
grLCMCreate.setValue('legacy_field_name', singleObjParent["legacy_field_name"]);
grLCMCreate.setValue('legacy_field_value', singleObjParent["legacy_field_value"]);
grLCMCreate.setValue('legacy_field_and_value', singleObjParent["legacy_field_and_value"]);
if (singleObjParent.hasOwnProperty('legacy_subfield_name')) {
grLCMCreate.setValue('legacy_subfield_name', singleObjParent["legacy_subfield_name"]);
grLCMCreate.setValue('legacy_subfield_value', singleObjParent["legacy_subfield_value"]);
grLCMCreate.setValue('legacy_subfield_and_value', singleObjParent["legacy_subfield_and_value"]);
}
grLCMCreate.setValue('active', 'true');
grLCMCreate.setValue('life_cycle_control', singleObjParent["life_cycle_control"]);
grLCMCreate.setValue('priority', singleObjParent["priority"]);
grLCMCreate.setValue('table', String(childToApplyMap));
grLCMCreate.update();
} catch (err) {
gs.info("Error while creating child map for table: " + String(childToApplyMap) + " -> " + err.message);
}
});
}
} catch (e) {
gs.info("Error while fetching parent map for table: " + String(parentToFetchMap) + " -> " + e.message);
}
}
//to remove empty keys from object
function replacer(key, value) {
if (value === "") {
return undefined;
}
return value;
}
function getMappingsClassParent(orginalCIClass) {
// Get the hierarchy of tables
var tableParent = new TableUtils(orginalCIClass);
var tableParentArrayList = tableParent.getTables();
var tableParentArray = j2js(tableParentArrayList);
var j = 1;
while (j < tableParentArray.length) {
//Check if parrent have mappings & if yes, return parent class
var grCheckLCMofParent = new GlideAggregate("life_cycle_mapping");
grCheckLCMofParent.addEncodedQuery("table=" + String(tableParentArray[j]));
grCheckLCMofParent.addAggregate("COUNT");
grCheckLCMofParent.query();
var cnt = 0;
if (grCheckLCMofParent.next()) {
cnt = grCheckLCMofParent.getAggregate("COUNT");
}
if (cnt > 0) {
return String(tableParentArray[j]);
}
j++;
}
}
- 1,224 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Hi
good idea!
some hints, thoughts & questions of mine:
- Why do need an REST API request to just query table life_cycle_mapping? Makes no sense to me.
- In case method "getMappingsClassParent" cannot find anything it returns nothing which is not handled properly in the calling method. This can cause exceptions and unexpected behavior.
- At method "getMappingsClassParent" why do you need an GlideAggregate for just checking whether your query has at least one record?
Better approach (inklusive "null" returned value in case nothing is found)
var grCheckLCMofParent = new GlideRecord("life_cycle_mapping"); grCheckLCMofParent.addEncodedQuery("table=" + String(tableParentArray[j])); grCheckLCMofParent.setLimit(1); grCheckLCMofParent.query(); return grCheckLCMofParent.next() ? String(tableParentArray[j]) : null;
Maik
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content