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

Here's a little bit of background information:  The end goal is for our Storage Team to be able to put in a Change Request for a Storage Cluster, and have the Business Applications that uses the Storage File Shares on that cluster appear in the Affected CIs tab.

I know that we've heavily customized our Change Request Workflows, so I know that in order to accomplish that, I need to have the Business Application, which is related either to the Server, or another Application then to a Server, related to the Storage File Share that is mounted.

For Example, after I manually relate the Linux Server below to the Storage File Share, it will automatically be added to the Change Request because the Business Application is within x relationships downstream.

find_real_file.png

I wrote the Probe and Sensor for Linux Server to automatically accomplish this relationship.  

I was wondering if this was the best way to do this, or if there is another way that people are using.

Also, another question, for Windows Servers that use SMB to connect to the EMC Isilon, it seems as if I cannot get the path information for a particular server because it is based on the user's permissions that mapped the server to the share.  Has anyone been able to automatically relate a Windows Server to a Storage File Share?

Thanks again for your help!  🙂

AnimeshKar10
ServiceNow Employee
ServiceNow Employee

Hi Michael, 

Is this all of the probe script or is there more? 

I am unable to save the probe with just this code.

 

#!/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

 

Regards

Animesh

Narayanan
Tera Contributor

Hi Michael, Thanks for sharing this probe/sensor. I am interested in linking Storage to the Servers and facing an issue with OOB version.

 

In my scenario, the NFS File System path received from the Linux is different from Storage File Share path. So wanted to check with what kind of Storage you tested with this code? I am having NetApp

 

Appreciated if you can share some insights here. 

 

Regards,

Narayanan