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 initialize_drives(cls, redfishConfig): inited = False cls.drives = [] url = cls.get_uri(redfishConfig, 'Drives') Trace.log(TraceLevel.DEBUG, '++ initialize_drives: url={}'.format(url)) try: # GET DriveCollection link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) # Retrieve a listing of all drives for this system membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) totalDrives = int(membersCount) odataIds = JsonExtract.get_values(link.jsonData, "@odata.id") Trace.log(TraceLevel.DEBUG, '++ initialize_drives: membersCount={}, totalDrives={}'.format(membersCount, totalDrives)) # Don't include the main @odata.id for the Drive Collection, all others are Drives/#.# if (url[-1] == '/'): url = url[:-1] if (len(odataIds) > 0): odataIds.remove(url) for driveUrl in odataIds: Trace.log(TraceLevel.TRACE, '++ extracting data for driveUrl={}'.format(driveUrl)) link = UrlAccess.process_request(redfishConfig, UrlStatus(driveUrl), 'GET', True, None) drive_number = JsonExtract.get_value(link.jsonData, None, 'Id', 1) serial_number = JsonExtract.get_value(link.jsonData, None, 'SerialNumber', 1) speed = JsonExtract.get_value(link.jsonData, None, 'NegotiatedSpeedGbs', 1) capacity = JsonExtract.get_value(link.jsonData, None, 'CapacityBytes', 1) block_size = JsonExtract.get_value(link.jsonData, None, 'BlockSizeBytes', 1) state = JsonExtract.get_value(link.jsonData, 'Status', 'State', 1) health = JsonExtract.get_value(link.jsonData, 'Status', 'Health', 1) # If the drive is linked to one or more volumes, it is already in use. volumes = JsonExtract.get_value(link.jsonData, 'Volumes', '@odata.id', 1) inUse = False if volumes is not None: inUse = True driveInfo = {'inUse': inUse, 'number': drive_number, 'serial': serial_number, 'speed': speed, 'capacity': capacity, 'size': block_size, 'state': state, 'health': health} Trace.log(TraceLevel.VERBOSE, '++ initialize_drives: {0: >6} / {1} - {2: >24}'.format(drive_number, inUse, serial_number)) cls.drives.append(driveInfo) cls.drives.sort(key=lambda k: k['number'], reverse=False) inited = True Trace.log(TraceLevel.VERBOSE, '++ initialize_drives: inited={}'.format(inited)) except Exception as e: Trace.log(TraceLevel.ERROR, '-- Unable to initialize drives, exception: {}'.format(e)) inited = False Trace.log(TraceLevel.DEBUG, '++ initialize_disks: {} drives added'.format(len(cls.drives))) Trace.log(TraceLevel.TRACE, '@@ drives: {}'.format(cls.drives)) return inited
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 initialize_initiators(cls, redfishConfig): inited = False cls.initiators = [] url = RedfishSystem.get_uri(redfishConfig, 'EndpointGroups') Trace.log(TraceLevel.DEBUG, '++ initialize_initiators: url={}'.format(url)) try: # GET DriveCollection link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True, None) # Retrieve a listing of all drives for this system membersCount = JsonExtract.get_value(link.jsonData, None, '*****@*****.**', 1) totalItems = int(membersCount) odataIds = JsonExtract.get_values(link.jsonData, "@odata.id") Trace.log(TraceLevel.DEBUG, '++ odataIds: {}'.format(odataIds)) Trace.log(TraceLevel.DEBUG, '++ initialize_initiators: membersCount={}, totalDrives={}'.format(membersCount, totalItems)) # Don't include the main @odata.id for the Drive Collection, all others are Drives/#.# if (url[-1] == '/'): url = url[:-1] if (len(odataIds) > 0): odataIds.remove(url) for itemUrl in odataIds: Trace.log(TraceLevel.DEBUG, '++ extracting data for Url={}'.format(itemUrl)) link = UrlAccess.process_request(redfishConfig, UrlStatus(itemUrl), 'GET', True, None) if ('GroupType' in link.jsonData): groupType = link.jsonData['GroupType'] if ((groupType == "Client") and ('All' not in link.jsonData['Id'])): endpoints = link.jsonData['Endpoints'] for i in range(len(endpoints)): # Example: "@odata.id": "/redfish/v1/StorageServices/S1/EndpointGroups/500605b00ab61310" endpointUri = endpoints[i]['@odata.id'] Trace.log(TraceLevel.DEBUG, ' ++ Adding initiator: ({})'.format(endpointUri)) link2 = UrlAccess.process_request(redfishConfig, UrlStatus(endpointUri)) if (link2.valid): newItem = link2.jsonData['Id'] if (newItem not in cls.initiators): Trace.log(TraceLevel.DEBUG, ' ++ Initiator: {}'.format(newItem)) cls.initiators.append(newItem) inited = True except Exception as e: Trace.log(TraceLevel.ERROR, '-- Unable to initialize initiators, exception: {}'.format(e)) inited = False Trace.log(TraceLevel.VERBOSE, '++ initialize_initiators: inited={}, count={}'.format(inited, len(cls.initiators))) Trace.log(TraceLevel.DEBUG, '@@ initiators: {}'.format(cls.initiators)) return inited
def init_from_url(self, redfishConfig, url): Trace.log(TraceLevel.DEBUG, ' ++ Init from URL {}'.format(url)) valid = False link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) if (link.valid): Trace.log( TraceLevel.DEBUG, ' ++ Item: ({}, {})'.format(link.jsonData['Name'], link.jsonData['GroupType'])) # Extract the Endpoint URI if this item has GroupType == Server try: self.GroupType = link.jsonData['GroupType'] if ((self.GroupType == "Client") and ('All' not in link.jsonData['Id'])): endpoints = link.jsonData['Endpoints'] for i in range(len(endpoints)): # Example: "@odata.id": "/redfish/v1/StorageServices/S1/EndpointGroups/500605b00ab61310" self.EndpointURI = endpoints[i]['@odata.id'] Trace.log(TraceLevel.DEBUG, ' ++ Examine: ({})'.format(self.EndpointURI)) link2 = UrlAccess.process_request( redfishConfig, UrlStatus(self.EndpointURI)) if (link2.valid): Trace.log( TraceLevel.DEBUG, ' ++ Endpoint: ({}, {})'.format( link2.jsonData['Name'], link2.jsonData['Id'])) self.Name = link2.jsonData['Name'] self.Description = link2.jsonData['Description'] status = link2.jsonData['Status'] self.State = status['State'] self.Health = status['Health'] ids = link2.jsonData['Identifiers'] self.DurableName = ids[0]['DurableName'] self.Id = link2.jsonData['Id'] valid = True except: self.Description = 'Unknown' return (valid)
def process_json(self, redfishConfig, url): # GET DriveCollection Trace.log(TraceLevel.VERBOSE, '++ GET Drive collection from ({})'.format(url)) self.link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) # Retrieve a listing of all drives for this system if (self.link.valid and self.link.jsonData): totalDrives = 0 createdDrives = 0 driveUrls = [] # Create a list of all the drive URLs for (key, value) in self.link.jsonData.items(): if (key == '*****@*****.**'): totalDrives = value elif (key == 'Members'): for driveLink in value: driveUrls.append(driveLink['@odata.id']) createdDrives += 1 # Create Drive object based on each drive URL if (createdDrives > 0 and createdDrives == totalDrives): for i in range(len(driveUrls)): Trace.log(TraceLevel.VERBOSE, ' -- GET Drive data ({0: >3}) of ({1: >3}) url ({2})'.format(i, len(driveUrls), driveUrls[i])) disk = DiskInformation() disk.init_from_url(redfishConfig, driveUrls[i]) self.disks.append(disk) else: Trace.log(TraceLevel.ERROR, ' ++ CommandHandler: Drive information mismatch: [email protected] ({}), Memebers {}'.format(totalDrives, createdDrives))
def process_json(self, redfishConfig, url): Trace.log( TraceLevel.TRACE, ' ++ CommandHandler: redfish urls // process_json url ({})'. format(url)) link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True) self.allLinks[url] = link self.dump_links(self) self.add_links(self, link.jsonData, '') # While there are still URLs to check, continue to GET links and process until all links have been checked while self.links_to_check(self): sleepTime = redfishConfig.get_value('linktestdelay') if (sleepTime): time.sleep(sleepTime) Trace.log( TraceLevel.INFO, ' .. urls total ({}) urls to process ({})'.format( len(self.allLinks), self.total_links_to_check(self))) nextLink = self.get_next_link(self) if (nextLink != None): Trace.log(TraceLevel.DEBUG, '... process_url ({})'.format(nextLink.url)) self.process_next_url(redfishConfig, nextLink)
def test_serviceroot(self): # Verify GET /redfish/v1 returns expected JSON data Trace.log( TraceLevel.VERBOSE, '>> Run {}.{}:{}'.format( type(self).__name__, sys._getframe().f_code.co_name, sys._getframe().f_lineno)) url = self.versionUrl link = UrlAccess.process_request(self.redfishConfig, UrlStatus(url), 'GET', False, None) TestSupport.test_link_status(self, link, url) expected = [("@odata.context", "/redfish/v1/$metadata#ServiceRoot.ServiceRoot"), ("@odata.id", "/redfish/v1/"), ("@odata.type", "#ServiceRoot.v1_2_0.ServiceRoot"), ("Id", "RootService"), ("Name", "Root Service"), ("RedfishVersion", None), ("UUID", None)] TestSupport.test_root_tags(self, link.jsonData, expected) expected = [ ("Systems", "@odata.id", "/redfish/v1/ComputerSystem"), ("Chassis", "@odata.id", "/redfish/v1/Chassis"), ("StorageServices", "@odata.id", "/redfish/v1/StorageServices"), ("Managers", "@odata.id", "/redfish/v1/Managers"), ("Tasks", "@odata.id", "/redfish/v1/TaskService"), ("SessionService", "@odata.id", "/redfish/v1/SessionService"), ] TestSupport.test_nested_tags(self, link.jsonData, expected)
def process_json(self, redfishConfig, url): # GET Thermal Collection for thermalUrl in url: Trace.log(TraceLevel.DEBUG, '++ GET collection from ({})'.format(thermalUrl)) self.link = UrlAccess.process_request(redfishConfig, UrlStatus(thermalUrl)) # Retrieve a listing of all fans for this system if (self.link.valid): # Create a list of all the URLs for (key, value) in self.link.jsonData.items(): Trace.log(TraceLevel.TRACE, ' ++ Fans collection: key={} value={}'.format(key, value)) if (key == 'Fans'): for link in value: Trace.log(TraceLevel.DEBUG, ' ++ process item {}'.format(link['@odata.id'])) words = link['@odata.id'].split('/') if (len(words) >= 4): enclosure = words[4] else: enclosure = 'unknown' MemberId = link['MemberId'] Reading = str(link['Reading']) Name = link['Name'] statusDict = link['Status'] StatusState = statusDict['State'] StatusHealth = statusDict['Health'] item = FanInformation(enclosure, MemberId, Reading, Name, StatusState, StatusHealth) self.readings.append(item)
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 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): # GET Thermal Collection for thermalUrl in url: Trace.log(TraceLevel.VERBOSE, '++ GET Thermal collection from ({})'.format(thermalUrl)) self.link = UrlAccess.process_request(redfishConfig, UrlStatus(thermalUrl)) # Retrieve a listing of all temperatures for this system if (self.link.valid): # Create a list of all the URLs for (key, value) in self.link.jsonData.items(): Trace.log(TraceLevel.TRACE, ' ++ Thermal collection: key={} value={}'.format(key, value)) if (key == 'Temperatures'): for link in value: Trace.log(TraceLevel.TRACE, ' ++ process item {}'.format(link['@odata.id'])) words = link['@odata.id'].split('/') if (len(words) >= 4): Enclosure = words[4] else: Enclosure = 'unknown' MemberId = link['MemberId'] Name = link['Name'] ReadingCelsius = str(link['ReadingCelsius']) statusDict = link['Status'] StatusState = statusDict['State'] StatusHealth = statusDict['Health'] # Adjust certain strings SensorName = Name.replace('sensor_temp_', '') item = ThermalInformation(MemberId, Name, ReadingCelsius, SensorName, StatusState, StatusHealth, Enclosure) self.readings.append(item)
def process_json(self, redfishConfig, url): Trace.log(TraceLevel.INFO, '') Trace.log(TraceLevel.INFO, '++ Create StorageGroup: ({})...'.format(self.command)) jsonRequest = CreateStorageGroupRequestProperties( redfishConfig, self.command, True) if jsonRequest is not None: link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'POST', True, json.dumps(jsonRequest, 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.TRACE, ' -- {0: <14}: {1}'.format('Id', link.jsonData['Id'])) else: Trace.log(TraceLevel.TRACE, ' -- JSON data was (None)') else: Trace.log(TraceLevel.INFO, json.dumps(link.jsonData, indent=4)) else: Trace.log( TraceLevel.INFO, 'Unable to create JSON request data from command line: {}'. format(self.command))
def add_links(self, data, parent): Trace.log( TraceLevel.TRACE, ' ++ CommandHandler: add_links ({}) parent ({})'.format( data, parent)) if isinstance(data, dict): for k, v in data.items(): if isinstance(v, dict): Trace.log(TraceLevel.TRACE, ' ++ add_links dict ({})'.format(v)) self.add_links(self, v, k) elif isinstance(v, list): for i in v: Trace.log(TraceLevel.TRACE, ' ++ add_links list ({})'.format(i)) self.add_links(self, i, k) else: Trace.log( TraceLevel.TRACE, ' @@ {0: >20} : {1: >24} -- {2}'.format( parent, k, v)) if (k == '@odata.id'): if (v not in self.allLinks): Trace.log(TraceLevel.DEBUG, ' @@ ++ New Link: ({})'.format(v)) link = UrlStatus(v) self.allLinks[v] = link self.dump_links(self)
def process_json(self, redfishConfig, url): cmd = url.replace('run loop ', '', 1) words = cmd.split(' ') timings = [] Trace.log(TraceLevel.DEBUG, '++ words={} - {}'.format(len(words), words)) if (len(words) == 2): count = int(words[0]) uri = words[1] Trace.log(TraceLevel.DEBUG, '++ count={}, uri={}'.format(count, uri)) index = 1 while index < count + 1: link = UrlAccess.process_request(redfishConfig, UrlStatus(uri)) Trace.log( TraceLevel.INFO, '[{0:4}] [{1:18}] GET {2}'.format(index, link.elapsedMicroseconds, uri)) timings.append(link.elapsedMicroseconds) index += 1 average = sum(timings) / len(timings) Trace.log(TraceLevel.INFO, '') Trace.log(TraceLevel.INFO, 'Average : {:,}'.format(average)) else: Trace.log( TraceLevel.ERROR, 'run loop expects: [count] [uri] but has this string ({})'. format(url))
def process_json(self, redfishConfig, url): redfishConfig.sessionValid = False Trace.log(TraceLevel.INFO, '') Trace.log(TraceLevel.VERBOSE, '++ Establish Redfish session: ({})...'.format(url)) JsonBuilder.startNew() JsonBuilder.newElement('main', JsonType.DICT) JsonBuilder.addElement('main', JsonType.STRING, 'UserName', redfishConfig.get_value('username')) JsonBuilder.addElement('main', JsonType.STRING, 'Password', redfishConfig.get_value('password')) link = UrlAccess.process_request( redfishConfig, UrlStatus(url), 'POST', False, json.dumps(JsonBuilder.getElement('main'), indent=4)) Trace.log( TraceLevel.TRACE, ' -- urlStatus={} urlReason={}'.format(link.urlStatus, link.urlReason)) # HTTP 201 Created if (link.urlStatus == 201): if (link.jsonData != None): Label.encode(config.sessionIdVariable, link.jsonData['Id']) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('Id', link.jsonData['Id'])) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('Name', link.jsonData['Name'])) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('Description', link.jsonData['Description'])) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('UserName', link.jsonData['UserName'])) else: Trace.log(TraceLevel.TRACE, ' -- JSON data was (None)') link.sessionKey = link.response.getheader('x-auth-token', '') redfishConfig.sessionKey = link.sessionKey if (redfishConfig.sessionKey != ''): redfishConfig.sessionValid = True else: print('') print('[] URL : {}'.format(link.url)) print('[] Status : {}'.format(link.urlStatus)) print('[] Reason : {}'.format(link.urlReason)) print('')
def process_json(self, redfishConfig, url): Trace.log( TraceLevel.VERBOSE, ' ++ CommandHandler: redfish json // process_url ({})'.format( url)) link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', True) self.link = link
def initialize_service_root_uris(cls, redfishConfig): Trace.log(TraceLevel.DEBUG, '++ initialize_service_root_uris (BaseInit={})'.format(cls.successfulRootInit)) if (cls.successfulRootInit == True): return cls.systemDict = {} url = config.redfish cls.successfulRootInit = True try: # GET Redfish Version Trace.log(TraceLevel.TRACE, '++ GET Redfish Version from ({})'.format(url)) link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', False, None) if (link.valid and "v1" in link.jsonData): newValue = link.jsonData["v1"] cls.systemDict["Root"] = newValue cls.discovered_uri("Root", newValue) else: Trace.log(TraceLevel.ERROR, '-- System Init: Invalid URL link for ({})'.format(url)) cls.successfulRootInit = False # GET Redfish Root Services if (cls.successfulRootInit): link = UrlAccess.process_request(redfishConfig, UrlStatus(cls.systemDict["Root"]), 'GET', False, None) cls.store_uri("Systems", link) cls.store_uri("Chassis", link) cls.store_uri("StorageServices", link) cls.store_uri("Managers", link) cls.store_uri("Tasks", link) cls.store_uri("SessionService", link) cls.store_uri_value("Sessions", cls.systemDict["SessionService"] + 'Sessions/') cls.store_uri_value("metadata", cls.systemDict["Root"] + '$metadata/' ) cls.store_uri_value("odata", cls.systemDict["Root"] + 'odata/') except Exception as e: Trace.log(TraceLevel.ERROR, '-- Unable to initialize Service Root URIs, exception: {}'.format(e)) cls.successfulRootInit = False Trace.log(TraceLevel.DEBUG, '@@1 systemDict: {}'.format(cls.systemDict)) return cls.successfulRootInit
def process_json(self, redfishConfig, url): # GET DriveCollection Trace.log(TraceLevel.VERBOSE, '++ GET Session collection from ({})'.format(url)) self.link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) # Retrieve a listing of all sessions if (self.link.valid and self.link.jsonData): total = 0 created = 0 urls = [] Trace.log(TraceLevel.TRACE, ' -- <<< RESPONSE >>>>') Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format( 'x-auth-token', self.link.response.getheader('x-auth-token', ''))) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('version', self.link.response.version)) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('status', self.link.response.status)) Trace.log( TraceLevel.TRACE, ' -- {0: <12}: {1}'.format('reason', self.link.response.reason)) # Create a list of all the URLs for (key, value) in self.link.jsonData.items(): if (key == '*****@*****.**'): total = value elif (key == 'Members'): for link in value: urls.append(link['@odata.id']) created += 1 # Create object based on each URL if (created > 0 and created == total): for i in range(len(urls)): Trace.log( TraceLevel.VERBOSE, ' -- GET data ({0: >3}) of ({1: >3}) url ({2})'. format(i, len(urls), urls[i])) session = SessionInformation() session.init_from_url(redfishConfig, urls[i]) self.sessions.append(session) else: Trace.log( TraceLevel.ERROR, ' ++ CommandHandler: Information mismatch: [email protected] ({}), Memebers {}' .format(total, created))
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 fill_storage_services_id(cls, redfishConfig, key): if (key not in cls.systemDict): if ('StorageServicesId' not in cls.systemDict ): # GET StorageServices Identifier link = UrlAccess.process_request(redfishConfig, UrlStatus(cls.systemDict["StorageServices"]), 'GET', True, None) if (link.valid and link.jsonData is not None and 'Members' in link.jsonData): for member in link.jsonData["Members"]: newuri = member["@odata.id"] if (newuri[-1] != '/'): newuri = newuri + '/' cls.store_uri_value("StorageServicesId", newuri)
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 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 process_json(self, redfishConfig, url): link = UrlAccess.process_request(redfishConfig, UrlStatus(url), 'GET', False, None) self.valid = link.valid if (link.valid): for key in link.jsonData: self.version = key self.versionUrl = link.jsonData[key] else: Trace.log(TraceLevel.ERROR, ' ++ CommandHandler: redfish version // ERROR receiving data from ({}): Error {}: {}'.format(url, link.urlStatus, link.urlReason))
def test_version(self): # Verify GET /redfish returns JSON data with /redfish/v1/ Trace.log( TraceLevel.VERBOSE, '>> Run {}.{}:{}'.format( type(self).__name__, sys._getframe().f_code.co_name, sys._getframe().f_lineno)) url = self.root link = UrlAccess.process_request(self.redfishConfig, UrlStatus(url), 'GET', False, None) TestSupport.test_link_status(self, link, url) expected = [("v1", "/redfish/v1/")] TestSupport.test_root_tags(self, link.jsonData, expected)
def test_links(self): Trace.log( TraceLevel.VERBOSE, '>> Run {}.{}:{}'.format( type(self).__name__, sys._getframe().f_code.co_name, sys._getframe().f_lineno)) url = self.versionUrl link = UrlAccess.process_request(self.redfishConfig, UrlStatus(url), 'GET', False, None) TestSupport.test_link_status(self, link, url) RedfishCommand.execute(self.redfishConfig, 'create session') odataIds = JsonExtract.get_values(link.jsonData, "@odata.id") for url in odataIds: link = UrlAccess.process_request(self.redfishConfig, UrlStatus(url), 'GET', True, None) self.assertTrue(link.valid, 'Link valid for URL ({})'.format(url)) # Delete any current active session sessionId = Label.decode(config.sessionIdVariable) if sessionId is not None: RedfishCommand.execute(self.redfishConfig, f'delete sessions {sessionId}')
def init_from_url(self, redfishConfig, url): Trace.log(TraceLevel.DEBUG, ' ++ Init from URL {}'.format(url)) link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) if (link.valid): Trace.log( TraceLevel.DEBUG, ' ++ Session: ({}, {}, {}, {})'.format( link.jsonData['Id'], link.jsonData['Name'], link.jsonData['Description'], link.jsonData['UserName'])) self.Id = int(link.jsonData['Id']) self.Name = link.jsonData['Name'] self.Description = link.jsonData['Description'] self.UserName = link.jsonData['UserName']
def process_json(self, redfishConfig, url): # GET list of pools and disk groups self.link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) # Retrieve a listing of all storage groups for this system if (self.link.valid and self.link.jsonData): total = 0 created = 0 urls = [] # Create a list of URIs for (key, value) in self.link.jsonData.items(): if (key == '*****@*****.**'): total = value Trace.log(TraceLevel.VERBOSE, '.. GET total ({})'.format(total)) elif (key == 'Members'): Trace.log(TraceLevel.TRACE, '.. Members value ({})'.format(value)) if (value != None): for groupLink in value: url = groupLink['@odata.id'] Trace.log( TraceLevel.VERBOSE, '.. ADD storage group url ({})'.format(url)) urls.append(url) created += 1 # Create object based on each URL if (created > 0 and created == total): for i in range(len(urls)): Trace.log( TraceLevel.VERBOSE, '.. GET Storage Group data ({0: >3}) of ({1: >3}) url ({2})' .format(i, len(urls) - 1, urls[i])) group = StorageGroupInformation() if (group.init_from_url(redfishConfig, urls[i])): self.groups.append(group) elif (created > 0): Trace.log( TraceLevel.ERROR, ' ++ CommandHandler: Information mismatch: [email protected] ({}), Memebers {}' .format(total, created))
def process_json(self, redfishConfig, url): # GET Volumes self.link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) # Retrieve a listing of all volumes for this system if (self.link.valid and self.link.jsonData is not None): totalVolumes = 0 createdVolumes = 0 volumeUrls = [] # Create a list of all the volume URLs for (key, value) in self.link.jsonData.items(): if (key == '*****@*****.**'): totalVolumes = value Trace.log( TraceLevel.VERBOSE, '... GET volumes total ({})'.format(totalVolumes)) elif (key == 'Members'): Trace.log(TraceLevel.VERBOSE, '... Members value ({})'.format(value)) if (value != None): for volumeLink in value: Trace.log( TraceLevel.VERBOSE, '... ADD volume url ({})'.format( volumeLink['@odata.id'])) volumeUrls.append(volumeLink['@odata.id']) createdVolumes += 1 # Create Volume object based on each drive URL if (createdVolumes > 0 and createdVolumes == totalVolumes): for i in range(len(volumeUrls)): Trace.log( TraceLevel.VERBOSE, '... GET volume data ({0: >3}) of ({1: >3}) url ({2})'. format(i, len(volumeUrls), volumeUrls[i])) volume = VolumeInformation() volume.init_from_url(redfishConfig, volumeUrls[i]) self.volumes.append(volume) elif (createdVolumes > 0): Trace.log( TraceLevel.ERROR, ' ++ CommandHandler: Volume information mismatch: [email protected] ({}), Memebers {}' .format(totalVolumes, createdVolumes))
def init_from_url(self, redfishConfig, url): Trace.log(TraceLevel.DEBUG, ' ++ Disk init from URL {}'.format(url)) link = UrlAccess.process_request(redfishConfig, UrlStatus(url)) if (link.valid and link.jsonData is not None): if ('Id' in link.jsonData and 'CapacityBytes' in link.jsonData and 'SerialNumber' in link.jsonData and 'Manufacturer' in link.jsonData and 'Protocol' in link.jsonData): Trace.log(TraceLevel.DEBUG, ' ++ Disk: ({}, {}, {}, {}, {})'.format( link.jsonData['Id'], link.jsonData['CapacityBytes'], link.jsonData['SerialNumber'], link.jsonData['Manufacturer'], link.jsonData['Protocol'])) if ('Id' in link.jsonData): self.Id = link.jsonData['Id'] if ('Name' in link.jsonData): self.Name = link.jsonData['Name'] if ('SerialNumber' in link.jsonData): self.SerialNumber = link.jsonData['SerialNumber'] if ('Manufacturer' in link.jsonData): self.Manufacturer = link.jsonData['Manufacturer'] if ('Revision' in link.jsonData): self.Revision = link.jsonData['Revision'] if ('PartNumber' in link.jsonData): self.PartNumber = link.jsonData['PartNumber'] if ('NegotiatedSpeedGbs' in link.jsonData): self.NegotiatedSpeedGbs = link.jsonData['NegotiatedSpeedGbs'] if ('CapacityBytes' in link.jsonData): self.CapacityBytes = link.jsonData['CapacityBytes'] if ('BlockSizeBytes' in link.jsonData): self.BlockSizeBytes = link.jsonData['BlockSizeBytes'] if ('Status' in link.jsonData): healthDict = link.jsonData['Status'] if ('Health' in healthDict): self.Health = healthDict['Health'] words = self.Id.split('.') if (len(words) >= 2): self.IdNumber = (100 * int(words[0])) + int(words[1])