Roger Poore
Tera Guru

 find_real_file.png

Ever wondered how ServiceNow builds their infrastructure relationships map?  Neither did I until I wanted to duplicate it with a script.  Now, I know there are various ways to get CI relationships such as recursing cmdb_rel_ci or using the CIUtils or CMDBUtil libraries.  I've done it those ways and they work fine.  But I wanted to do something different.

If you inspect what ServiceNow is doing when it's building that dependency list, it's calling an API named cmdbrelation:

https://${instance_name}.service-now.com/api/now/cmdbrelation/relation/${id}?loadType=flat&sLevel=${levels}

The ${id} endpoint is going to be the sys_id of the CI you're getting the relationships for.
The loadType parameter determines whether you want the results flattened or in a tree.
The sLevel parameter determines how deep you want to go.

So I built an Outbound REST message that is called for each business app. The returned JSON includes arrays named "relations".  There is a varying number of these so you need to get the count of them and process each one iteratively.  

Something like that.

function getBusinessApps() {
    var gr = new GlideRecord('cmdb_ci_business_app');
    gr.addEncodedQuery('environment=PROD^operational_status=1');
    gr.query();

    var apps = [];
    while (gr.next()) {
        var o = {};
        o.name = gr.getDisplayValue();
        o.sysid = gr.sys_id.toString();

        apps.push(o);        
    }

    return apps;
}

function getDependents(ci, max_levels) {
  var requestBody, responseBody, status;

  try {
    var request = new sn_ws.RESTMessageV2("CMDB Dependencies", "GET");  
    request.setStringParameter("instance_name", "my-instance");
    request.setStringParameter("id", ci);
    request.setStringParameter("levels", max_levels);
    request.setHttpTimeout(10000); 

    response = request.execute();

    responseBody = response.haveError() ? response.getErrorMessage() : response.getBody();
    status = response.getStatusCode();

  } 
  catch(x) {
    responseBody = x.getMessage();
    status = '500';
  } 
  finally {
    requestBody = request ? request.getRequestBody():null;
  }


  return responseBody;
}

/*****************************************************/

var max_levels=3, base_class;
var apps = getBusinessApps();

apps.forEach(function(table) {
    base_class = table.sysid;
  
    var json = getDependents(table.sysid, max_levels);
    if (json) {
      json = JSON.parse(json);
      json = json.result.relations;
  
      var rel_node_length = JSON.parse(json).relations.length;
      
      for (var i=0; i<rel_node_length; i++) {
        var node = JSON.parse(json).relations[i];
        gs.print(node);
      }
    }

});
	

And the output:

 find_real_file.png
Version history
Last update:
‎02-18-2021 06:40 PM
Updated by: