# account name, and password to send https requests # SYSTEM_URL acceptable examples: # "https://10.0.0.100" # "https://ilo.hostname" SYSTEM_URL = "https://10.0.0.100" LOGIN_ACCOUNT = "admin" LOGIN_PASSWORD = "******" ESKM_USERNAME = "******" ESKM_PASSWORD = "******" ESKM_ACCOUNTGROUP = "group" ESKM_PRIMARYKEYSERVER_ADDR = "192.168.1.10" ESKM_PRIMARYKEYSERVER_PORT = 5927 # flag to force disable resource directory. Resource directory and associated operations are # intended for HPE servers. DISABLE_RESOURCE_DIR = False try: # Create a Redfish client object REDFISHOBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \ password=LOGIN_PASSWORD) # Login with the Redfish client REDFISHOBJ.login() except ServerDownOrUnreachableError as excp: sys.stderr.write("ERROR: server not reachable or does not support RedFish.\n") sys.exit() ESKM_username_pass(REDFISHOBJ, ESKM_USERNAME, ESKM_PASSWORD, ESKM_ACCOUNTGROUP, \ ESKM_PRIMARYKEYSERVER_ADDR, ESKM_PRIMARYKEYSERVER_PORT) REDFISHOBJ.logout()
class RedfishObject(object): def __init__(self, host, login_account, login_password): """ This function is to create redfish object Arguments: host {string} -- host url login_account {string} -- host username login_password {string} -- host password """ # Creating instace for RedfishClient clasee by providing ilo_url, ilo_username, ilo_password # Note:redfish.ris.tpdefs is not supported by python-ilorest-library 3.0 try: self.redfish_client = RedfishClient(base_url=host, username=login_account, password=login_password) except: raise self.redfish_client.login(auth=AuthMethod.SESSION) self.SYSTEMS_RESOURCES = self.ex1_get_resource_directory() self.MESSAGE_REGISTRIES = self.ex2_get_base_registry() def delete_obj(self): """ This function is to logout """ try: self.redfish_client.logout() except AttributeError as excp: pass def search_for_type(self, type): """ This function is to get redifsh resources """ instances = [] for item in self.SYSTEMS_RESOURCES["resources"]: foundsettings = False if "@odata.type" in item and type.lower( ) in item["@odata.type"].lower(): for entry in self.SYSTEMS_RESOURCES["resources"]: if (item["@odata.id"] + "/settings/").lower() == ( entry["@odata.id"]).lower(): foundsettings = True if not foundsettings: instances.append(item) if not instances: log_info("Resource or feature is not supported on this system:" + type) return instances def error_handler(self, response): """ This function is to display extnded info of error message Arguments: response {dict}: response of a rest call on specified host """ if not self.MESSAGE_REGISTRIES: log_info("ERROR: No message registries found.") try: message = json.loads(response.text) newmessage = message["error"]["@Message.ExtendedInfo"][0][ "MessageId"].split(".") except: log_info("No extended error information returned by iLO.") return for err_mesg in self.MESSAGE_REGISTRIES: if err_mesg != newmessage[0]: continue else: for err_entry in self.MESSAGE_REGISTRIES[err_mesg]: if err_entry == newmessage[3]: log_info( "iLO return code " + str(message["error"]["@Message.ExtendedInfo"][0]) + " : " + str(self.MESSAGE_REGISTRIES[err_mesg] [err_entry]["Description"])) def redfish_get(self, suburi): """ This function is to get redfish resources based on the specified uri Arguments: suburi {string}: redfish uri for the specified host """ return self.redfish_client.get(path=suburi) def redfish_patch(self, suburi, request_body): """ REDFISH PATCH Arguments: suburi {string}: redfish uri for the specified host request_body {dict}: resource content """ log_debug("PATCH " + str(request_body) + " to " + suburi) response = self.redfish_client.patch(path=suburi, body=request_body) log_debug("PATCH response: " + str(response.status)) return response def redfish_put(self, suburi, request_body): """ REDFISH PUT Arguments: suburi {string}: redfish uri for the specified host request_body {dict}: resource content """ log_debug("PUT " + str(request_body) + " to " + suburi) response = self.redfish_client.put(path=suburi, body=request_body) log_info("PUT response: " + str(response.status)) return response def redfish_post(self, suburi, request_body): """ REDFISH POST Arguments: suburi {string}: redfish uri for the specified host request_body {dict}: resource content """ log_info("POST " + str(request_body) + " to " + suburi) response = self.redfish_client.post(path=suburi, body=request_body) log_info("POST response: " + str(response.status)) return response def redfish_delete(self, suburi): """ REDFISH DELETE Arguments: suburi {string}: redfish uri for the specified host request_body {dict}: resource content """ log_info("DELETE " + suburi) response = self.redfish_client.delete(path=suburi) log_info("DELETE response: " + str(response.status)) return response def ex1_get_resource_directory(self): """ This function is to get resources of resource directory """ response = self.redfish_get("/redfish/v1/resourcedirectory/") resources = {} if response.status == 200: resources["resources"] = response.dict["Instances"] return resources else: log_info("\tResource directory missing at " \ "/redfish/v1/resourcedirectory" + "\n") def ex2_get_base_registry(self): """ This function is to get Registries resources """ response = self.redfish_get("/redfish/v1/Registries/") messages = {} location = None for entry in response.dict["Members"]: if not [x for x in ["/Base/", "/iLO/"] if x in entry["@odata.id"]]: continue else: registry = self.redfish_get(entry["@odata.id"]) for location in registry.dict["Location"]: if "extref" in location["Uri"]: location = location["Uri"]["extref"] else: location = location["Uri"] reg_resp = self.redfish_get(location) if reg_resp.status == 200: messages[reg_resp.dict["RegistryPrefix"]] = \ reg_resp.dict["Messages"] else: log_info("\t" + reg_resp.dict["RegistryPrefix"] + \ " not found at " + location + "\n") return messages
# Upload the firmware file to the iLO Repository update_repo_flag = True # Update the system with the firmware file update_target_flag = False comp_type = 'C' tpm_flag = True # flag to force disable resource directory. Resource directory and associated operations are # intended for HPE servers. DISABLE_RESOURCE_DIR = True try: # Create a Redfish client object redfish_obj = RedfishClient(base_url=system_url, username=options.ilo_user, password=options.ilo_pass) # Login with the Redfish client redfish_obj.login() except ServerDownOrUnreachableError as excp: sys.stderr.write( "ERROR: server not reachable or does not support RedFish.\n") sys.exit() upload_firmware(redfish_obj, options.comp_path, comp_type, update_repo_flag, update_target_flag) if comp_type == 'C': create_task(redfish_obj, options.comp_path, tpm_flag) redfish_obj.logout()
def getgen(self, gen=None, url=None, username=None, password=None, logger=None,\ proxy=None, ca_certs=None, isredfish=True): """Function designed to verify the servers platform :param url: The URL to perform the request on. :type url: str. :param logger: The logger handler. :type logger: str. """ if self.adminpriv is False and url.startswith("blob"): raise UserNotAdminError("") self.url = url self.is_redfish = isredfish self.gencompany = self.rootresp = False self.ilogen = 5 # If no iLO or Anonymous data , default to iLO 5 types logger = logger if not logger else LOGGER client = None self.noschemas = False self.schemapath = self.regpath = '' if not gen: try: client = RedfishClient(base_url=self.url, username=username, password=password,\ proxy=proxy, ca_certs=ca_certs) client._get_root() except ServerDownOrUnreachableError as excp: if self.is_redfish: raise excp if not self.is_redfish: try: restclient = LegacyRestClient(base_url=self.url, username=username, \ password=password, proxy=proxy, ca_certs=ca_certs) restclient._get_root() #Check that the response is actually legacy rest and not a redirect _ = restclient.root.Type self.is_redfish = False client = restclient except Exception as excep: if not client: logger.info("Gen get rest error:" + str(excep) + "\n") raise excep else: self.is_redfish = True rootresp = client.root.obj self.rootresp = rootresp client.logout() self.gencompany = next(iter(self.rootresp.get("Oem", {}).keys()), None) in ('Hpe', 'Hp') comp = 'Hp' if self.gencompany else None comp = 'Hpe' if rootresp.get("Oem", {}).get('Hpe', None) else comp if comp and next(iter(rootresp.get("Oem", {}).get(comp, {}).get("Manager", {}))).\ get('ManagerType', None): self.ilogen = next(iter(rootresp.get("Oem", {}).get(comp, {}).get("Manager", {})))\ .get("ManagerType") self.ilover = next(iter(rootresp.get("Oem", {}).get(comp, {}).get("Manager", {}))).\ get("ManagerFirmwareVersion") if self.ilogen.split(' ')[-1] == "CM": # Assume iLO 4 types in Moonshot self.ilogen = 4 self.iloversion = None else: self.iloversion = float(self.ilogen.split(' ')[-1] + '.' + \ ''.join(self.ilover.split('.'))) else: self.ilogen = int(gen) try: if not isinstance(self.ilogen, int): self.ilogen = int(self.ilogen.split(' ')[-1]) self.flagiften = True if int(self.ilogen) >= 5 else False except: raise UnableToObtainIloVersionError( "Unable to find the iLO generation.") self.noschemas = True if self.rootresp and "JsonSchemas" in self.rootresp and not \ self.rootresp.get("JsonSchemas", None) else False if self.noschemas: self.ilogen = self.ilover = self.iloversion = None if self.rootresp and not self.noschemas: self.defineregschemapath(self.rootresp) if self.flagiften: self.defs = Definevalstenplus() else: self.defs = DefinevalsNine()
# When running remotely connect using the secured (https://) address, # account name, and password to send https requests # SYSTEM_URL acceptable examples: # "https://10.0.0.100" # "https://ilo.hostname" SYSTEM_URL = "https://10.0.0.100" LOGIN_ACCOUNT = "admin" LOGIN_PASSWORD = "******" # Create a REDFISH object try: REDFISH_OBJ = RedfishClient(base_url=SYSTEM_URL, username=LOGIN_ACCOUNT, \ password=LOGIN_PASSWORD) REDFISH_OBJ.login() except ServerDownOrUnreachableError: sys.stderr.write( "ERROR: server not reachable or doesn't support Redfish.\n") sys.exit() resources = get_resource_directory(REDFISH_OBJ) for resource in resources: try: sys.stdout.write("\t" + str(resource["@odata.type"]) + \ "\n\t\t" + str(resource["@odata.id"]) + "\n") except KeyError: pass REDFISH_OBJ.logout()
def getgen(self, gen=None, url=None, username=None, password=None, logger=None,\ proxy=None, ca_cert_data={}, isredfish=True): """Function designed to verify the servers platform. Will generate the `Typeandpathdefines` variables based on the system type that is detected. :param url: The URL to perform the request on. :type url: str :param username: The username to login with. :type username: str :param password: The password to login with. :type password: str :param proxy: The proxy to connect to the system with. :type proxy: str :param ca_certs: Dictionary including the TLS certificate information of user based authentication :type ca_certs: dict :param isredfish: The flag to force redfish conformance on iLO 4 systems. You will still need to call `updatedefinesflag` to update the defines to Redfish. :type isredfish: bool :param logger: The logger handler to log data too uses the default if none is provided. :type logger: str """ if self.adminpriv is False and url.startswith("blob"): raise UserNotAdminError("") self.url = url self.is_redfish = isredfish self.gencompany = self.rootresp = False self.ilogen = 5 # If no iLO or Anonymous data , default to iLO 5 types logger = logger if not logger else LOGGER client = None self.noschemas = False self.schemapath = self.regpath = '' if not gen: try_count = 0 try: client = RedfishClient(base_url=self.url, username=username, password=password,\ proxy=proxy, ca_cert_data=ca_cert_data) client._get_root() except ServerDownOrUnreachableError as excp: if self.is_redfish: raise excp try_count += 1 if not self.is_redfish: try: restclient = LegacyRestClient(base_url=self.url, username=username, \ password=password, proxy=proxy, ca_cert_data=ca_cert_data) restclient._get_root() #Check that the response is actually legacy rest and not a redirect _ = restclient.root.obj.Type self.is_redfish = False client = restclient except Exception as excp: try_count += 1 if not client: logger.info("Gen get rest error:" + str(excp) + "\n") raise excp else: self.is_redfish = True if try_count > 1: raise ServerDownOrUnreachableError("Server not reachable or does not support "\ "HPRest or Redfish: %s\n" % str(excp)) rootresp = client.root.obj self.rootresp = rootresp client.logout() self.gencompany = next(iter(self.rootresp.get("Oem", {}).keys()), None) in ('Hpe', 'Hp') comp = 'Hp' if self.gencompany else None comp = 'Hpe' if rootresp.get("Oem", {}).get('Hpe', None) else comp if comp and next(iter(rootresp.get("Oem", {}).get(comp, {}).get("Manager", {}))).\ get('ManagerType', None): self.ilogen = next(iter(rootresp.get("Oem", {}).get(comp, {}).get("Manager", {})))\ .get("ManagerType") self.ilover = next(iter(rootresp.get("Oem", {}).get(comp, {}).get("Manager", {}))).\ get("ManagerFirmwareVersion") if self.ilogen.split(' ')[-1] == "CM": # Assume iLO 4 types in Moonshot self.ilogen = 4 self.iloversion = None else: self.iloversion = float(self.ilogen.split(' ')[-1] + '.' + \ ''.join(self.ilover.split('.'))) else: self.ilogen = int(gen) try: if not isinstance(self.ilogen, int): self.ilogen = int(self.ilogen.split(' ')[-1]) self.flagiften = True if int(self.ilogen) >= 5 else False except: raise UnableToObtainIloVersionError( "Unable to find the iLO generation.") self.noschemas = True if self.rootresp and "JsonSchemas" in self.rootresp and not \ self.rootresp.get("JsonSchemas", None) else False if self.noschemas: self.ilogen = self.ilover = self.iloversion = None if self.rootresp and not self.noschemas: self.defineregschemapath(self.rootresp) if self.flagiften: self.defs = Definevalstenplus() else: self.defs = DefinevalsNine()