CI Verification - Merge CIs

A Westervelt
Mega Guru

We have an issue with "duplicate" CIs in our CMDB due to our integration point with Netcool event monitoring. We have rules set up that during the Incident creation, it will attempt to match the alerted device to our CMDB populated by Discovery. Failing to due so, it will create a new CI in the default cmdb_ci table with only the device name.

One our issues is that on occasion, Netcool will generate a ticket on a device before Discovery auto-creates it for us. All of a sudden, I now have two CIs in different tables. Incident and Change (because support groups see the name and think "Oh, that's what I wanted" without looking at the Class or Duplicate status) tracking by CI record begins to break down and chaos ensues. Well, maybe not that bad, but I just hate dirty data when I know it can be fixed.

After too much exposition, here's the meat of the situation: how can I leverage the existing CI Verification and Merge CI action to combine my temporary Netcool CI into my good Discovery CI while keeping the integrity of the CIs Affected (task_ci) table. Testing is showing (Eureka Patch 11) that I can consolidate the record by laying the good one on top of the other, but it kills off all related lists. Is there a way I can modify the action to directly merge the two together specifically for this related list?

1 ACCEPTED SOLUTION

jake_mckenna
ServiceNow Employee
ServiceNow Employee

This is something that i have been working on to help other with as i have seen it before also. Once you have changes, incidents, or even sometime BSM related items attached it becomes a challenge to just "clean up" the records and move on. One method I was working on was updating the merge ci action to also include going out and finding all related table/ relationships and updating those with the right CI along with the actual merger. I think there might be some more logic to put into it, but here is what I ended up changing the processing script to. This code logic was captured from the folks who created the Knowledge15 material for discovery around deleting related items from a CI. I have just merely twisted it to update those references. I think there is some testing that is still needed, but I am happy to pass it along if you want to take a look on this one.



Really for your scenario I would build some more logic around your integration to set the unverified field to true if it does insert a record, but also I ended up making some changes to the UI page to expand my cleanup.



HTML: Here i changed the table to look at all tables since for you it could be a server, but the record was in cmdb_ci


<g:ui_form>


<input type="hidden" id="cancelled" name="cancelled" value="false"/>


<input type="hidden" id="ci" name="ci" value="${sysparm_sys_id}"/>




<table style="height:100px;" width="100%">


              <tr>


                              <td style="width:100px; text-align:right;"><label for="${jvar_ci_query}" onclick="" dir="">${gs.getMessage('CI to Merge:')}</label>$[SP]</td>


  <td><g:ui_reference name="QUERY:unverified=false^ORunverifiedISEMPTY" table="cmdb_ci"/></td>   <!--updated table ref -->


              </tr>


              <tr id="dialogbuttons">


                      <td colspan="2" align="right">


                              <g:dialog_buttons_ok_cancel ok="return actionOK();" cancel="cancel();"/>


                      </td>


              </tr>


</table>


</g:ui_form>



Client Script: I added a new hidden element to the form for the table that the ci is in.


function cancel() {


  var c = gel('cancelled');


  c.value = "true";


  GlideDialogWindow.get().destroy();


}




function actionOK() {


  var ci_id = gel('QUERY:unverified=false^ORunverifiedISEMPTY').value;



  if (ci_id == '') {


  alert(getMessage("Please select a CI to merge this CI into"));


  return false;


  } else {


  var form = document.forms['form.' + '${sys_id}'];


  addInput(form, "HIDDEN", "new_ci", ci_id);


  addInput(form, "HIDDEN", "table", '${sysparm_class_name}'); //new line


  return true;


  }


}



Processing Script: Here i am using that code i adapted from K15 to merge the related list items that would normally be orphaned.



if (cancelled == "false" && new_ci != "") {


  mergeRelated(ci,new_ci,table);// new line


  new AssetandCI().mergeCI(ci, new_ci);


  response.sendRedirect("cmdb_ci.do?sys_id=" + new_ci);


} else{


  response.sendRedirect("cmdb_ci.do?sys_id=" + ci);


}





//new function call


function mergeRelated(oldCI, newCI, tableName) {



  // get a list of tables that are parent class to this one


  var tu1 = new TableUtils(tableName);


  var parentList= j2js(tu1.getTables());


  var parentQueryList = [];


  // Build an encoded query string


  for (var i = 0; i < parentList.length; i++)


  parentQueryList.push('reference=' + parentList[i]);



  var parentQuery = parentQueryList.join('^OR');


  // gs.print('parentQuery=' + parentQuery);



  var dGr = new GlideRecord('sys_dictionary');



  dGr.addQuery('internal_type', 'reference');


  dGr.addEncodedQuery(parentQuery);


  dGr.orderBy('name');


  dGr.query();



  // gs.print('count=' + dGr.getRowCount());



  while (dGr.next()) {



  // Now query the known table/field to see if they reference the current CI


  var gr = new GlideRecord(dGr.getValue('name'));



  gr.addQuery(dGr.getValue('element'), oldCI); // eg. cmdb_alias.cmdb_ci=your sys_id


  gr.query();



  while (gr.next()) {


  // Just blank out the CI field


  gr.setValue(dGr.getValue('element'), newCI);


  gr.update();


  }


  }


}


View solution in original post

6 REPLIES 6

Mohammed A Kha1
Tera Contributor

Just curious if it's possible to merge two records and associated data under them through scripting,

 

Table Name: cmdb_ci_linux_server  have one or more similar records  Let's just say Record Mac101 and Record Mac101 both are having incidents, changes, tasks, business services under them as association. How do go about merging them?

 

Name              

Mac101   -------------> sys_id 3902ksdkfosiidss         (Latest CI)

Changes,tasks, incidents, business services

Mac101 --------------->sys_id 230820klsdlkfdss          (old CI)

Changes,tasks, incidents, business services

 

Output: - //combined from both Mac101

Mac101   -------------> sys_id 3902ksdkfosiidss         (Latest CI)

Changes,tasks, incidents, business services (all association)

I'm wondering if you ever got an answer to this?