The Zurich release has arrived! Interested in new features and functionalities? Click here for more

Find the relationship between vCenter Cluster and vCenter Datacenter

scqpnovo
Tera Contributor

Hi all

I can see here, that there's supposed to be a relationship between discovered Vmware vCenter Clusters and vCenter Datacenters: VMware vCenter Object [cmdb_ci_vcenter_object] class (servicenow.com). But when I lookup in the table cmdb_ci_vcenter_cluster, there is no field/column with relationship/reference to cmdb_ci_vcenter_datacenter. It seems all the vcenter_x tables only have a reference to a vCenter.
Am I approaching this in the right way?

Thanks.

 

1 ACCEPTED SOLUTION

Daniel Borkowi1
Mega Sage

@scqpnovo here is an example for a Script Include, which could be called by Client Script 

var DBCMDBUtilAjax = Class.create();
DBCMDBUtilAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    type: 'DBCMDBUtilAjax',
    RETURN_FIELDS: ['name', 'sys_id', 'sys_class_name'], //fields which are printed for each CI

    getDownstreamRelationships: function() {
        var cmdb_ci = this.getParameter('sysparm_configuration_item');
        var level = this.getParameter('sysparm_level');
        if (!level) {
            level = 3; // Defaul level
        }
        var return_object = {};
		if (cmdb_ci) {
            return_object = this._getDownstreamRelationships(cmdb_ci, level, 1);
		}
        return JSON.stringify(return_object);
    },

    _getDownstreamRelationships: function(cmdb_ci_sys_id, level, current_level) {
        var relationships = [];
        if (level > 0) {
            var parent_obj = this._getCIObject(cmdb_ci_sys_id);
            var grRelationship = new GlideRecord("cmdb_rel_ci");
            grRelationship.addQuery('parent', cmdb_ci_sys_id);
            grRelationship.addNotNullQuery('child');
            grRelationship.query();
            while (grRelationship.next()) {
                relation_obj = {};
                relation_obj.parent = parent_obj;
                relation_obj.type = grRelationship.getDisplayValue('type');
                var child_id = grRelationship.getValue('child');
                relation_obj.child = this._getCIObject(child_id);
                relation_obj.level = current_level;
                relationships.push(relation_obj);
                var next_relationships = this._getDownstreamRelationships(child_id, level - 1, current_level + 1);
                for (var i in next_relationships) {
                    relationships.push(next_relationships[i]);
                }
            }
        }
        return relationships;

    },
    //Print CIs with field given in RETURN_FIELDS
    _getCIObject: function(cmdb_ci_sys_id) {
        var obj = {};
        var ciGR = new GlideRecord('cmdb_ci');
        if (ciGR.get(cmdb_ci_sys_id)) {
            for (var i in this.RETURN_FIELDS) {
                var field = this.RETURN_FIELDS[i];
                obj[field] = ciGR.getValue(field);
            }
        }
        return obj;
    }

});

 

The example client script:

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }

    var ga = new GlideAjax('DBCMDBUtilAjax');
    ga.addParam('sysparm_name', 'getDownstreamRelationships');
    ga.addParam('sysparm_configuration_item', newValue);
    ga.addParam('sysparm_level', 2);
    ga.getXML(callback);

    function callback(response) {
        var answer = response.responseXML.documentElement.getAttribute("answer");
		var relations = JSON.parse(answer);
		var alert_text = "";
		for (var i = 0; i <  relations.length; i++){
			var relation = relations[i];
			//do something with each relation
			var str = relation.parent.name + " " + relation.child.name;
			alert_text += str;
		}
		alert("Alert_text: " + alert_text);
    }
}

 

Greets
Daniel

Please mark reply as Helpful/Correct, if applicable. Thanks!

View solution in original post

6 REPLIES 6

Daniel Borkowi1
Mega Sage

Hi @scqpnovo ,

 

these are the OOTB relationships (cmdb_rel_ci) used for VMware object:

DanielBorkowi1_0-1694775997873.png

 

https://docs.servicenow.com/bundle/vancouver-it-operations-management/page/product/discovery/referen...

 

Greets
Daniel

Please mark reply as Helpful/Correct, if applicable. Thanks!

 

scqpnovo
Tera Contributor

Hi @Daniel Borkowi1 .
Awesome - that is what I am looking for.

However it gets quite complex to join 3 tables in client ui scripts, to find their relationships. Are there any good examples out there, on how to accomplish this?

Daniel Borkowi1
Mega Sage

Hi @scqpnovo, you can use CMDB Relationship API (/api/now/cmdbrelation/relation/), here a example from ServiceNow support:

 

var request = new sn_ws.RESTMessageV2();
request.setEndpoint('https://instance_name.service-now.com/api/now/cmdbrelation/relation/YourCISysID?sLevel=YourRequiredLevel');
request.setHttpMethod('GET');

// Eg. UserName="admin", Password="admin" for this code sample.
// var user = 'YourUserName'; //(UserName)
// var password = 'YourPassword'; //(Password)

request.setBasicAuth(user,password);
request.setRequestHeader("Accept","application/json");

var response = request.execute();
gs.log(response.getBody());
""

Output:
\"childName\":\"VirtualMachine-LS8\",\"childrenCount\":1,\"childSysClassName\":\"cmdb_ci_server\",\"childSysId\":\"CiSysID\",\"relationTypeSysId\":\"RelationTypeID\",\"parents\":[{\"sysId\":\"CiSysID\",\"sysClassName\":\"cmdb_ci_server\",\"name\":\"VirtualMachine-LS7\"}],\"relationSysId\":\"RelationTypeID\",\"relationTable\":\"cmdb_rel_ci\",\"downStream\":false},{\"

 

 

Or you build a Client Callable Script Includes, which reads out all downstream relationships and delivers the needed output.

 

 Greets
Daniel

Please mark reply as Helpful/Correct, if applicable. Thanks!

Daniel Borkowi1
Mega Sage

@scqpnovo here is an example for a Script Include, which could be called by Client Script 

var DBCMDBUtilAjax = Class.create();
DBCMDBUtilAjax.prototype = Object.extendsObject(AbstractAjaxProcessor, {
    type: 'DBCMDBUtilAjax',
    RETURN_FIELDS: ['name', 'sys_id', 'sys_class_name'], //fields which are printed for each CI

    getDownstreamRelationships: function() {
        var cmdb_ci = this.getParameter('sysparm_configuration_item');
        var level = this.getParameter('sysparm_level');
        if (!level) {
            level = 3; // Defaul level
        }
        var return_object = {};
		if (cmdb_ci) {
            return_object = this._getDownstreamRelationships(cmdb_ci, level, 1);
		}
        return JSON.stringify(return_object);
    },

    _getDownstreamRelationships: function(cmdb_ci_sys_id, level, current_level) {
        var relationships = [];
        if (level > 0) {
            var parent_obj = this._getCIObject(cmdb_ci_sys_id);
            var grRelationship = new GlideRecord("cmdb_rel_ci");
            grRelationship.addQuery('parent', cmdb_ci_sys_id);
            grRelationship.addNotNullQuery('child');
            grRelationship.query();
            while (grRelationship.next()) {
                relation_obj = {};
                relation_obj.parent = parent_obj;
                relation_obj.type = grRelationship.getDisplayValue('type');
                var child_id = grRelationship.getValue('child');
                relation_obj.child = this._getCIObject(child_id);
                relation_obj.level = current_level;
                relationships.push(relation_obj);
                var next_relationships = this._getDownstreamRelationships(child_id, level - 1, current_level + 1);
                for (var i in next_relationships) {
                    relationships.push(next_relationships[i]);
                }
            }
        }
        return relationships;

    },
    //Print CIs with field given in RETURN_FIELDS
    _getCIObject: function(cmdb_ci_sys_id) {
        var obj = {};
        var ciGR = new GlideRecord('cmdb_ci');
        if (ciGR.get(cmdb_ci_sys_id)) {
            for (var i in this.RETURN_FIELDS) {
                var field = this.RETURN_FIELDS[i];
                obj[field] = ciGR.getValue(field);
            }
        }
        return obj;
    }

});

 

The example client script:

 

function onChange(control, oldValue, newValue, isLoading, isTemplate) {
    if (isLoading || newValue === '') {
        return;
    }

    var ga = new GlideAjax('DBCMDBUtilAjax');
    ga.addParam('sysparm_name', 'getDownstreamRelationships');
    ga.addParam('sysparm_configuration_item', newValue);
    ga.addParam('sysparm_level', 2);
    ga.getXML(callback);

    function callback(response) {
        var answer = response.responseXML.documentElement.getAttribute("answer");
		var relations = JSON.parse(answer);
		var alert_text = "";
		for (var i = 0; i <  relations.length; i++){
			var relation = relations[i];
			//do something with each relation
			var str = relation.parent.name + " " + relation.child.name;
			alert_text += str;
		}
		alert("Alert_text: " + alert_text);
    }
}

 

Greets
Daniel

Please mark reply as Helpful/Correct, if applicable. Thanks!