Find your people. Pick a challenge. Ship something real. The CreatorCon Hackathon is coming to the Community Pavilion for one epic night. Every skill level, every role welcome. Join us on May 5th and learn more here.

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: