def emc_inq(remotePath, fc_vols): try: output = sensorhelper.executeCommand(remotePath + ' -no_dots -wwn') except: log.info(remotePath + ' command failed, halting execution of disk discovery.') return fc_vols for line in output.splitlines(): # TODO look for other valid startswith lines if they exist # found /dev/vx/rdmp/ on gar-jamis if line.startswith('/dev/rdsk/'): s = line.split(':') if len(s) == 4: device = s[0].strip() name = device.split('/')[-1][:-2] # remove s2 from the end vendor = s[1].strip() prod = s[2].strip() # VRAID and RAID 5 products found uuid = s[3] # make sure wwn is in format of a UUID and proper type if len(uuid) == 32 and (prod == 'VPLEX' or (vendor == 'DGC' and 'RAID' in prod)): log.info('Found LUN: ' + line) uuid = uuid.upper() vsv = sensorhelper.newModelObject('cdm:dev.StorageVolume') # ManagedSystemName is SUPPOSED to be reserved for ITM/TMS integration, however the developers # have been using it all over the place as a hack vsv.setManagedSystemName(uuid) if name in fc_vols.keys(): fcv = fc_vols[name] # use existing else: fcv = sensorhelper.newModelObject('cdm:dev.FCVolume') fcv.setName(name) # create relationships bo = sensorhelper.newModelObject('cdm:dev.BasedOnExtent') bo.setSource(fcv) bo.setTarget(vsv) bo.setType( 'com.collation.platform.model.topology.dev.BasedOnExtent' ) fcv.setBasedOn( sensorhelper.getArray([bo], 'cdm:dev.BasedOnExtent')) fc_vols[name] = fcv else: #result.warning('line parse unexpected:' + uuid) log.info('Skipping line:' + line) else: #result.warning('line parse unexpected:' + line) log.warning('line parse unexpected:' + line) return fc_vols
def buildVolume(uuid, vol): vsv = sensorhelper.newModelObject('cdm:dev.StorageVolume') # ManagedSystemName is SUPPOSED to be reserved for ITM/TMS integration, however the developers # have been using it all over the place as a hack vsv.setManagedSystemName(uuid) log.debug('Array volume:' + str(vsv)) # create relationships bo = sensorhelper.newModelObject('cdm:dev.BasedOnExtent') bo.setSource(vol) bo.setTarget(vsv) bo.setType('com.collation.platform.model.topology.dev.BasedOnExtent') vol.setBasedOn(sensorhelper.getArray([bo],'cdm:dev.BasedOnExtent')) log.debug('FC volume:' + str(vol)) return vol
def buildAppServer(version, vendor, product, desc, sp, path, obj_type): appserver = sensorhelper.newModelObject('cdm:app.AppServer') appserver.setKeyName('AppServer') appserver.setHost(computersystem) if obj_type: appserver.setObjectType(obj_type) if version: appserver.setProductVersion(version) if vendor: appserver.setVendorName(vendor) if product: appserver.setProductName(product) if desc: appserver.setDescription(desc) if sp: appserver.setServicePack(sp) # build bind address bindaddr = sensorhelper.newModelObject('cdm:net.CustomBindAddress') bindaddr.setPortNumber(0) bindaddr.setPath(path) # build IP for bind address ipaddr = sensorhelper.newModelObject('cdm:net.IpV4Address') ipaddr.setStringNotation(str(seed)) bindaddr.setPrimaryIpAddress(ipaddr) bindaddr.setIpAddress(ipaddr) appserver.setPrimarySAP(bindaddr) appserver.setLabel(computersystem.getFqdn() + ':' + path) # build process pool procpool = sensorhelper.newModelObject('cdm:app.ProcessPool') procpool.setParent(appserver) procpool.setName('ProcessPool') procpool.setCmdLine(path) appserver.setProcessPools( sensorhelper.getArray([ procpool, ], 'cdm:app.ProcessPool')) return appserver
def main(): ########################################################## # Main # Setup the various objects required for the extension ########################################################## try: (os_handle, result, computersystem, seed, log) = sensorhelper.init(targets) global log log.info( "powermt discovery extension started (written by Mat Davis - [email protected])." ) try: if helper.validateCommand('/sbin/powermt'): sudo = Validator() if sudo.validateSudo('/sbin/powermt'): output = sensorhelper.executeCommand( 'sudo /sbin/powermt display dev=all') else: log.info( '/sbin/powermt not in sudo, halting execution of disk discovery.' ) raise CommandNotFoundError('/sbin/powermt not in sudo') else: log.info( '/sbin/powermt not installed, halting execution of disk discovery.' ) raise CommandNotFoundError('/sbin/powermt not installed') except: log.info( 'sudo /sbin/powermt command failed, halting execution of disk discovery.' ) raise CommandNotFoundError('sudo /sbin/powermt command failed') disk = None uuid = None vvol = None fcvolumes = [] for line in output.splitlines(): if line.startswith('Pseudo name='): disk = line.split('=')[1] if line.startswith('Logical device ID='): uuid = line.split('=')[1].split(' ')[0] if len(line.split(' ')) > 3: vvol = line.split(' ')[3].replace('[', '').replace(']', '') elif len(line.split()) > 2: vvol = None else: log.info('Skipping line missing volume information: ' + line) disk = None uuid = None continue if disk: log.info(str(disk) + ' ' + str(uuid) + ' ' + str(vvol)) vsv = sensorhelper.newModelObject('cdm:dev.StorageVolume') if vvol: vsv.setName(vvol) vsv.setVirtual(True) # ManagedSystemName is SUPPOSED to be reserved for ITM/TMS integration, however the developers # have been using it all over the place as a hack vsv.setManagedSystemName(uuid) fcv = sensorhelper.newModelObject('cdm:dev.FCVolume') fcv.setName(disk) fcv.setParent(computersystem) # create relationships bo = sensorhelper.newModelObject('cdm:dev.BasedOnExtent') bo.setSource(fcv) bo.setTarget(vsv) bo.setType( 'com.collation.platform.model.topology.dev.BasedOnExtent' ) fcv.setBasedOn( sensorhelper.getArray([bo], 'cdm:dev.BasedOnExtent')) fcvolumes.append(fcv) # reset all values disk = None uuid = None vvol = None # DANGER! Do not create and store the vplex without updating ALL the virtual volume members on the vplex, you # open up the possibility of the StorageExtentCleanupAgent deleting a bunch of virtual volumes. # if any FC volumes discovered, we continue if len(fcvolumes) > 0: extents = [] # local disks local_disks = os_handle.getLocalDiskVolumes() if local_disks: for local_disk in local_disks: log.info('disk=' + str(local_disk)) match = False for fcv in fcvolumes: if fcv.getName() == local_disk.getName(): log.info('Found matching disk') extents.append(fcv) fcvolumes.remove(fcv) # remove from list match = True break if not match: extents.append(local_disk) # disk partitions partitions = os_handle.getDiskPartitions() if partitions: for partition in partitions: log.info('partition=' + str(partition)) extents.append(partition) # volumes try: volumes = os_handle.getStorageVolumes() if volumes: for volume in volumes: log.info('storage volume=' + str(volume)) extents.append(volume) except: log.info('Unable to find Storage Volumes') # if there are any FC volumes left then add to the end of the list for fcv in fcvolumes: log.info('Adding additional FC volume=' + str(fcv)) extents.append(fcv) computersystem.setStorageExtent( sensorhelper.getArray(extents, 'cdm:dev.StorageExtent')) log.info("powermt discovery extension ended.") except CommandNotFoundError: pass # quietly move on if powermt command is not found except: (ErrorType, ErrorValue, ErrorTB) = sys.exc_info() errMsg = 'Unexpected error occurred during discover: ' + str( ErrorValue) LogError(errMsg) result.warning(errMsg)
def main(): try: global log (os_handle, result, computersystem, seed, log) = sensorhelper.init(targets) log.info( "Solaris Fibre Channel discovery extension started (written by Mat Davis - [email protected])." ) # build skinny computersystem for storage performance cs = sensorhelper.newModelObject( 'cdm:sys.sun.SunSPARCUnitaryComputerSystem') if computersystem.hasSignature(): cs.setSignature(computersystem.getSignature()) elif computersystem.hasSerialNumber() and computersystem.hasModel( ) and computersystem.hasManufacturer(): cs.setSerialNumber(computersystem.getSerialNumber()) cs.setModel(computersystem.getModel()) cs.setManufacturer(computersystem.getManufacturer()) else: log.info( 'Could not find naming rules to build skinny computer system, storage performance might suffer from using full computer system' ) cs = computersystem fc_vols = fcinfo() # only run EMC INQ if physical is_virtual = True # assume virtual if computersystem.hasModel( ) and not 'virtual' in computersystem.getModel().lower(): # model is set and does not contain 'virtual' if computersystem.hasVirtual(): if not computersystem.getVirtual(): is_virtual = False # virtual is set to False else: # virtual is not set and model does not contain 'virtual' is_virtual = False if is_virtual is False: # EMC inquiry tool can be downloaded from ftp://ftp.emc.com/pub/symm3000/inquiry/ # copy inq to targets inq = 'inq.sol64' path = coll_home + "/etc/templates/commands/extension-scripts/" + inq # TODO verify local path remotePath = os_handle.executeCommand('pwd').strip() if not remotePath.endswith('/'): remotePath = remotePath + '/' remotePath = remotePath + inq os_handle.copyToRemote(path, remotePath) sensorhelper.executeCommand('chmod +x ' + remotePath) # grant execute permission # check if command in sudo sudo = Validator() if sudo.validateSudo(remotePath): log.info(remotePath + ' found in sudoers, using sudo for command') remotePath = 'sudo ' + remotePath #fc_vols = emc_inq(remotePath, fc_vols) else: log.info('Virtual server detected, skipping EMC INQ discovery') # add all the FCVolumes to the extended result for fc_vol in fc_vols.values(): fc_vol.setParent(cs) # set parent if fc_vol.hasController(): fc_vol.getController().setParent(cs) result.addExtendedResult(fc_vol) log.info("Solaris Fibre Channel discovery extension ended.") except: (ErrorType, ErrorValue, ErrorTB) = sys.exc_info() errMsg = 'Unexpected error occurred during discover: ' + str( ErrorValue) LogError(errMsg) result.warning(errMsg)
def fcinfo(): fc_vols = {} # check if sudo is configured for fcinfo first, this way we won't trigger # a sudo alert if we run it and it fails sudo_list = sensorhelper.executeCommandWithTimeout('sudo -l', 30 * 1000) if sudo_list: if not re.search('.*fcinfo.*', sudo_list): log.info('fcinfo not in sudo') # don't attempt sudo fcinfo return fc_vols else: log.info('fcinfo not in sudo') # don't attempt sudo fcinfo return fc_vols if not helper.does_exist('/usr/sbin/fcinfo'): log.info('/usr/sbin/fcinfo does not exist') return fc_vols try: output = sensorhelper.executeCommand('sudo /usr/sbin/fcinfo hba-port') except: log.info('fcinfo command failed, halting execution of disk discovery.') return fc_vols for hba_line in output.splitlines(): if re.search('HBA Port WWN: [a-fA-F0-9]{16}', hba_line): hba_port_wwn = hba_line.split()[-1] hba_node_wwn = None elif re.search('Node WWN: [a-fA-F0-9]{16}', hba_line): hba_node_wwn = hba_line.split()[-1] log.info('Found HBA Port ' + hba_port_wwn + ' and Node ' + hba_node_wwn) scsi_pc = sensorhelper.newModelObject( 'cdm:dev.SCSIProtocolController') scsi_pc.setName(WorldWideNameUtils.toUniformString(hba_node_wwn)) #scsi_pc.setParent(cs) # parent set later at the end scsi_pe = sensorhelper.newModelObject( 'cdm:dev.SCSIProtocolEndPoint') scsi_pe.setName(WorldWideNameUtils.toUniformString(hba_port_wwn)) scsi_pe.setWorldWideName( WorldWideNameUtils.toUniformString(hba_port_wwn)) scsi_pe.setParent(scsi_pc) scsi_pc.setEndPoints( sensorhelper.getArray([scsi_pe], 'cdm:dev.SCSIProtocolEndPoint')) # continue now that we have the HBA port and node WWN rport_output = sensorhelper.executeCommand( 'sudo /usr/sbin/fcinfo remote-port -ls -p ' + hba_port_wwn) if rport_output: for line in rport_output.splitlines(): if re.search('LUN: [0-9]+', line): lun = line.split()[-1] elif re.search('Vendor: ', line): vendor = line.split()[-1] elif re.search('Product: ', line): product = line.split()[-1] elif re.search('OS Device Name: ', line): dev_name = line.split()[-1] if dev_name.startswith('/dev/rmt/'): log.info('Skipping tape drive: ' + dev_name) continue if dev_name == 'Unknown': log.info('Skipping OS Device Name \'Unknown\'') continue if dev_name.startswith('/devices/'): log.info('Skipping device under /devices: ' + dev_name) continue # build FCVolume log.info('Found LUN ' + lun + ' and device name ' + dev_name) name = dev_name.split('/')[-1][:-2] fcv = sensorhelper.newModelObject('cdm:dev.FCVolume') fcv.setSCSILun(long(lun)) fcv.setFCPLun(int(lun)) fcv.setName(name) fcv.setPortWWN( WorldWideNameUtils.toUniformString(hba_port_wwn)) fcv.setNodeWWN( WorldWideNameUtils.toUniformString(hba_node_wwn)) fcv.setController(scsi_pc) log.debug(str(fcv)) fc_vols[name] = fcv return fc_vols
# a sudo alert if we run it and it fails sudo = Validator() if sudo.validateSudo('sg_inq') is False: raise Exception() # don't attempt sudo sg_inq # use sudo sg_inq -i <device> for line in output.splitlines(): if re.search('.*EMC.*', line) or ( re.search('.*DGC.*', line) and re.search('.*RAID.*', line) ): disk = line.split()[-1] name = disk.split('/')[-1] vol = None if name in vols.keys(): vol = vols[name] # use existing sg_inq(disk, vol) else: vol = sensorhelper.newModelObject('cdm:dev.FCVolume') # create SCSIVolume if RDM instead of FCVolume if is_vmware: vol = sensorhelper.newModelObject('cdm:dev.SCSIVolume') vol.setDescription('RDM') vol.setParent(computersystem) vol.setName(name) vol.setDeviceID(disk) sg_vol = sg_inq(disk, vol) if sg_vol: result.addExtendedResult(vol) except: log.warning('Failed to run sudo sg_inq on target') # get lsscsi version to decide how to proceed version = sensorhelper.executeCommand('lsscsi -V 2>&1')
log.info('Malformed disk number, skipping disk harddisk??') continue uuid = line.split('=')[1].split(' ')[0] if len(line.split(' ')) > 3: vol_name = line.split(' ')[3].replace('[', '').replace(']','') elif len(line.split()) > 2: vol_name = None else: log.info('Skipping line missing volume information: ' + line) disk = None uuid = None continue if disk: log.info(str(disk) + ' ' + str(uuid) + ' ' + str(vol_name)) lun = sensorhelper.newModelObject('cdm:dev.StorageVolume') if vol_name: lun.setName(vol_name) # ManagedSystemName is SUPPOSED to be reserved for ITM/TMS integration, however the developers # have been using it all over the place as a hack lun.setManagedSystemName(uuid) fcv = sensorhelper.newModelObject('cdm:dev.FCVolume') fcv.setName('Disk ' + disk) fcv.setParent(computersystem) # create relationships bo = sensorhelper.newModelObject('cdm:dev.BasedOnExtent') bo.setSource(fcv) bo.setTarget(lun) bo.setType('com.collation.platform.model.topology.dev.BasedOnExtent') fcv.setBasedOn(sensorhelper.getArray([bo],'cdm:dev.BasedOnExtent'))
def main(): try: LogInfo("Starting...") try: opts, args = getopt.getopt(sys.argv[1:], 'u:p:h', ['help']) except getopt.GetoptError, err: # print help information and exit: print str( err) # will print something like "option -a not recognized" usage() sys.exit(2) LogDebug("Options " + str(opts)) global userid userid = None global password password = None for o, a in opts: if o == "-u": userid = a elif o == "-p": password = a elif o in ("-h", "--help"): usage() sys.exit() else: assert False, "unhandled option" #------------------------------------------------ # Set Defaults... #------------------------------------------------ host = "localhost" # we default to localhost if userid is None: userid = "administrator" if password is None: password = "******" # # Initialize # LogDebug('Initializing database connection') props = TopologyManagerFactory.getProps() dbConn = connectToDB(props.getDbDriver(), props.getDbUrl(), props.getDbUser(), props.getDbPassword()) # cache the FCVolumes fcv_stmt = dbConn.createStatement() sql_query = ( 'SELECT ' + 'CS.GUID_C AS CS_GUID, FCV.DEVICEID_C AS DEVICEID, FCV.FCPLUN_C AS FCPLUN, ' + 'FCV.PORTWWN_C AS PORTWWN, FCV.NAME_C AS NAME, FCV.GUID_C AS GUID, ARRAYVOL.GUID_C AS ARRAYVOL_GUID ' + 'FROM BB_FCVOLUME55_V FCV ' + 'JOIN BB_COMPUTERSYSTEM40_V CS ON FCV.PK__PARENTSTORAGEEXTENT_C = CS.PK_C ' + 'LEFT OUTER JOIN BB_STORAGEEXTENTJDO_BASEDON_J FC_BO ON FCV.PK_C = FC_BO.PK__JDOID_C ' + 'LEFT OUTER JOIN BB_BASEDONEXTENT34_V BO ON BO.PK_C = FC_BO.PK__BASEDON_C ' + 'LEFT OUTER JOIN BB_STORAGEVOLUME95_V ARRAYVOL ON BO.TARGET_C = ARRAYVOL.GUID_C' ) fcv_data = fcv_stmt.executeQuery(sql_query) volumes = {} while fcv_data.next(): cs_guid = fcv_data.getString('CS_GUID') v = { 'deviceid': fcv_data.getString('DEVICEID'), 'FCPLun': fcv_data.getString('FCPLUN'), 'portWWN': fcv_data.getString('PORTWWN'), 'name': fcv_data.getString('NAME'), 'guid': fcv_data.getString('GUID'), 'arrayvol': fcv_data.getString('ARRAYVOL_GUID') } if cs_guid in volumes: volumes[cs_guid].append(v) else: volumes[cs_guid] = [v] fcv_data.close() fcv_data = None fcv_stmt.close() LogDebug('ComputerSystems with FC volumes:' + str(len(volumes))) # cache the SCSIVolumes also in case there are some SCSIVolumes that should be FCVolumes # scsi_stmt = dbConn.createStatement() # sql_query = ( # 'SELECT CS.GUID_C AS CS_GUID, SCSIVOL.DEVICEID_C AS DEVICEID, SCSIVOL.NAME_C AS NAME, SCSIVOL.SCSILUN_C AS SCSILUN, SCSIVOL.GUID_C AS SCSI_GUID ' + # 'FROM BB_SCSIVOLUME2_V SCSIVOL, BB_COMPUTERSYSTEM40_V CS WHERE SCSIVOL.PK__PARENTSTORAGEEXTENT_C = CS.PK_C AND CS.PK_C IN ' + # '( SELECT CS.PK_C ' + # 'FROM BB_FCVOLUME55_V FCV, BB_COMPUTERSYSTEM40_V CS WHERE FCV.PK__PARENTSTORAGEEXTENT_C = CS.PK_C )') # scsi_data = scsi_stmt.executeQuery(sql_query) # scsi_volumes = {} # while scsi_data.next(): # cs_guid = scsi_data.getString('CS_GUID') # v = {'deviceid': scsi_data.getString('DEVICEID'), 'SCSILun': scsi_data.getString('SCSILUN'), 'name': scsi_data.getString('NAME'), 'guid': scsi_data.getString('SCSI_GUID')} # if cs_guid in scsi_volumes: # scsi_volumes[cs_guid].append(v) # else: # scsi_volumes[cs_guid] = [v] # scsi_data.close() # scsi_stmt.close() # get SCSIPaths stmt = dbConn.createStatement() sql_query = ( 'SELECT ' + ' CS.GUID_C AS CS_GUID, CS.NAME_C AS CS_NAME, PATH.DESCRIPTION_C AS DESCRIPTION, ' + ' HEP.WORLDWIDENAME_C AS WWN, PATH.GUID_C AS PATH_GUID, ARRAYVOL.GUID_C AS ARRAYVOL_GUID ' + 'FROM BB_SCSIPATH21_V PATH, BB_SCSIPROTOCOLENDPOINT3_V HEP, ' + ' BB_SCSIPROTOCOLCONTROLLER20_V CONT, BB_COMPUTERSYSTEM40_V CS, ' + ' BB_STORAGEVOLUME95_V ARRAYVOL ' + 'WHERE PATH.LUN_C IS NULL AND ' + ' PATH.PK__VOLUME_C IS NULL AND ' + ' PATH.PK__HOSTENDPOINT_C = HEP.PK_C AND ' + ' HEP.PK__PARENTSCSIPROINT_4324E367C = CONT.PK_C AND ' + ' CONT.PK__PARENTPROTOCOLCONTROLLER_C = CS.PK_C AND ' + ' PATH.PK__ARRAYVOLUME_C = ARRAYVOL.PK_C') mo_data = stmt.executeQuery(sql_query) paths = [] while mo_data.next(): description = mo_data.getString('DESCRIPTION') # parse pathname from description desc_dict = dict(re.findall(r'(\S+)=(".*?"|\S+)', description)) name = None if 'pathname' in desc_dict: pathname = str(desc_dict['pathname']) name = pathname.split('/')[-1] elif 'part' in desc_dict: # if Windows then replace PHYSICALDRIVE with 'Disk ' pathname = str(desc_dict['part']).replace( 'PHYSICALDRIVE', 'Disk ') name = pathname else: LogDebug('Could not find pathname in description field: ' + str(description)) continue cs_guid = mo_data.getString('CS_GUID') wwn = mo_data.getString('WWN') path_guid = mo_data.getString('PATH_GUID') path_arrayvol = mo_data.getString('ARRAYVOL_GUID') LogDebug('pathname=' + pathname + ';path_guid=' + path_guid + ';cs_guid=' + cs_guid + ';wwn=' + wwn) found = False if cs_guid in volumes: # loop through all FC volumes on CS for volume in volumes[cs_guid]: # LogDebug('volume=' + str(volume)) # look for matching WWN and path # TODO arrayvol could be null on both? no scipath if (volume['portWWN'] == wwn or volume['arrayvol'] == path_arrayvol) and ( volume['deviceid'] == pathname or volume['name'] == name): LogDebug('volume=' + str(volume)) # loop again and look for volumes with the same FCPLun and matching WWN found_match = False for v in volumes[cs_guid]: # look for another volume on this CS with same WWN and LUN and different name if v['portWWN'] == wwn and v['FCPLun'] == volume[ 'FCPLun'] and not (v['deviceid'] == pathname or v['name'] == name): LogDebug('matching LUN volume=' + str(v)) found_match = True found = True # if no matching duplicate LUN/WWN combo then update the SCSIPath and volume FCPLun is set (otherwise matching on existing arrayvol) if found_match is False and not volume[ 'FCPLun'] is None: sPath = sensorhelper.newModelObject( 'cdm:dev.SCSIPath') sPath.setGuid(Guid(path_guid)) sPath.setLUN(int(volume['FCPLun'])) LogDebug(' Defining SCSIPath: ' + str(sPath)) paths.append(sPath) break else: # build relationships here instead of letting topoagent build due to the matching LUN/WWN fcv = sensorhelper.newModelObject( 'cdm:dev.FCVolume') fcv.setGuid(Guid(volume['guid'])) vsv = sensorhelper.newModelObject( 'cdm:dev.StorageVolume' ) # define virtual storage volume vsv.setGuid( Guid(mo_data.getString('ARRAYVOL_GUID'))) bo = sensorhelper.newModelObject( 'cdm:dev.BasedOnExtent') bo.setSource(fcv) bo.setTarget(vsv) bo.setType( 'com.collation.platform.model.topology.dev.BasedOnExtent' ) fcv.setBasedOn( sensorhelper.getArray([bo], 'cdm:dev.BasedOnExtent')) LogDebug(' Defining FCVolume: ' + str(fcv)) paths.append(fcv) # not messing with RealizesExtent from the other side because it has potential to cause issues #fcv = sensorhelper.newModelObject('cdm:dev.FCVolume') #fcv.setGuid(Guid(volume['guid'])) #vsv = sensorhelper.newModelObject('cdm:dev.StorageVolume') # define virtual storage volume #vsv.setGuid(Guid(mo_data.getString('ARRAYVOL_GUID'))) #realizes = sensorhelper.newModelObject('cdm:dev.RealizesExtent') #realizes.setSource(vsv) #realizes.setTarget(fcv) #realizes.setType('com.collation.platform.model.topology.dev.RealizesExtent') #vsv.setRealizedBy(realizes) #LogDebug(' Defining StorageVolume: ' + str(vsv)) #paths.append(vsv) # set scsipath Volume so it won't come up next time fcv = sensorhelper.newModelObject( 'cdm:dev.FCVolume') fcv.setGuid(Guid(volume['guid'])) sPath = sensorhelper.newModelObject( 'cdm:dev.SCSIPath') sPath.setGuid(Guid(path_guid)) sPath.setVolume(fcv) LogDebug(' Defining SCSIPath: ' + str(sPath)) paths.append(sPath) break else: LogInfo('No volumes for host ' + cs_guid) mo_data.close() stmt.close() dbConn.close() num_threads = 10 global output output = Output() mo_array = MO_Array(paths) threads = [] # only create enough threads needed if len(paths) < num_threads: num_threads = len(paths) for c in range(0, num_threads): t = threading.Thread(target=worker, args=(mo_array, )) t.start() threads.append(t) for t in threads: t.join()
def main(): try: global log (os_handle, result, computersystem, seed, log) = sensorhelper.init(targets) log.info( "EMC INQ discovery extension started (written by Mat Davis - [email protected])." ) os_type = helper.get_os_type(os_handle) is_vmware = helper.is_vmware(computersystem) # EMC inquiry tool can be downloaded from ftp://ftp.emc.com/pub/symm3000/inquiry/ if os_type == 'Linux': inq = 'inq.LinuxAMD64' if computersystem.hasArchitecture(): if computersystem.getArchitecture() == 'i686': inq = 'inq.linux' elif computersystem.getArchitecture() == 'ia64': inq = 'inq.LinuxIA64' else: # if arch command failed during computersystem discovery try: arch = sensorhelper.executeCommand('uname -m') if 'i686' in arch: inq = 'inq.linux' elif 'ia64' in arch: inq = 'inq.LinuxIA64' except: log.info('uname command failed, using ' + inq + ' as default command') elif os_type == 'Sun': inq = 'inq.sol64' if computersystem.hasArchitecture(): if computersystem.getArchitecture() == 'i86pc': inq = 'inq.solarisx86_64' else: # if arch command failed during computersystem discovery try: arch = sensorhelper.executeCommand('uname -m') if 'i86pc' in arch: inq = 'inq.solarisx86_64' except: log.info('uname command failed, using ' + inq + ' as default command') else: log.info('Unknown OS type') log.info("EMC INQ discovery extension ended.") return remotePath = '/usr/local/bin/' # check if INQ installed in /usr/local/bin/ if not helper.does_exist(remotePath + inq): # make sure home directory is writable before we continue if not helper.is_writable('.'): log.info( 'HOME directory is not writable, discovery cannot continue' ) return # copy inq to targets lpath = coll_home + "/etc/templates/commands/extension-scripts/" + inq # TODO verify local binary exists pwd = os_handle.executeCommand('pwd').strip() if not pwd.endswith('/'): pwd = pwd + '/' os_handle.copyToRemote(lpath, pwd + inq) sensorhelper.executeCommand('chmod +x ' + pwd + inq) # grant execute permission log.info(inq + ' not installed under ' + remotePath + ', binary was staged in ' + pwd) remotePath = pwd # check if command in sudo cmd = remotePath + inq sudo = Validator() cmd_sudo = sudo.validateSudo(cmd) log.info('command in sudo?: ' + str(cmd_sudo)) if cmd_sudo: cmd = 'sudo ' + remotePath + inq # get any previously discovered volumes vols = helper.get_volumes(result, log) try: # output = sensorhelper.executeCommand(cmd + ' -no_dots -vplex_wwn') output = sensorhelper.executeCommand(cmd + ' -no_dots -wwn') for line in output.splitlines(): # if line starts with /dev/ then we use this disk if (os_type == 'Linux' and line.startswith('/dev/')) or ( os_type == 'Sun' and line.startswith('/dev/rdsk/')): s = line.split(':') if len(s) == 4: device = s[0].strip() name = device.split('/')[-1] if os_type == 'Sun': name = name[:-2] # remove s2 from the end vendor = s[1].strip() prod = s[2].strip( ) # VRAID and RAID 5 products found on Solaris uuid = s[3] # make sure wwn is in format of a VPLEX UUID # if len(uuid) == 32: # make sure wwn is in format of a UUID and proper type if len(uuid) == 32 and (prod == 'VPLEX' or (vendor == 'DGC' and 'RAID' in prod)): log.info('Found LUN: ' + line) uuid = uuid.upper() vsv = sensorhelper.newModelObject( 'cdm:dev.StorageVolume') # ManagedSystemName is SUPPOSED to be reserved for ITM/TMS integration, however the developers # have been using it all over the place as a hack vsv.setManagedSystemName(uuid) vol = None if name in vols.keys(): vol = vols[name] # use existing else: cdm_type = 'cdm:dev.FCVolume' # create SCSIVolume if RDM instead of FCVolume if is_vmware: cdm_type = 'cdm:dev.SCSIVolume' vol = sensorhelper.newModelObject(cdm_type) vol.setParent(computersystem) vol.setName(name) result.addExtendedResult(vol) # create relationship bo = sensorhelper.newModelObject( 'cdm:dev.BasedOnExtent') bo.setSource(vol) bo.setTarget(vsv) bo.setType( 'com.collation.platform.model.topology.dev.BasedOnExtent' ) vol.setBasedOn( sensorhelper.getArray([bo], 'cdm:dev.BasedOnExtent')) else: #result.warning('line parse unexpected:' + uuid) log.info('Skipping line:' + line) else: #result.warning('line parse unexpected:' + line) log.warning('line parse unexpected:' + line) if line: log.info('last line: ' + line) else: log.info('last line is empty') xa = {} xa['sudo_emc'] = '' # check if last line is separator line (no output) if '-----' in line: log.info('sudo_emc: no output from command') if cmd_sudo: log.info('sudo_emc: sudo used') xa['sudo_emc'] = 'unexpected' # unexpected, if sudo is used it should produce output else: log.info('sudo_emc: no sudo used') # if physical Sun host, need sudo for command if os_type == 'Sun' and not helper.is_virtual( computersystem): # for ALL physical Sun hosts we want to run the EMC INQ tool log.info('sudo_emc: physical Sun') xa['sudo_emc'] = 'invalid' elif os_type == 'Linux': # EMC INQ is needed only if sg_inq not installed and lsscsi version < 0.26 # otherwise RDM.py can discover if not helper.validateCommand('sg_inq'): if helper.validateCommand('lsscsi'): version = sensorhelper.executeCommand( 'lsscsi -V 2>&1') if version and Decimal( version.split()[1]) < Decimal('0.26'): lsscsi_out = sensorhelper.executeCommand( 'lsscsi') # check if there are any EMC Invista or DGC (V)RAID disks if re.search('.*EMC.*', lsscsi_out) or re.search( '.*DGC.*', lsscsi_out): log.info( 'sg_inq not installed, lsscsi < 0.26, EMC disks found - sudo_emc = invalid' ) xa['sudo_emc'] = 'invalid' else: log.info( 'sg_inq and lsscsi not installed - sudo_emc = invalid' ) xa['sudo_emc'] = 'invalid' else: log.info('sudo_emc: output produced') if cmd_sudo: log.info('sudo_emc: sudo used') xa['sudo_emc'] = 'valid' else: log.info('sudo_emc: no sudo used') # nothing to do helper.setExtendedAttributes(computersystem, xa) except: # strip out sudo to test command executable if 'sudo' in cmd: cmd = cmd.replace('sudo ', '') if helper.is_exec(cmd): log.info( cmd + ' command failed, halting execution of disk discovery.') (ErrorType, ErrorValue, ErrorTB) = sys.exc_info() errMsg = 'Unexpected error occurred during discover: ' + str( ErrorValue) LogError(errMsg) result.warning(errMsg) helper.setExtendedAttributes(computersystem, {'sudo_emc': 'unexpected'}) else: # if command is not executable then we need sudo log.info(cmd + ' command is not executable') helper.setExtendedAttributes(computersystem, {'sudo_emc': 'invalid'}) log.info("EMC INQ discovery extension ended.") except: (ErrorType, ErrorValue, ErrorTB) = sys.exc_info() errMsg = 'Unexpected error occurred during discover: ' + str( ErrorValue) LogError(errMsg) result.warning(errMsg)
"VMware"): isVirtual = True if computersystem.hasOSRunning( ) and not computersystem.hasCPUCoresInstalled() and not isVirtual: CPUCoresInstalled = 0 CPUCoresEnabled = 0 CPUDiesInstalled = 0 CPUDiesEnabled = 0 os = computersystem.getOSRunning() # startswith makes sure to include "Windows Server 2008 64-bit" if os.hasOSName() and os.getOSName().startswith("Windows Server 2008"): procs = sensorhelper.getWmiCimV2Class('Win32_Processor') members = [] for idx in range(len(procs)): mo = sensorhelper.newModelObject('cdm:sys.CPU') mo.setParent(computersystem) mo.setIndexOrder(str(idx)) mo.setNumCPUs( Integer.parseInt(procs[idx]['NumberOfLogicalProcessors'])) CPUCoresInstalled = CPUCoresInstalled + Integer.parseInt( procs[idx]['NumberOfCores']) CPUDiesInstalled = CPUDiesInstalled + 1 members.append(mo) computersystem.setCPU(sensorhelper.getArray(members, 'cdm:sys.CPU')) elif os.hasOSName() and os.getOSName().startswith("Windows Server 2003"): log.info("OSRunning is Windows Server 2003") cs = sensorhelper.getWmiCimV2Class('Win32_ComputerSystem') if cs: # if this value is available then KB932370 has been applied
else: firstFolder = 1 continue task2run = columns[8] taskName = columns[1] status = columns[3] for task in taskList: # check if the executable contains the task to force and make sure it is enabled if task2run.find(task) != -1: if status == 'Disabled': LogInfo( 'Task ' + task + ' found but it is disabled, skipping discovery') continue LogInfo('Processing:' + taskName + ' ' + task2run) appserver = sensorhelper.newModelObject( 'cdm:app.AppServer') appserver.setKeyName('AppServer') appserver.setHost(server) appserver.setObjectType(task) # build bind address bindaddr = sensorhelper.newModelObject( 'cdm:net.CustomBindAddress') bindaddr.setPortNumber(0) bindaddr.setPath('ForcedServer.' + task) # build IP for bind address ipaddr = sensorhelper.newModelObject('cdm:net.IpV4Address') ipaddr.setStringNotation(str(seed)) bindaddr.setPrimaryIpAddress(ipaddr) bindaddr.setIpAddress(ipaddr) appserver.setPrimarySAP(bindaddr) appserver.setLabel(server.getFqdn() + ':ForcedServer.' +
LogError("Command execution failed") raise # make sure data directory is discovered so we can create the databases properly if dataDir is not None: # look for databases and parse out m = re.search('DB Name .*', output) # m2 = re.search('DB Create Date .*', output) if m is not None: match = str(m.group(0)) split = match.split('=') if len(split) > 1: value = split[1].strip() if value != '': log.debug('Defining database with name:' + value) module = sensorhelper.newModelObject( 'cdm:app.db.mssql.SqlServerModule') #db = sensorhelper.newModelObject('cdm:app.db.mssql.SqlServerDatabase') module.setName(value) #db.setName(value) module.setFileName(dataDir + '\\' + value + '.mdf') #db.setPrimaryDataFile(dataDir + '\\' + value + '.mdf') #module.setParent(sqlserver) module.setParent(appserver) #db.setParent(sqlserver) # get creation time # match = str(m2.group(0)) # split = match.split('=') # if len(split) > 1: # value = split[1].strip() # if value != '': # db.setCreationDate(value)
except: msg = 'redhat_cluster.py: The following file does not exist or is not readable: ' + cluster_conf_file LogError(msg) # throw up warning on discovery UI result.warning(msg) try: # get cluster name if doc is None: # use command if we can't read cluster.conf clustername = str(sensorhelper.executeCommand(cmanCommand + ' status | grep "Cluster Name" | awk -F: {\'print $2\'}')).strip() if len(clustername) == 0: raise Exception('cman_tool output not as expected, please make sure cman_tool command is working properly and sudo is set up if needed.') else: clustername = doc.getDocumentElement().getAttribute('name') cluster = sensorhelper.newModelObject('cdm:sys.ComputerSystemCluster') LogDebug('Setting cluster name to ' + clustername) cluster.setLoadBalancer(clustername) # this is the naming rule attribute for cluster # very important to identify the local node or else we can't attach the cluster to that localnode localnodename = str(sensorhelper.executeCommand(cmanCommand + ' status | grep "Node name" | awk -F: \'{print $2}\'')).strip() if len(localnodename) == 0: raise Exception('cman_tool output not as expected, please make sure cman_tool command is working properly and sudo is set up if needed.') # Iterate over all nodes and create each one if doc is None: nodes_output = sensorhelper.executeCommand(cmanCommand + ' nodes | tail -n +2 | awk \'{print $6}\'') if len(nodes_output) == 0: raise Exception('cman_tool output not as expected, please make sure cman_tool command is working properly and sudo is set up if needed.') nodenames = nodes_output.splitlines() # verify that only node names are included and not quorumd devices for nodename in nodenames:
device = s[0].strip() name = 'Disk ' + device.replace( '\\\\.\\PHYSICALDRIVE', '') array_serial = s[1].strip() adjust = 0 if len(s) == 6: adjust = 2 # skip SP and IP Address columns lun_hex = s[2 + adjust].strip() wwn = s[3 + adjust].strip() # make sure wwn is in format of a VPLEX UUID if len(wwn) == 32 and lun_hex != '0xffff': log.info('Building LUN for ' + name) # continue creating wwn = wwn.upper() #log.debug('device:' + device + ';serial:' + array_serial + ';wwn:' + wwn) vsv = sensorhelper.newModelObject( 'cdm:dev.StorageVolume') # ManagedSystemName is SUPPOSED to be reserved for ITM/TMS integration, however the developers # have been using it all over the place as a hack vsv.setManagedSystemName(wwn) #log.debug('VPLEX volume:' + str(vsv)) vol = None if name in vols.keys(): vol = vols[name] # use existing else: vol = sensorhelper.newModelObject( 'cdm:dev.FCVolume') # create SCSIVolume if RDM instead of FCVolume if is_vmware: vol = sensorhelper.newModelObject( 'cdm:dev.SCSIVolume')
computerSystem.getContextIp()) file = open('/tmp/cert_' + computerSystem.getContextIp()) for character in file.readlines(): if character.find("Public Key type") != -1: type = character.split(':')[1].strip() if character.find("Public Key bits") != -1: bits = character.split(':')[1].strip() if character.find("Not valid before") != -1: notValidBefore = character.split(':', 1)[1].strip() if character.find("Not valid after") != -1: notValidAfter = character.split(':', 1)[1].strip() os.remove('/tmp/cert_' + computerSystem.getContextIp()) try: cf = sensorhelper.newModelObject('cdm:app.CertificateFile') cf.setURI("certificate://" + computerSystem.getContextIp() + "/CertList") jmap = java.util.HashMap() jmap.put("type", type) jmap.put("bits", bits) jmap.put("Not Valid Before", notValidBefore) jmap.put("Not Valid After", notValidAfter) bos = java.io.ByteArrayOutputStream() oos = java.io.ObjectOutputStream(bos) oos.writeObject(jmap) oos.flush() data = bos.toByteArray() oos.close() bos.close() cf.setExtendedAttributes(data)