def test_create_storagegrpoup_1(self): Trace.log( TraceLevel.VERBOSE, '>> Run {}.{}:{}'.format( type(self).__name__, sys._getframe().f_code.co_name, sys._getframe().f_lineno)) self.assertTrue( self.systemInitialized, 'System could not be initialized ({})'.format( self.systemInitialized)) TestSupport.create_diskgroup_paged(self, self.redfishConfig, 'dgA01', 'A', 4, 'raid5') TestSupport.create_volume_paged(self, self.redfishConfig, 'TestVolume01', 'A', 10000000) ports = RedfishSystem.get_ports(self.redfishConfig) initiators = RedfishSystem.get_initiators(self.redfishConfig) TestSupport.create_storage_group(self, self.redfishConfig, '100', 'TestVolume01', 'read-write', ports, initiators) TestSupport.delete_volume(self, self.redfishConfig, 'TestVolume01') TestSupport.delete_pool(self, self.redfishConfig, 'A')
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 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 prepare_url(self, redfishConfig, command): commandFull = command.strip() Trace.log(TraceLevel.DEBUG, ' SET commandFull: ({})'.format(commandFull)) filename = commandFull.replace('run script ', '', 1) Trace.log(TraceLevel.DEBUG, ' SET filename: ({})'.format(filename)) return (filename)
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 process_next_url(self, redfishConfig, link): Trace.log( TraceLevel.TRACE, ' ++ CommandHandler: redfish urls // process_next_url ({})'. format(link.url)) UrlAccess.process_request(redfishConfig, link, 'GET', True) self.add_links(self, link.jsonData, '')
def display_results(self, redfishConfig): print('Redfish Services') print('---------------------') if (self.link.valid): print(json.dumps(self.link.jsonData, indent=4)) else: Trace.log(TraceLevel.ERROR, ' ++ CommandHandler: redfish services // ERROR receiving data from ({}): Error {}: {}'.format(self.link.url, self.link.urlStatus, self.link.urlReason))
def get_initiators(cls, redfishConfig): if (cls.successfulSystemInit == False): RedfishSystem.initialize_system(redfishConfig) initiators = ','.join(cls.initiators) Trace.log(TraceLevel.VERBOSE, '++ get_initiators: {}'.format(initiators)) return initiators
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 encode(cls, label, value): try: cls.ldict[str(label)] = value except Exception as e: Trace.log( TraceLevel.ERROR, ' -- encode: Unable to store label ({}) and vlaue {}: Exception: {}' .format(label, value, str(e))) pass
def extract_help(cls, brand): Trace.log(TraceLevel.DEBUG, 'extract_help_file: START ({})'.format(brand)) folder = 'commands/' + brand + '/*.py' list_of_files = glob.glob(folder) if (len(list_of_files) > 0): for filename in list_of_files: cls.extract_help_file(filename)
def dump_links(self): Trace.log(TraceLevel.TRACE, ' // allLinks -- count={}'.format(len(self.allLinks))) index = 0 for key in self.allLinks: link = self.allLinks[key] index += 1 Trace.log( TraceLevel.TRACE, ' // allLinks -- [{}/{}] key={} checked={} url={}'.format( index, len(self.allLinks), key, link.checked, link.url))
def resetElement(cls, name): for i in range(len(cls.elements)): if (cls.elements[i].name == name): if (isinstance(cls.elements[i].value, dict)): cls.elements[i].value = {} elif (isinstance(cls.elements[i].value, list)): cls.elements[i].value = [] else: Trace.log( TraceLevel.WARN, 'resetElement with name ({}) was not handled, type is ({})' .format(name, str(type(cls.elements[i].value))))
def prepare_url(self, redfishConfig, command): # Usage: redfish json <url> words = command.split(' ') if (len(words) > 2): self.startingurl = words[2] else: self.startingurl = '' Trace.log( TraceLevel.VERBOSE, ' ++ CommandHandler: redfish json // url ({})'.format( self.startingurl)) return (self.startingurl)
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 display_results(self, redfishConfig): if (redfishConfig.sessionValid == True): Trace.log( TraceLevel.INFO, '[] Redfish session established ({}:{})'.format( Label.decode(config.sessionIdVariable), redfishConfig.sessionKey)) else: Trace.log( TraceLevel.ERROR, 'Unable to establish a Redfish session, connection, check ip address, username and password' )
def addElement(cls, name, jsonType, label, value): jsonEntity = cls.getElement(name) if (jsonEntity is None): Trace.log( TraceLevel.ERROR, 'Could not find JSON element with name ({})'.format(name)) return Trace.log( TraceLevel.DEBUG, '++ addElement: name={} type={} label={} value={}'.format( name, JsonType.toType(jsonType), label, value)) # DICT if (isinstance(jsonEntity, dict)): Trace.log( TraceLevel.DEBUG, '++ addElement: DICT ({}) label={} value={}'.format( JsonType.toType(jsonType), label, value)) if (jsonType == JsonType.STRING): jsonEntity.update({label: value}) elif (jsonType == JsonType.INTEGER): try: jsonEntity.update({label: int(value)}) except: Trace.log( TraceLevel.WARN, 'JsonBuilder.addElement could not convert value={} to integer, label={}' .format(value, label)) jsonEntity.update({label: 0}) pass elif (jsonType == JsonType.DICT): if (label == ''): jsonEntity.update(value) else: jsonEntity.update({label: value}) # LIST elif (isinstance(jsonEntity, list)): Trace.log( TraceLevel.DEBUG, '++ addElement: LIST ({}) label={} value={}'.format( JsonType.toType(jsonType), label, value)) if (jsonType == JsonType.STRING): jsonEntity.append(value) elif (jsonType == JsonType.DICT): if (label == ''): jsonEntity.append(value) else: jsonEntity.update({label: value})
def cmdloop(self, redfishConfig, prompt='redfish'): while 1: try: print('') sys.stdout.write('({}) '.format(prompt)) sys.stdout.flush() line = sys.stdin.readline().strip() except KeyboardInterrupt: break if not line: if (redfishConfig.get_bool('entertoexit')): break elif (line == 'exit' or line == 'quit'): break elif (line.startswith('alias')): # Add the new alias to the dictionary words = line.split(' ') if (len(words) == 3): alias = words[1] original = words[2] Trace.log( TraceLevel.INFO, ' ++ CFG: replacing ({}) with the alias ({})'.format( alias, original)) self.aliases[alias] = original else: Trace.log(TraceLevel.INFO, ' ++ usage: alias <new> <original>') elif (line.startswith('!')): Trace.log(TraceLevel.TRACE, ' CFG: [{0: >3}] {1}'.format(len(line), line)) redfishConfig.execute(line) else: Trace.log(TraceLevel.TRACE, '>> PROCESS line={}'.format(line)) # Check for the use of any alias words = line.split(' ') if (len(words) > 1): if (words[0] in self.aliases): line = line.replace(words[0], self.aliases[words[0]], 1) Trace.log(TraceLevel.TRACE, ' CMD: [{0: >3}] {1}'.format(len(line), line)) RedfishCommand.execute(redfishConfig, line)
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_create_diskgroup_paged_raid6(self): # Create a RAID6 disk group Trace.log( TraceLevel.VERBOSE, '>> Run {}.{}:{}'.format( type(self).__name__, sys._getframe().f_code.co_name, sys._getframe().f_lineno)) self.assertTrue( self.systemInitialized, 'System could not be initialized ({})'.format( self.systemInitialized)) TestSupport.create_diskgroup_paged(self, self.redfishConfig, 'dgA03', 'A', 6, 'raid6') TestSupport.delete_pool(self, self.redfishConfig, 'A')
def initialize_system(cls, redfishConfig): initialized = cls.successfulSystemInit if (initialized is False and redfishConfig.sessionValid): tempstatus = cls.initialize_drives(redfishConfig) Trace.log(TraceLevel.DEBUG, '++ initialize_system: initialize_drives={}'.format(tempstatus)) if (tempstatus == True): initialized = True else: initialized = False tempstatus = cls.initialize_ports(redfishConfig) Trace.log(TraceLevel.DEBUG, '++ initialize_system: initialize_ports={}'.format(tempstatus)) if (tempstatus == True): initialized = True else: initialized = False tempstatus = cls.initialize_initiators(redfishConfig) Trace.log(TraceLevel.DEBUG, '++ initialize_system: initialize_initiators={}'.format(tempstatus)) if (tempstatus == True): initialized = True else: initialized = False cls.successfulSystemInit = initialized Trace.log(TraceLevel.VERBOSE, '++ initialize_system: {}'.format(initialized)) return (initialized)
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 save(self): configurationfile = self.dictionary['configurationfile'] Trace.log( TraceLevel.VERBOSE, ' -- Save Redfish API configuration to ({})'.format( configurationfile)) try: with open(configurationfile, "w") as write_file: json.dump(self.dictionary, write_file, indent=4) except: Trace.log( TraceLevel.ERROR, ' -- Unable to save configuration to ({}) - check spelling'. format(configurationfile)) pass
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 displayJson(cls, name): Trace.log(TraceLevel.INFO, 'JsonBuilder displayJson (name={})'.format(name)) Trace.log(TraceLevel.INFO, '') Trace.log(TraceLevel.INFO, '[[ JSON DATA ]]') jsonEntity = cls.getElement(name) if (jsonEntity is not None): print(json.dumps(jsonEntity, indent=4)) else: Trace.log( TraceLevel.INFO, 'Could not find JSON element with name ({})'.format(name)) Trace.log(TraceLevel.INFO, '[[ JSON DATA END ]]')
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 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])
def get_next_available_drive(cls, redfishConfig): url = None drive_number = '' serial_number = '' if (cls.successfulSystemInit == False): RedfishSystem.initialize_system(redfishConfig) for drive in cls.drives: if drive['inUse'] == False: drive_number = drive['number'] serial_number = drive['serial'] url = cls.get_uri(redfishConfig, 'Drives') + drive_number drive['inUse'] = True Trace.log(TraceLevel.DEBUG, '++ get_next_available_drive: return drive {}, in use {}'.format(drive_number, drive['inUse'])) break return {'url': url, 'number': drive_number ,'serial': serial_number}