Name

global.SNMPResponse

Description

Wraps an SNMP payload response instance with methods to safely and easily retrieve SNMP singleton fields or tables.

Script

// Discovery class

/**
* Wraps an SNMP payload response instance with methods to safely and easily retrieve SNMP singleton fields or tables.
* 
* Tom Dilatush tom.dilatush@service-now.com
*/
var SNMPResponse = Class.create();

SNMPResponse.prototype = {
  /*
   * Initializes a new instance of this class from the given payload.
   */
  initialize: function(result) {
      this.snmp = result.snmp;
      if (!this.snmp)
          this.snmp = result.result.snmp;
      this.map = {};

      this.normalize(this.snmp);
      this.buildIndex(this.snmp, '', '');
      this.buildReferences();
  },

  /*
   * Resolve SNMP tables into hashmaps and OID values into primitives. All SNMP numeric types convert to a JavaScript 
   * number. An SNMP null type converts to a JavaScript null. An SNMP IP Address value converts to a Java IPAddressV4 
   * instance. All other values convert to a JavaScript string.
   */
  normalize: function(cur) {
      // what's in this thing?
      for (var prop_name in cur) {
          // if it's an attribute, ignore it...
          if (prop_name.substring(0, 1) == '@' || prop_name.substring(0, 1) == '#')
              continue;

          var prop = cur[prop_name];
          if (JSUtil.nil(prop))
              continue;

          var prop_type = JSUtil.type_of(prop);

          // if this is a leaf value, it will have a type; convert it...
          var oid_type = prop['@type']
          if (oid_type) {
              var oid_numeric = (oid_type == 'SnmpCounter32') || (oid_type == 'SnmpCounter64') ||
                  (oid_type == 'SnmpGauge32');
              oid_numeric = oid_numeric || (oid_type == 'SnmpInt32') || (oid_type == 'SnmpUInt32') ||
                  (oid_type == 'SnmpTimeTicks');
              var oid_null = (oid_type == 'SnmpNull');
              var oid_ip = (oid_type == 'SnmpIPAddress');
              var oid_oid = (oid_type == 'SnmpObjectId');

              if (oid_numeric)
                  cur[prop_name] = JSUtil.has(prop['#text']) ? parseInt(prop['#text']) : 0;
              else if (oid_oid) {
                  var oid_txt = JSUtil.has(prop['#text']) ? '' + prop['#text'] : null;
                  cur[prop_name] = (JSUtil.notNil(oid_txt) && oid_txt.charAt(0) == '.') ? oid_txt.substr(1) : oid_txt;
              } else if (oid_null)
                  cur[prop_name] = null;
              else if (oid_ip)
                  cur[prop_name] = JSUtil.has(prop['#text']) ?
                  SncIPAddressV4.getIPAddressV4Instance(prop['#text']) :
                  null;
              else
                  cur[prop_name] = JSUtil.has(prop['#text']) ? '' + prop['#text'] : null;
              continue;
          }

          // ah, but is this a table?
          var index = prop['@instance'];
          if (index || (prop instanceof Array)) {
              // yup, we've got a table entry; transform it...
              var entries = g_array_util.ensureArray(prop);
              var tm = new SNMPTable();
              for (var i = 0; i < entries.length; i++) {
                  var entry = entries[i];
                  var instance = entry['@instance'].substring(1); // lose the leading period...
                  tm[instance] = entry;
                  this.normalize(entry);
              }
              cur[prop_name] = tm;
              continue;
          }

          // nope, we must have a container, so recursively explore it...
          this.normalize(prop);
      }
  },

  /*
   * Builds references to actual instances for all identified indexes (in the discovery_snmp_ref table) that can be 
   * resolved.
   */
  buildReferences: function() {
      // iterate through all the references we know how to map to table entries...
      var gr = new GlideRecord('discovery_snmp_ref');
      gr.addActiveQuery();
      gr.orderBy('order');
      gr.query();
      while (gr.next()) {
          var ref = '' + gr.getValue('reference');
          var ent = '' + gr.getValue('entry');
          var ent_obj = this.getOIDObj(ent);
          var ref_last_dot = ref.lastIndexOf('.');
          var ref_base = ref.substring(0, ref_last_dot);
          var ref_leaf = ref.substring(ref_last_dot + 1);
          var refs = this.getAmbiguousOIDs(ref_base, ref_leaf);

          if (JSUtil.nil(ent_obj))
              continue;

          // map to specific entries...
          for (var i = 0; i < refs.length; i++) {
              var entry = refs[i];
              var refers_to = ent_obj[entry[ref_leaf]];
              if (JSUtil.nil(refers_to))
                  refers_to = null;
              entry[ref_leaf + '_'] = refers_to;
          }
      }
  },

  /*
   * Return an array of OIDs that match the given ref_base and which have a defined, non-null ref_leaf.  Note that 
   * the last character of ref_base may be a question mark; in that case, if the parent node is a table then all 
   * table entries are returned.
   */
  getAmbiguousOIDs: function(ref_base, ref_leaf) {
      var result = [];

      // is this an ambiguous entry?
      if (ref_base.substr(-1) == '?') {
          var table = this.getOIDObj(ref_base.substr(0, ref_base.length - 2));
          for (var ent_name in table) {
              var ent = table[ent_name];
              if (!ent)
                  continue;

              var leaf = ent[ref_leaf];
              if (JSUtil.nil(leaf))
                  continue;

              result.push(ent);
          }
      }

      // nope, so treat it as a non-table entry...
      var ent = this.getOIDObj(ref_base);
      if (ent)
          result.push(ent);
      return result;
  },

  /*
   * Builds an index to all SNMP entities in our object. Note that it does NOT index the fields within table entries 
   * (though it does index the table itself).
   */
  buildIndex: function(cur, name, ext_name) {
      // what's in this thing?
      for (var prop_name in cur) {
          // if it's an attribute, ignore it...
          if (prop_name.substring(0, 1) == '@' || prop_name.substring(0, 1) == '#')
              continue;

          var prop = cur[prop_name];
          var prop_type = JSUtil.type_of(prop);

          // add this fellow to our index...
          var index = ext_name + ((ext_name == '') ? '' : '.') + prop_name;
          this.map[index] = prop;

          // if this property is a table, a primitive, or an IPAddressV4, we're done...
          if ((typeof prop != 'object') || (prop instanceof SNMPTable) || (JSUtil.instance_of(prop,
                  'com.snc.commons.networks.IPAddressV4')))
              continue;

          else // nope, we've got something else; recursively explore it...
              this.buildIndex(prop, prop_name, ext_name + ((ext_name == '') ? '' : '.') + prop_name);
      }
  },

  /*
   * Returns the text contained in the OID object with the given MIB name.  Returns null if the object could not be 
   * found, or if it has no text.
   */
  getOIDText: function(name) {
      var oid = this.getOIDObj(name);
      if (JSUtil.nil(oid))
          return null;

      return '' + oid;
  },

  /*
   * Returns the integer contained in the OID object with the given MID name, or zero if the object could not be 
   * found or is empty.
   */
  getOIDInt: function(name) {
      var result = this.getOIDText(name);
      return JSUtil.nil(result) ? 0 : result - 0;
  },

  /*
   * Returns a hashmap of table entries under the given parent MIB name, with the given entry MIB names.  Returns 
   * null if the parent does not exist.
   */
  getOIDTable: function(parent_name, entry_name) {
      var pn = parent_name;
      if (entry_name)
          pn += '.' + entry_name;
      return this.getOIDObj(pn);
  },

  /*
   * Retrieve the OID object with the given MIB name from the response.  Returns null if the object could not be 
   * found, or if any table entries are encountered while walking down the named elements.  Note that this method 
   * does not work with numeric OID strings, only MIB names.
   */
  getOIDObj: function(name) {
      return this.map[name];
  },

  type: "SNMPResponse"
};

Sys ID

83f9a33a0ab30153004187736f3a6d34

Offical Documentation

Official Docs: