Creating a Relationship From a Storage File Share CI to the Server that has it Mounted

Michael Zglesze
Giga Expert

Hello Community!

I have set up EMC Isilon devices in Discovery and am very happy with the results, except for one thing:  there is no relationship from the Storage File Share CI to the Server on which it is mounted.

As a solution for Linux Servers, I've...

  1. Developed a custom Probe that is triggered by the Linux - Storage Sensor, that returns the NFS File System paths,
  2. Developed a custom Sensor that takes each NFS File System path and creates a relationship to the Server being discoved to any Storage File Share CIs with a matching path.

Now the CIs from the EMC Isilon discovery are related to the rest of the CMDB.

My question is, has anyone else attempted to relate EMC Isilon CIs to other CIs, like Server, NAS File System, Business Applications, etc.?  If so, what was the idea; what is the best way to go about this?

The Probe and Sensor code is below for reference:

#!/bin/sh

MOUNTS="`cat /proc/mounts 2>&1`"

if [ "`echo $?`" == "1" ]; then
	echo "ERROR:  Unable to cat /proc/mounts.  $MOUNTS"
elif [ "$MOUNTS" == "" ]; then
	echo "ERROR:  No information returned for cat /proc/mounts"
else
	echo "$MOUNTS" | grep nfs | while read MOUNT; do
		if [ "`echo $MOUNT | cut -d' ' -f3`" == "nfs" -o "`echo $MOUNT | cut -d' ' -f3`" == "nfs4" ]; then
			echo $MOUNT | cut -d' ' -f1 | cut -d':' -f2
		fi
	done
fi

 

new DiscoverySensor({
	process: function(result) {
		//	Create a new instance of DiscoveryFunctions to be used to initialize the DiscoveryLogger
		var discoFunctions = new DiscoveryFunctions();
		
		//	Get the Discovery Status sys_id to determine if this is being run from Test Probe or a Quick Discovery
		var discoStatusSysID = discoFunctions.getStatusRecord();
		
		if(discoStatusSysID) {
			//	Create a new instance of the DiscoveryLogger so that Error, Warnings, and Information messages can be written to the Discovery Log
			var discoLog = new DiscoveryLogger(discoFunctions.getStatusRecord().sys_id);
			
			//	Set the variables to be used in the Logging functions
			var loggerSource = this.getSensorName();
			var loggerSensor = this.getEccQueueId();
			var loggerCI = this.getCmdbCi();
			
			// Create an object to get and set values of the Configuration Item record being discovered.
			var deviceCI = this.getCmdbRecord();
		}
		
		if((result.output.indexOf('ERROR') >= 0) || JSUtil.nil(result.output)) {
			discoLog.warn(((JSUtil.notNil(result.output)) ? (result.output) : ('The Probe returned no data from cat /proc/mounts.')), loggerSource, loggerSensor, loggerCI);
			return;
		} else {
			var relType = 'e1679212dba05810cf5a6f13ca961975';
			var arrayData = result.output.split('\n');
			
			//	First, determine if a NAS File System Configuration Item exists for each path in arrayData
			//	If the NAS File System CI exists, push the sys_id into an arrayData
			for(var i = 0; i < arrayData.length; i++) {
				var grNAS_FileSystem = new GlideRecord('cmdb_ci_nas_file_system');
				grNAS_FileSystem.addQuery('computer', ((discoStatusSysID) ? (deviceCI.sys_id.toString()) : (g_probe_parameters['ci_sys_id'].toString())));
				grNAS_FileSystem.addQuery('nas_path', arrayData[i].toString());
				grNAS_FileSystem.query();
				
				//	If there is an existing NAS File System CI for the path specified in arrayData[i], then check for an existing Storage File Share CI with the same path
				while(grNAS_FileSystem.next()) {
					var grStorageFileShare = new GlideRecord('cmdb_ci_storage_fileshare');
					grStorageFileShare.addQuery('u_active', true);
					grStorageFileShare.addQuery('install_status', '!=', 7);
					grStorageFileShare.addQuery('operational_status', '!=', 2);
					grStorageFileShare.addQuery('path', arrayData[i]);
					grStorageFileShare.query();
					
					//	If there are existing Storage File Share CIs with the same path, then check for an existing Relationship between the two
					while(grStorageFileShare.next()) {
						var grRel = new GlideRecord('cmdb_rel_ci');
						grRel.addQuery('parent', ((discoStatusSysID) ? (deviceCI.sys_id.toString()) : (g_probe_parameters['ci_sys_id'].toString())));
						grRel.addQuery('type', relType);
						grRel.addQuery('child', grStorageFileShare.sys_id.toString());
						grRel.query();
						
						if(!grRel.hasNext()) {
							var grNewRel = new GlideRecord('cmdb_rel_ci');
							grNewRel.initilize();
							grNewRel.setValue('parent', ((discoStatusSysID) ? (deviceCI.sys_id.toString()) : (g_probe_parameters['ci_sys_id'].toString())));
							grNewRel.setValue('type', relType);
							grNewRel.setValue('child', grStorageFileShare.sys_id.toString());
							var insertResult = grNewRel.insert();
							
							if(insertResult) {
								discoLog.info('Relationship Created:\n\n' + grNewRel.parent.getDisplayValue() + '\n' + grNewRel.type.getDisplayValue() + '\n' + grNewRel.child.getDisplayValue(), loggerSource, loggerSensor, loggerCI);
							}
						}
					}
				}
			}
		}
	},
	
	type: "DiscoverySensor"
});
7 REPLIES 7

Michael Zglesze
Giga Expert

Thank you, Ashutosh!  🙂

That's exactly what we did...use the out-of-the-box EMC Isilon Discovery Pattern, and it works like a charm!  The only issue that we had was that we want to use SNMPv3 instead of SNMP Community String, and it looks like ServiceNow can't do that.  (...if I'm wrong, let me know how to do it...)

That builds a great relationship structure, but doesn't connect to the servers that are using those shares.  I'm curious if anyone has linked the Storage File Share CI to any existing CIs, so that the Dependency Map shows a continuous line for which Business Applications are using which Storage Clusters.

Thoughts?

Hi, Should not be this other way round as well. Just trying to get your thoughts, discovery then independently and then when you discover storage server let them create relationship with File shares? Thanks, Ashutosh