Adding AS400 to Discovery

dturner
Giga Contributor

Out of box, ServiceNow does not give us the ability to scan and classify AS400 devices. However, if your AS400 administrator is willing to open SSH on the boxes, then you can create probes and sensors to do the work just like as if it was a Unix machine.

/*******************************************************************************
***** < I have attached the XML data to import to your instance for easy installation! > **********
*******************************************************************************/


First, you need a UNIX CI Classifier (Name it AS400). I suggest a brand new table to put these devices on (we are using "u_i5_server").
Make the classification criteria 'output' CONTAINS 'OS400' and in the On classification script, you can put in something like this to start with:
current.os = "OS/400";
current.os_name = "OS/400";
current.short_description = output;

Now you need to make a multiprobe. Call it "AS400 - Identity" with ECC queue topic as "MultiProbe" and the ECC queue name as "AS400 - Identity." Ensure the probe is a MultiProbe and save it. Later, we will add items to the related lists "Includes probes" and "Sensors".

Now lets make the first probe. Call it "AS400 - OS" and make the ECC queue topic SSHCommand, and the ECC queue name as "uname -a" (without the quotes). This will get the Operating system from the AS400 since if you are using SSH the AS400 gives you a simple UNIX shell to work with. In this probe, ensure Used by discovery is selected and in the Related List "Included by Multiprobe" add the previously created AS400 - Identity multiprobe.

Now, in the MultiSensor Scripts related list for the AS400 - OS probe, click on New and paste this code:


function(result, ciData, debug, sensor) {
       var output = result.output;
       if (output === null || gs.nil(output))
               return;

       run(output, ciData, debug);

       function run(output, ciData, debug) {
               var ci_data = ciData.getData();
               var uname = output;
               var unameParts = uname.split(/ /);

               var osName = unameParts[0];
               var osHostname = unameParts[1] ? unameParts[1] : "unknown.host";
               var osVersion = unameParts[2] ? unameParts[2] : "";

               ci_data.os_name = osName;
               ci_data.os_version = osVersion;
               ci_data.output = output;

               // Don't bother with ssh hostname if we shouldn't trust the ssh name and DNS already has already populated it
               var trusted = JSUtil.toBoolean(gs.getProperty("glide.discovery.hostname.ssh_trusted", "false"));
               var haveNow = JSUtil.notNil(ci_data['name']);
               var haveNew = JSUtil.notNil(osHostname);

               if (!haveNew)
                       return;

               if (!trusted &amp;&amp; haveNow)
                       return;
             
               var hn = new HostnameJS();
               ci_data['name'] = hn.format(osHostname, JSUtil.notNil(ciData.ip_address)? ciData.ip_address:null);
       }
}

Make sure that it Reacts to Probe "AS400 - OS" and click Save or Update.


Now, create a brand new MultiSensor called AS400 - Identity and make sure that it Reacts to Probe: AS400 - Identity. Use the following in the Script:

new DiscoveryIDSensor({

type: "AS400 Identity"
});


Save the MultiSensor and in the related list, ensure that Responds to Probes related list has the "AS400 - OS" probe that you created earlier.


Now, ensure that you have an SSH credential that will work set up in the Credentials table!

Create a new discovery on an AS400 box you know of and then see what happens!

Once you have confirmed that this works, you can add additional probes to the MultiProbe in the related list "Includes probes". Since AS400 has a UNIX shell you can use, you can make a Filesystem probe with simply "df -kP" and you can make an Active Processes probe with "ps -aef". In these extended probes, just ensure that they are Triggered by your AS400 classifier and that there are Sensors defined for each!

For active processes, simply use this in the script for the sensor:

new DiscoveryPsSensor({

       type: "DiscoverySensor"
});


For Filesystems, use this code in the script for the sensor:


new DiscoverySensor({
       fileSystems: {},

       process: function(result) {
               if (gs.nil(result.output))
                       return;

               this.parseOutput(result.output);
               this.updateFileSystems();
       },

       updateFileSystems: function() {
               var fsList = [];

               for (var fs in this.fileSystems) {
                       var fileSystem = {};
                       fileSystem.name = this.fileSystems[fs].name;
                       fileSystem.capacity = this.fileSystems[fs].capacity;
                       fileSystem.available_space = this.fileSystems[fs].available_space;
                       fileSystem.mount_point = fs;

                       fsList.push(fileSystem);
               }

               this.addToRelatedList('cmdb_ci_file_system', fsList, 'provided_by', 'pid');
       },

       parseOutput: function(output) {
               var lines = output.split(/\n/);

               for (var i = 0; i < lines.length; i++) {
                       var line = lines<i>.trim();

                       // handle the case where one of our data lines was split because the name was too long...
                       if (line.indexOf(' ') < 0) {
                               if ((i + 1 < lines.length) &amp;&amp; (lines[i + 1].charAt(0) == ' ')) {
                                       i++;
                                       line = line + ' ' + lines<i>.trim();
                               }
                       }

                       if (!line.startsWith('/dev/'))
                               continue;

                       var parts = line.split(/\s+/);
                       this.fileSystems[parts[5]] = {};
                       this.fileSystems[parts[5]].name = parts[0];
                       this.fileSystems[parts[5]].capacity = Math.round(parseInt(parts[1]) / 1024);
                       this.fileSystems[parts[5]].available_space = Math.round(parseInt(parts[3]) / 1024);
               }
       },

       type: 'DiscoverySensor'
});


I hope this helps someone.
27 REPLIES 27

dturner
Giga Contributor

Sorry, see below.


StephenHey
Mega Guru

If you don't have SSH access, you can always include IBM's "JTOpen" Java library in the MID Server includes and then write an integration using this Library, a MID Server Script Include, and the "JavaScript" probe. This only requires normal login accesses to the AS400.


Hi Stephen, have you implemented using JTOpen, if so can you please share the solution

stenore
Kilo Explorer

I have followed the instructions but each time this runs, I receive the following message

Sensor error when processing UNIX - Classify: No sensors defined

Does anyone know why or what I can do to figure out what is happening? There is a probe, sensor, etc all create per above. I do see the connection to the AS400, it does bring back the unname information but then does nothing with it other than throwing the error. I'm not sure where I have gone wrong, please help


We found that the dev environment was not working, something within discovery is broken. We moved it to test and sure enough it worked!