- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
On occasion in this blog, I've mentioned Script Includes (navigate to System Definition → Script Includes) and talked about classes using the prototype.js library. On the Service-now instance, JavaScript classes are generally defined within a Script Include, so on our platform the two notions are related. In this post, I'm going to start a series of posts on scripting within the Service-now platform. All of these posts will result in code that you could actually use, at least theoretically. Even if you can't use them directly, they will serve as practical examples. If you've got ideas for things you'd like to see me discuss, by all means let me know about them.
In today's post, I'm going to start with this problem: I want a reusable bit of code that will let me find the CI that has a given network MAC address. Such a piece of code might be useful in a UI action (perhaps to let a service technician find out what device a particular MAC address belongs to), or it might be useful in a business rule associated with a change process. The real point is this: it's a bit of code that I'd like to write once, then be able to use it in multiple places without having to write it all over again.
In this particular case, I'm envisioning being able to write code like this:
var mac = new MACResolver();
var gr = mac.resolve('00:50:56:ae:33:d9');
gs.log(gr.sys_class_name + ': ' + gr.name);
How would I do this?
First I have to know how the CMDB schema needed works. There are two possible ways that the MAC address could be stored. The simplest way is that it could be in the mac_address field of the CI I want. If you're not using Discovery, you may have your desktop computers in your CMDB this way. The slightly more complex way is that the MAC address could be in the mac_address field of a cmdb_ci_network_adapter record, and that record would have a reference in the cmdb_ci field to the CI it's a part of (and that's what I really need).
- The _get_real_gr function is needed because our original GlideRecord is on the cmdb_ci table, and in two places we need the GlideRecord for the actual class of that CI. For example, in one place the script detects that a CI is a network adapter and uses this function to return a GlideRecord for the network adapter. This is necessary because the original GlideRecord (for cmdb_ci) doesn't have access to the fields that are specific to cmdb_ci_network_adapter — and we need one of them (cmdb_ci).
- The script skips right over records in dscy_swtch_fwd_rule (Switch Forwarding Rules). Unless you know our CMDB well, this won't make any sense at all. Here's why we skip over it: in the case of this table, the MAC address field doesn't represent the MAC address of that particular device, but rather a configuration of that device (a network switch). Because we know this can't be the device we really want, we're just skipping it.
var MACResolver = Class.create();
MACResolver.prototype = {
initialize: function() {
// naught to do here...
},
/*
* If there is a CI in the CMDB with the given MAC address, a GlideRecord instance
* for that CI is returned. Otherwise a null is returned.
*/
resolve: function(mac) {
// find a CI with this MAC...
var gr = new GlideRecord('cmdb_ci');
gr.addQuery('mac_address', mac);
gr.query();
while (gr.next()) {
// if it's not installed, try another...
if (gr.install_status == 100)
continue;
var klass = '' + gr.sys_class_name;
// if we have a switch forwarding rule, just move along...
if (klass == 'dscy_swtch_fwd_rule')
continue;
// if we have a NIC here, get the real CI...
if (klass == 'cmdb_ci_network_adapter') {
gr = this._get_real_gr(gr);
if (!gr)
continue;
var ci = '' + gr.cmdb_ci;
gr = new GlideRecord('cmdb_ci');
if (!gr.get(ci))
continue;
}
// right now we have a GlideRecord on cmdb_ci
// get the correct table
gr = this._get_real_gr(gr);
if (gr)
return gr;
}
// if we get here, then we failed to find a CI...
return null;
},
_get_real_gr: function(gr) {
var sys_id = gr.getUniqueValue();
var table = '' + gr.sys_class_name;
var real_gr = new GlideRecord(table);
return real_gr.get(sys_id) ? real_gr : null;
}
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
