2020from badfish .helpers .logger import (
2121 BadfishLogger ,
2222)
23- from badfish .helpers .http_client import BadfishHTTPClient
23+ from badfish .helpers .http_client import HTTPClient
2424
2525from logging import (
2626 DEBUG ,
@@ -61,7 +61,7 @@ def __init__(self, _host, _username, _password, _logger, _retries, _loop=None):
6161 self .loop = _loop
6262 if not self .loop :
6363 self .loop = asyncio .get_event_loop ()
64- self .http_client = BadfishHTTPClient (_host , _username , _password , _logger , _retries )
64+ self .http_client = HTTPClient (_host , _username , _password , _logger , _retries )
6565 self .system_resource = None
6666 self .manager_resource = None
6767 self .bios_uri = None
@@ -188,7 +188,7 @@ async def get_sriov_mode(self):
188188 async def get_bios_attributes_registry (self ):
189189 self .logger .debug ("Getting BIOS attribute registry." )
190190 _uri = "%s%s/Bios/BiosRegistry" % (self .host_uri , self .system_resource )
191- data = await self .http_client .get_request (_uri )
191+ data = await self .http_client .get_json (_uri )
192192
193193 if not data :
194194 self .logger .error ("Operation not supported by vendor." )
@@ -213,7 +213,7 @@ async def get_bios_attribute_registry(self, attribute):
213213 async def get_bios_attributes (self ):
214214 self .logger .debug ("Getting BIOS attributes." )
215215 _uri = "%s%s/Bios" % (self .host_uri , self .system_resource )
216- data = await self .http_client .get_request (_uri )
216+ data = await self .http_client .get_json (_uri )
217217
218218 if not data :
219219 self .logger .error ("Operation not supported by vendor." )
@@ -280,8 +280,11 @@ async def get_boot_devices(self):
280280 _uri = "%s%s/BootSources" % (self .host_uri , self .system_resource )
281281 _response = await self .get_request (_uri )
282282
283- if _response .status == 404 :
284- self .logger .debug (_response .text )
283+ if _response and _response .status == 404 :
284+ self .logger .debug (await _response .text ())
285+ raise BadfishException ("Boot order modification is not supported by this host." )
286+
287+ if not _response :
285288 raise BadfishException ("Boot order modification is not supported by this host." )
286289
287290 raw = await _response .text ("utf-8" , "ignore" )
@@ -380,11 +383,13 @@ async def get_host_type(self, _interfaces_path):
380383 return None
381384
382385 async def find_session_uri (self ):
383- data = await self .http_client .get_request (self .root_uri , _get_token = True )
386+ response = await self .http_client .get_request (self .root_uri , _get_token = True )
384387
385- if not data :
388+ if not response :
386389 raise BadfishException (f"Failed to communicate with { self .host } " )
387390
391+ raw = await response .text ("utf-8" , "ignore" )
392+ data = json .loads (raw .strip ())
388393 redfish_version = int (data ["RedfishVersion" ].replace ("." , "" ))
389394 session_uri = None
390395 if redfish_version >= 160 :
@@ -393,8 +398,8 @@ async def find_session_uri(self):
393398 session_uri = "/redfish/v1/Sessions"
394399
395400 _uri = "%s%s" % (self .host_uri , session_uri )
396- check_data = await self .http_client .get_request (_uri , _continue = True , _get_token = True )
397- if check_data is None :
401+ check_response = await self .http_client .get_request (_uri , _continue = True , _get_token = True )
402+ if check_response is None :
398403 session_uri = "/redfish/v1/SessionService/Sessions"
399404
400405 return session_uri
@@ -404,26 +409,29 @@ async def validate_credentials(self):
404409 headers = {"content-type" : "application/json" }
405410 _uri = "%s%s" % (self .host_uri , self .session_uri )
406411
407- response_data , status , response_headers = await self .http_client .post_request (_uri , payload , headers , _get_token = True )
408-
412+ _response = await self .http_client .post_request (_uri , payload , headers , _get_token = True )
413+
414+ await _response .text ("utf-8" , "ignore" )
415+
416+ status = _response .status
409417 if status == 401 :
410418 raise BadfishException (f"Failed to authenticate. Verify your credentials for { self .host } " )
411419 if status not in [200 , 201 ]:
412420 raise BadfishException (f"Failed to communicate with { self .host } " )
413-
421+
414422 # Extract token from response headers
415- token = response_headers . get ("X-Auth-Token" ) if response_headers else None
423+ token = _response . headers . get ("X-Auth-Token" )
416424 if token :
417425 self .token = token
418426 self .http_client .token = token
419427 # Store session info for cleanup
420- self .session_id = response_headers .get ("Location" )
428+ self .session_id = _response . headers .get ("Location" )
421429
422430 return token
423431
424432 async def get_interfaces_endpoints (self ):
425433 _uri = "%s%s/EthernetInterfaces" % (self .host_uri , self .system_resource )
426- data = await self .http_client .get_request (_uri )
434+ data = await self .http_client .get_json (_uri )
427435
428436 if not data :
429437 raise BadfishException ("EthernetInterfaces entry point not supported by this host." )
@@ -439,25 +447,30 @@ async def get_interfaces_endpoints(self):
439447
440448 async def get_interface (self , endpoint ):
441449 _uri = "%s%s" % (self .host_uri , endpoint )
442- data = await self .http_client .get_request (_uri )
450+ data = await self .http_client .get_json (_uri )
443451
444452 if not data :
445453 raise BadfishException ("EthernetInterface entry point not supported by this host." )
446454
447455 return data
448456
449457 async def find_systems_resource (self ):
450- data = await self .http_client .get_request (self .root_uri )
451- if not data :
458+ response = await self .http_client .get_request (self .root_uri )
459+ if not response :
452460 raise BadfishException ("Failed to communicate with server." )
453461
462+ raw = await response .text ("utf-8" , "ignore" )
463+ data = json .loads (raw .strip ())
454464 if "Systems" not in data :
455465 raise BadfishException ("Systems resource not found" )
456466
457467 systems = data ["Systems" ]["@odata.id" ]
458- systems_data = await self .http_client .get_request (self .host_uri + systems )
459- if not systems_data :
468+ systems_response = await self .http_client .get_request (self .host_uri + systems )
469+ if not systems_response :
460470 raise BadfishException ("Authorization Error: verify credentials." )
471+
472+ raw = await systems_response .text ("utf-8" , "ignore" )
473+ systems_data = json .loads (raw .strip ())
461474
462475 if systems_data .get ("Members" ):
463476 for member in systems_data ["Members" ]:
@@ -468,17 +481,23 @@ async def find_systems_resource(self):
468481 raise BadfishException ("ComputerSystem's Members array is either empty or missing" )
469482
470483 async def find_managers_resource (self ):
471- data = await self .http_client .get_request (self .root_uri )
472- if not data :
484+ response = await self .http_client .get_request (self .root_uri )
485+ if not response :
473486 raise BadfishException ("Failed to communicate with server." )
474487
488+ raw = await response .text ("utf-8" , "ignore" )
489+ data = json .loads (raw .strip ())
475490 self .vendor = "Dell" if "Dell" in data ["Oem" ] else "Supermicro"
476491
477492 if "Managers" not in data :
478493 raise BadfishException ("Managers resource not found" )
479494
480495 managers = data ["Managers" ]["@odata.id" ]
481- managers_data = await self .http_client .get_request (self .host_uri + managers )
496+ managers_response = await self .http_client .get_request (self .host_uri + managers )
497+ managers_data = None
498+ if managers_response :
499+ raw = await managers_response .text ("utf-8" , "ignore" )
500+ managers_data = json .loads (raw .strip ())
482501 if managers_data and managers_data .get ("Members" ):
483502 for member in managers_data ["Members" ]:
484503 managers_service = member ["@odata.id" ]
@@ -487,11 +506,24 @@ async def find_managers_resource(self):
487506 else :
488507 raise BadfishException ("Manager's Members array is either empty or missing" )
489508
509+ # HTTP client wrapper methods
510+ async def get_request (self , uri , _continue = False , _get_token = False ):
511+ return await self .http_client .get_request (uri , _continue , _get_token )
512+
513+ async def post_request (self , uri , payload , headers , _get_token = False ):
514+ return await self .http_client .post_request (uri , payload , headers , _get_token )
515+
516+ async def patch_request (self , uri , payload , headers , _continue = False ):
517+ return await self .http_client .patch_request (uri , payload , headers , _continue )
518+
519+ async def delete_request (self , uri , headers ):
520+ return await self .http_client .delete_request (uri , headers )
521+
490522 async def get_power_state (self ):
491523 _uri = "%s%s" % (self .host_uri , self .system_resource )
492524 self .logger .debug ("url: %s" % _uri )
493525
494- data = await self .http_client .get_request (_uri , _continue = True )
526+ data = await self .http_client .get_json (_uri , _continue = True )
495527 if not data :
496528 self .logger .debug ("Couldn't get power state. Retrying." )
497529 return "Down"
@@ -796,34 +828,38 @@ async def check_schedule_job_status(self, job_id):
796828
797829 if status_code == 200 :
798830 await asyncio .sleep (10 )
831+ # Only try to access job data if we got a successful response
832+ if isinstance (data , dict ) and 'Id' in data :
833+ self .logger .info (f"JobID: { data [u'Id' ]} " )
834+ self .logger .info (f"Name: { data [u'Name' ]} " )
835+ self .logger .info (f"Message: { data [u'Message' ]} " )
836+ self .logger .info (f"PercentComplete: { str (data [u'PercentComplete' ])} " )
799837 else :
800838 self .logger .error (f"Command failed to check job status, return code is { status_code } " )
801839 self .logger .debug (f"Extended Info Message: { data } " )
802840 return False
803-
804- self .logger .info (f"JobID: { data [u'Id' ]} " )
805- self .logger .info (f"Name: { data [u'Name' ]} " )
806- self .logger .info (f"Message: { data [u'Message' ]} " )
807- self .logger .info (f"PercentComplete: { str (data [u'PercentComplete' ])} " )
808841 else :
809842 self .logger .error ("Command failed to check job status" )
810843 return False
811844
812845 async def check_job_status (self , job_id ):
813846 for count in range (self .retries ):
814847 _url = f"{ self .host_uri } { self .manager_resource } /Jobs/{ job_id } "
815- self .get_request .cache_clear ()
848+ self .http_client . get_request .cache_clear ()
816849 _response = await self .get_request (_url )
817850
818851 status_code = _response .status
819852 raw = await _response .text ("utf-8" , "ignore" )
820853 data = json .loads (raw .strip ())
821- if status_code == 200 :
822- pass
823- else :
854+ if status_code != 200 :
824855 self .logger .error (f"Command failed to check job status, return code is { status_code } " )
825856 self .logger .debug (f"Extended Info Message: { data } " )
826857 return False
858+
859+ if "Message" not in data :
860+ self .logger .warning ("Job status response missing Message field" )
861+ return False
862+
827863 if "Fail" in data ["Message" ] or "fail" in data ["Message" ]:
828864 self .logger .debug (f"\n { job_id } job failed." )
829865 return False
@@ -2096,7 +2132,7 @@ async def export_scp(self, file_path, targets="ALL", include_read_only=False):
20962132 while True :
20972133 ct = get_now () - start_time
20982134 uri = "%s/redfish/v1/TaskService/Tasks/%s" % (self .host_uri , job_id )
2099- response = await self .get_raw (uri )
2135+ response = await self .get_request (uri )
21002136 raw = await response .text ("utf-8" , "ignore" )
21012137 data = json .loads (raw .strip ())
21022138 if "SystemConfiguration" in data :
@@ -2164,7 +2200,7 @@ async def import_scp(self, file_path, targets="ALL"):
21642200 while True :
21652201 ct = get_now () - start_time
21662202 uri = "%s/redfish/v1/TaskService/Tasks/%s" % (self .host_uri , job_id )
2167- response = await self .get_raw (uri )
2203+ response = await self .get_request (uri )
21682204 raw = await response .text ("utf-8" , "ignore" )
21692205 data = json .loads (raw .strip ())
21702206 if response .status in [200 , 202 ]:
0 commit comments