def init_from_url(self, redfishConfig, url): Trace.log(TraceLevel.DEBUG, ' ++ Storage Group init from URL {}'.format(url)) link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) endpointGroupsUrl = RedfishSystem.get_uri(redfishConfig, 'EndpointGroups') if (link.valid): Trace.log( TraceLevel.VERBOSE, ' ++ Storage Group: ({}, {})'.format(link.jsonData['Id'], link.jsonData['Name'])) try: self.Description = link.jsonData['Description'] self.SerialNumber = link.jsonData['Id'] self.MembersAreConsistent = link.jsonData[ 'MembersAreConsistent'] self.VolumesAreExposed = link.jsonData['VolumesAreExposed'] self.Name = link.jsonData['Name'] self.AccessState = link.jsonData['AccessState'] self.ClientEndpointGroups = [] ceg = link.jsonData['ClientEndpointGroups'] for i in range(len(ceg)): # Example: "@odata.id": "/redfish/v1/StorageServices/S1/EndpointGroups/500605b00ab61310" url = ceg[i]['@odata.id'].replace(endpointGroupsUrl, '') self.ClientEndpointGroups.append(url) self.ServerEndpointGroups = [] seg = link.jsonData['ServerEndpointGroups'] for i in range(len(seg)): # Example: "@odata.id": "/redfish/v1/StorageServices/S1/EndpointGroups/500605b00ab61310" url = seg[i]['@odata.id'].replace(endpointGroupsUrl, '') self.ServerEndpointGroups.append(url) mv = link.jsonData['MappedVolumes'] for i in range(len(mv)): # Example: "@odata.id": "/redfish/v1/StorageServices/S1/EndpointGroups/500605b00ab61310" self.LogicalUnitNumber = mv[i]['LogicalUnitNumber'] self.Volume = mv[i]['Volume']['@odata.id'].replace( RedfishSystem.get_uri(redfishConfig, 'Volumes'), '') status = link.jsonData['Status'] self.State = status['State'] self.Health = status['Health'] self.HealthRollup = status['HealthRollup'] except: self.Description = 'Unknown' # pass else: Trace.log( TraceLevel.VERBOSE, ' ++ Storage Group: link was not valid status={} reason={}'. format(link.urlStatus, link.urlReason)) return True
def process_json(self, redfishConfig, url): # Don't attempt to purge if a session is not active sessionId = Label.decode(config.sessionIdVariable) if sessionId is None: Trace.log( TraceLevel.INFO, '-- A valid session ({}) was not found!'.format(sessionId)) return # Purge all StorageGroups ids = super().get_members_list(self, redfishConfig, 'StorageGroups') super().delete_id_list( self, redfishConfig, RedfishSystem.get_uri(redfishConfig, 'StorageGroups'), ids) # Purge all Volumes ids = super().get_members_list(self, redfishConfig, 'Volumes') super().delete_id_list(self, redfishConfig, RedfishSystem.get_uri(redfishConfig, 'Volumes'), ids) # Purge all StoragePools ids = super().get_members_list(self, redfishConfig, 'StoragePools', 'A B') super().delete_id_list( self, redfishConfig, RedfishSystem.get_uri(redfishConfig, 'StoragePools'), ids)
def get_members_list(self, redfishConfig, collection, qualifier=''): ids = [] Trace.log( TraceLevel.DEBUG, ' ++ get_members_list from Redfish service: collection={}'. format(collection)) itemUrl = RedfishSystem.get_uri(redfishConfig, collection) if (not itemUrl): return Trace.log(TraceLevel.TRACE, ' Checking ({})'.format(itemUrl)) link = UrlAccess.process_request(redfishConfig, UrlStatus(itemUrl)) if (link.valid and link.jsonData is not None): if ('Members' in link.jsonData and '*****@*****.**' in link.jsonData and int(link.jsonData['*****@*****.**']) > 0): members = link.jsonData['Members'] for member in members: if ('@odata.id' in member): item = member['@odata.id'] words = item.split('/') if (len(words) > 1): itemId = words[len(words) - 1] if (qualifier == '' or itemId in qualifier): Trace.log( TraceLevel.TRACE, ' -- adding ({})'.format(itemId)) ids.append(itemId) Trace.log(TraceLevel.DEBUG, ' -- get_members_list returning ({})'.format(ids)) return (ids)
def create_volume_paged(cls, testObject, redfishConfig, desiredName, poolName, size): command = 'create volume name=' + desiredName + ' size=' + str(size) + ' pool=' + poolName RedfishCommand.execute(redfishConfig, command) # Validate that the volume exists url = RedfishSystem.get_uri(redfishConfig, 'Volumes') link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) cls.test_link_status(testObject, link, url) membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) testObject.assertEqual(membersCount, 1, 'Volumes [email protected], expected {}, received {}'.format(1, membersCount)) odataIds = JsonExtract.get_values(link.jsonData, "@odata.id") # Don't include the main @odata.id for the Collection if (url[-1] == '/'): url = url[:-1] if (len(odataIds) > 0): odataIds.remove(url) # Test name and size url = odataIds[0] link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) testObject.assertTrue(link.valid, 'Volume link valid for URL ({})'.format(url)) name = JsonExtract.get_value(link.jsonData, None, 'Name', 1) testObject.assertEqual(name, desiredName, 'Volume name error, expected {}, received {}'.format(desiredName, name)) capacity = JsonExtract.get_value(link.jsonData, None, 'CapacityBytes', 1) testObject.assertLessEqual(capacity, size, 'Volume size error, expected {}, received {}'.format(size, capacity))
def create_storage_group(cls, testObject, redfishConfig, lun, volume, access, ports, initiators): command = 'create storagegroup lun=\"' + lun + '\"' + ' volume=' + volume + ' access=' + access + ' ports=' + ports + ' initiators=' + initiators RedfishCommand.execute(redfishConfig, command) # Validate that the StorageGroup exists url = RedfishSystem.get_uri(redfishConfig, 'StorageGroups') link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) cls.test_link_status(testObject, link, url) membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) testObject.assertGreaterEqual(membersCount, 1, 'StorageGroups [email protected], expected {}, received {}'.format(1, membersCount)) odataIds = JsonExtract.get_values(link.jsonData, "@odata.id") # Don't include the main @odata.id for the Collection if (url[-1] == '/'): url = url[:-1] if (len(odataIds) > 0): odataIds.remove(url) # Test name url = odataIds[0] link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) testObject.assertTrue(link.valid, 'StorageGroup link valid for URL ({})'.format(url)) name = JsonExtract.get_value(link.jsonData, None, 'Name', 1) words = name.split('_') testObject.assertEqual(2, len(words), 'StorageGroup Name error, expected {}, received {}'.format(2, len(words))) volumeId = words[0] testObject.assertEqual(volume, volumeId, 'StorageGroup Volume Name error, expected {}, received {}'.format(volume, volumeId))
def delete_volume(cls, testObject, redfishConfig, desiredName): # Delete Volume RedfishCommand.execute(redfishConfig, 'delete volumes ' + desiredName) time.sleep(config.sleepTimeAfterDelete) url = RedfishSystem.get_uri(redfishConfig, 'Volumes') link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) cls.test_link_status(testObject, link, url) membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) testObject.assertEqual(membersCount, 0, 'Volumes [email protected], expected {}, received {}'.format(0, membersCount))
def delete_pool(cls, testObject, redfishConfig, poolName): # Remove Pool A and the disk group RedfishCommand.execute(redfishConfig, 'delete pools ' + poolName) time.sleep(config.sleepTimeAfterDelete) url = RedfishSystem.get_uri(redfishConfig, 'StoragePools') link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) cls.test_link_status(testObject, link, url) membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) testObject.assertEqual(membersCount, 0, 'StoragePools [email protected], expected {}, received {}'.format(0, membersCount))
def prepare_url(self, redfishConfig, command): # Usage: redfish urls [startingurl] self.allLinks = {} words = command.split(' ') if (len(words) > 2): self.startingurl = words[2] else: RedfishSystem.initialize_service_root_uris(redfishConfig) self.startingurl = RedfishSystem.get_uri(redfishConfig, 'Root') Trace.log( TraceLevel.INFO, ' ++ CommandHandler: redfish urls // starting url ({})'.format( self.startingurl)) return (self.startingurl)
def create_diskgroup_paged(cls, testObject, redfishConfig, desiredName, poolName, driveCount, raidLevel): # Create a disk group command = 'create diskgroup name=' + desiredName + ' disks=' while driveCount > 0: drive = RedfishSystem.get_next_available_drive(redfishConfig) command = command + drive['number'] driveCount -= 1 if driveCount: command = command + ',' command = command + ' pool=' + poolName + ' level=' + raidLevel RedfishCommand.execute(redfishConfig, command) # Validate that the disk group and Pool exist url = RedfishSystem.get_uri(redfishConfig, 'StoragePools') link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) cls.test_link_status(testObject, link, url) membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) testObject.assertEqual(membersCount, 2, 'StoragePools [email protected], expected {}, received {}'.format(2, membersCount)) odataIds = JsonExtract.get_values(link.jsonData, "@odata.id") # Don't include the main @odata.id for the Collection if (url[-1] == '/'): url = url[:-1] if (len(odataIds) > 0): odataIds.remove(url) for url in odataIds: link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) testObject.assertTrue(link.valid, 'StoragePool link valid for URL ({})'.format(url)) description = JsonExtract.get_value(link.jsonData, None, 'Description', 1) name = JsonExtract.get_value(link.jsonData, None, 'Name', 1) if description == 'DiskGroup': testObject.assertEqual(name, desiredName, 'StoragePool name error, expected {}, received {}'.format(desiredName, name)) elif description == 'Pool': testObject.assertEqual(name, poolName, 'StoragePool name error, expected {}, received {}'.format(poolName, name))
def prepare_url(self, redfishConfig, command): self.command = command return (RedfishSystem.get_uri(redfishConfig, 'Volumes'))
def prepare_url(self, redfishConfig, command): self.sessions = [] # RedfishSystem.initialize_service_root_uris(redfishConfig) return (RedfishSystem.get_uri(redfishConfig, 'Sessions'))
def prepare_url(self, redfishConfig, command): return (RedfishSystem.get_uri(redfishConfig, 'Sessions'))
def process_json(self, redfishConfig, url): Trace.log(TraceLevel.INFO, '') Trace.log(TraceLevel.INFO, '++ Create Disk Group: ({})...'.format(self.command)) drivesUrl = RedfishSystem.get_uri(redfishConfig, 'Drives') storagePoolsUrl = RedfishSystem.get_uri(redfishConfig, 'StoragePools') # From the command, build up the required JSON data # Example: 'create diskgroup name=dgA01 disks=0.7,0.8 pool=A level=raid1' # For now, use a simple split based on spaces JsonBuilder.startNew() JsonBuilder.newElement('main', JsonType.DICT) # Name jsonType, name = JsonBuilder.getValue('name', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.addElement('main', JsonType.STRING, 'Name', name) # CapacitySources jsonType, disks = JsonBuilder.getValue('disks', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.newElement('dict', JsonType.DICT, True) JsonBuilder.newElement('array', JsonType.ARRAY, True) if (jsonType is JsonType.ARRAY): for i in range(len(disks)): JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', drivesUrl + disks[i]) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) else: JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', drivesUrl + disks) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) JsonBuilder.addElement('dict', JsonType.DICT, 'ProvidingDrives', JsonBuilder.getElement('array')) JsonBuilder.addElement('main', JsonType.DICT, 'CapacitySources', JsonBuilder.getElement('dict')) # AllocatedPools jsonType, pool = JsonBuilder.getValue('pool', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.newElement('dict', JsonType.ARRAY, True) JsonBuilder.newElement('array', JsonType.ARRAY, True) if (jsonType is JsonType.ARRAY): for i in range(len(pool)): JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', storagePoolsUrl + pool[i]) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) else: JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', storagePoolsUrl + pool) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) JsonBuilder.addElement('dict', JsonType.DICT, 'Members', JsonBuilder.getElement('array')) JsonBuilder.addElement('main', JsonType.DICT, 'AllocatedPools', JsonBuilder.getElement('dict')) # ClassesOfService jsonType, level = JsonBuilder.getValue('level', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.newElement('dict', JsonType.DICT, True) JsonBuilder.addElement( 'dict', JsonType.STRING, '@odata.id', RedfishSystem.get_uri(redfishConfig, 'ClassesOfService') + level.upper()) JsonBuilder.addElement('main', JsonType.DICT, 'ClassesOfService', JsonBuilder.getElement('dict')) link = UrlAccess.process_request( redfishConfig, UrlStatus(url), 'POST', True, json.dumps(JsonBuilder.getElement('main'), indent=4)) Trace.log(TraceLevel.INFO, ' -- {0: <14}: {1}'.format('Status', link.urlStatus)) Trace.log(TraceLevel.INFO, ' -- {0: <14}: {1}'.format('Reason', link.urlReason)) # HTTP 201 Created if (link.urlStatus == 201): if (link.jsonData != None): Trace.log( TraceLevel.INFO, ' -- {0: <14}: {1}'.format('SerialNumber', link.jsonData['Name'])) Trace.log( TraceLevel.INFO, ' -- {0: <14}: {1}'.format('Id', link.jsonData['Id'])) else: Trace.log(TraceLevel.TRACE, ' -- JSON data was (None)') elif (link.urlStatus == 204): Trace.log(TraceLevel.TRACE, ' -- No representation of the created resource') else: Trace.log(TraceLevel.INFO, json.dumps(link.jsonData, indent=4))
def prepare_url(self, redfishConfig, command): RedfishSystem.initialize_service_root_uris(redfishConfig) return (RedfishSystem.get_uri(redfishConfig, 'metadata'))
def prepare_url(self, redfishConfig, command): self.groups = [] return (RedfishSystem.get_uri(redfishConfig, 'StorageGroups'))
def prepare_url(self, redfishConfig, command): self.disks = [] return (RedfishSystem.get_uri(redfishConfig, 'Drives'))
def prepare_url(self, redfishConfig, command): self.readings = [] return (RedfishSystem.get_uri(redfishConfig, 'Thermals'))
def process_json(self, redfishConfig, url): Trace.log(TraceLevel.INFO, '') Trace.log(TraceLevel.INFO, '++ Create Volume: ({})...'.format(self.command)) storagePoolsUrl = RedfishSystem.get_uri(redfishConfig, 'StoragePools') # From the command, build up the required JSON data # Example: create volume name=[name] size=[size] lun=[lun] pool=[A|B] diskgroup=[group] # For now, use a simple split based on spaces JsonBuilder.startNew() JsonBuilder.newElement('main', JsonType.DICT) # Name jsonType, name = JsonBuilder.getValue('name', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.addElement('main', JsonType.STRING, 'Name', name) # CapacityBytes jsonType, size = JsonBuilder.getValue('size', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.addElement('main', JsonType.INTEGER, 'CapacityBytes', size) # CapacitySources (virtual) jsonType, pool = JsonBuilder.getValue('pool', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.newElement('array', JsonType.ARRAY, True) if (jsonType is JsonType.ARRAY): for i in range(len(pool)): JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', storagePoolsUrl + pool[i]) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) else: JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', storagePoolsUrl + pool) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) JsonBuilder.addElement('main', JsonType.DICT, 'CapacitySources', JsonBuilder.getElement('array')) # CapacitySources (linera) jsonType, pool = JsonBuilder.getValue('diskgroup', self.command) if (jsonType is not JsonType.NONE): JsonBuilder.newElement('array', JsonType.ARRAY, True) if (jsonType is JsonType.ARRAY): for i in range(len(pool)): JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', storagePoolsUrl + pool[i]) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) else: JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement('dict2', JsonType.STRING, '@odata.id', storagePoolsUrl + pool) JsonBuilder.addElement('array', JsonType.DICT, '', JsonBuilder.getElement('dict2')) JsonBuilder.addElement('main', JsonType.DICT, 'CapacitySources', JsonBuilder.getElement('array')) # Links / ClassOfService JsonBuilder.newElement('dict', JsonType.DICT, True) JsonBuilder.newElement('dict2', JsonType.DICT, True) JsonBuilder.addElement( 'dict2', JsonType.STRING, '@odata.id', RedfishSystem.get_uri(redfishConfig, 'ClassesOfServiceDefault')) JsonBuilder.addElement('dict', JsonType.DICT, 'ClassOfService', JsonBuilder.getElement('dict2')) JsonBuilder.addElement('main', JsonType.DICT, 'Links', JsonBuilder.getElement('dict')) link = UrlAccess.process_request( redfishConfig, UrlStatus(url), 'POST', True, json.dumps(JsonBuilder.getElement('main'), indent=4)) Trace.log(TraceLevel.INFO, ' -- {0: <14}: {1}'.format('Status', link.urlStatus)) Trace.log(TraceLevel.INFO, ' -- {0: <14}: {1}'.format('Reason', link.urlReason)) # HTTP 201 Created if (link.urlStatus == 201): if (link.jsonData != None): Trace.log( TraceLevel.INFO, ' -- {0: <14}: {1}'.format('Name', link.jsonData['Name'])) Trace.log( TraceLevel.INFO, ' -- {0: <14}: {1}'.format('SerialNumber', link.jsonData['Id'])) else: Trace.log(TraceLevel.TRACE, ' -- JSON data was (None)') else: Trace.log(TraceLevel.INFO, json.dumps(link.jsonData, indent=4))
def process_json(self, redfishConfig, url): Trace.log(TraceLevel.DEBUG, '++ delete storagegroups ids: {}'.format(len(self.ids))) super().delete_id_list(self, redfishConfig, RedfishSystem.get_uri(redfishConfig, 'StorageGroups'), self.ids)
def prepare_url(self, redfishConfig, command): self.items = [] return (RedfishSystem.get_uri(redfishConfig, 'EndpointGroups'))
def process_json(self, redfishConfig, url): Trace.log(TraceLevel.DEBUG, '++ delete sessions: ids={}'.format(self.ids)) super().delete_id_list( self, redfishConfig, RedfishSystem.get_uri(redfishConfig, 'Sessions'), self.ids)
def prepare_url(self, redfishConfig, command): self.command = command return (RedfishSystem.get_uri(redfishConfig, 'StoragePools'))