Name

global.DiscoverySmi15StorageServerSensor

Description

Processes Storage Array block devices, file systems, pools, HBAs, ports, etc. Used by both the SMI - Storage Server and SMI 1.5 - Storage Server sensors.

Script

// Discovery

ArrayPolyfill;
JsonCi;

var DiscoverySmi15StorageServerSensor;

(function() {

var deviceSysId, locationId, device,
  DiscoverySmiStorageServerSensor = Class.create(),
  // Field names are shortened in the payload to keep it as small as possible.
  // This object defines the mapping from short name to full name.
  remap = {
  	c: 'controller',
  	co: 'computer',
  	d: 'device_id',
  	e: 'exported_by',
  	f: 'free_space_bytes',
  	ii: 'initiator_iqn',
  	iw: 'initiator_wwpn',
  	l: 'lun',
  	n: 'name',
  	p: 'provided_by',
  	pi: 'pool_id',
  	pt: 'port_type',
  	s: 'size_bytes',
  	sd: 'short_description',
  	sn: 'serial_number',
  	sp: 'speed',
  	st: 'storage',
  	v: 'volume_id',
  	w: 'wwpn',
  	wn: 'wwnn'
  },
  // See the JsonCi script for a description of this structure.
  schema = {
  	cmdb_ci_storage_server: {
  		index: [ 'serial_number' ],
  		fixup: fixupStorageServer,
  		remap: remap,
  		reverseRelations: { usedBy: 'Uses::Used by' }
      },
  	cmdb_ci_storage_volume: {
  		index: [ 'computer', 'name' ],
  		fixup: fixupVolume,
  		remap: remap,
  		reverseRelations:{computer: 'Contains::Contained by'}
  	},
  	cmdb_ci_disk: {
  		index: [ 'computer', 'device_id' ],
  		fixup: fixupDisk,
  		remap: remap
  	},
  	cmdb_ci_storage_pool: {
  		index: [ 'hosted_by', 'pool_id' ],
  		fixup: fixupStoragePool,
  		remap: remap,
  		reverseRelations:{hosted_by: 'Contains::Contained by'}
  	},
  	cmdb_ci_storage_controller: {
  		index: [ 'computer', 'device_id' ],
  		fixup: fixupStorageController,
  		remap: remap,
  		relations: { fp: 'Controller for::Controlled by' }
  	},
  	cmdb_ci_fc_port: {
  		index: [ 'computer', 'wwpn' ],
  		fixup: fixupFcPort,
  		remap: remap
  	},
  	cmdb_ci_iscsi_export: {
  		index: [ 'exported_by', 'storage', 'initiator_iqn' ],
  		fixup: fixupIScsiExport,
  		remap: remap
  	},
  	cmdb_ci_fc_export: {
  		index: [ 'exported_by', 'storage', 'initiator_wwpn' ],
  		fixup: fixupFcExport,
  		remap: remap
  	}
  },
  validIntfs = { sas: 'sas', scsi: 'scsi', sata: 'sata' };

DiscoverySmi15StorageServerSensor = {
  process: function(sensor, output) {
  	var results = JSON.parse(output),
  		args = {
  			results: results,
  			schema: schema,
  			isDebugging: sensor.isDebugging()
  		};

  	device = sensor.getCmdbRecord();
  	deviceSysId = device && ('' + device.sys_id);  // device.sys_id only looks like a string.  Convert it to a real string.
  	locationId = sensor.getLocationID();

  	// prepare() does a few things to all returned objects and then
  	// reattaches them, returning the same JS object produced by the probe.
  	args.results = JsonCi.prepare(args);
  	
  	JsonCi.writeJsObject(args);
  	JsonCi.writeRelationships(args);
  }
};

function fixupVolume(volume) {
  volume.computer = deviceSysId;
  volume.media_type = 'fixed';
  volume.location = locationId;
  volume.lun = '' + volume.lun;
}

function fixupDisk(disk) {
  disk.computer = deviceSysId;
  disk.storage_type = 'disk';
  disk.drive_type = 'disk';   // deprecated
  disk.location = locationId;

  if (disk.mf) {
  	var makeModel = MakeAndModelJS.fromNames(disk.mf, null);
  	disk.manufacturer = '' + makeModel.getManufacturerSysID();
  	disk.model_id = '' + makeModel.getModelNameSysID();
  	disk.device_interface = validIntfs[disk.intf.toLowerCase()];
  	disk['interface'] = disk.device_interface;  // An SN bug doesn't allow "disk.interface".  Also this field is deprecated.
  }
}

function fixupStoragePool(pool) {
  pool.hosted_by = deviceSysId;
  pool.short_description = pool.name;
  pool.location = locationId;
}

function fixupStorageController(controller) {
  controller.computer = deviceSysId;
  controller.location = locationId;
}

function fixupFcPort(port) {
  port.computer = port.computer || deviceSysId;
  port.location = locationId;
  port.wwnn = StorageWWN.parse(port.wwnn);
  var parsedWWPN = StorageWWN.parse(port.wwpn);
  var emptyWWPN = '00:00:00:00:00:00:00:00';
  // StorageWWN.parse() should return nothing when it can't parse the WWPN, but it returns
  // all zeros instead. Fixing StorageWWN would have side effects in Windows & Linux storage
  // sensors for existing customers, so we're forced to use this hack instead of handling it at the source StorageWWN.parse().
  // Since some  FcPorts may not have a permanent address(WWPN) so, we are adding this hack to keep this field as empty.
  // Empty WWPN  prevents it from getting inserted to the cmdb.
  port.wwpn = parsedWWPN === emptyWWPN ? undefined : parsedWWPN ;
  port.port_type = new DiscoveryFcPortType(port.port_type).getPortType();
  port.speed = DiscoveryDataRate.toGFC(port.speed) + ' GFC';
}

function fixupIScsiExport(iScsiExport) {
  fixupExport(iScsiExport);
  iScsiExport.name += ' IQN ' + iScsiExport.initiator_iqn;
}

function fixupFcExport(fcExport) {
  fixupExport(fcExport);
  fcExport.name += ' LUN ' + fcExport.storage.lun;
  fcExport.initiator_wwpn = StorageWWN.parse(fcExport.initiator_wwpn);
}

function fixupExport(commonExport) {
  var volume = commonExport.storage;
  
  commonExport.name = volume.name;
  commonExport.export_id = volume.name + '--' + commonExport.exported_by.name;
  commonExport.hosted_by = deviceSysId;
  commonExport.location = locationId;
}

function fixupStorageServer(server) {
  server.usedBy = device;
  var makeModel = MakeAndModelJS.fromNames(server.mf, server.mi, 'hardware');
  server.manufacturer = '' + makeModel.getManufacturerSysID();
  server.model_id = '' + makeModel.getModelNameSysID();
}

})();

Sys ID

bc0a8aef8f222200c2fe0b5437bdee57

Offical Documentation

Official Docs: