Skip to content

Commit

Permalink
fix: removed bafish sys exit
Browse files Browse the repository at this point in the history
replaced badfish sys.exit calls on exceptions for a custom badfish
exception.

Change-Id: If686eb2d33dcda5f0371391b1013bf8685e3552d
  • Loading branch information
grafuls committed Oct 3, 2019
1 parent 1696676 commit f24b613
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 36 deletions.
1 change: 0 additions & 1 deletion bin/quads-cli
Expand Up @@ -30,7 +30,6 @@ import os
from json import JSONDecodeError
from quads.config import conf, API_URL
from quads.quads import Api as QuadsApi
from quads.tools import make_instackenv_json
from quads.tools.move_and_rebuild_hosts import move_and_rebuild, switch_config
from quads.model import Cloud, Schedule, Host

Expand Down
65 changes: 34 additions & 31 deletions quads/tools/badfish.py
Expand Up @@ -26,6 +26,10 @@ async def badfish_factory(_host, _username, _password, loop=None, _retries=RETRI
return badfish


class BadfishException(Exception):
pass


class Badfish:
def __init__(self, _host, _username, _password, loop=None, _retries=RETRIES):
self.host = _host
Expand Down Expand Up @@ -69,13 +73,13 @@ async def error_handler(_response):
data = await _response.json(content_type="application/json")
except Exception:
logger.error("Error reading response from host.")
sys.exit(1)
raise BadfishException

if "error" in data:
detail_message = str(data["error"]["@Message.ExtendedInfo"][0]["Message"])
logger.warning(detail_message)

sys.exit(1)
raise BadfishException

async def get_request(self, uri, _continue=False):
try:
Expand All @@ -93,7 +97,7 @@ async def get_request(self, uri, _continue=False):
else:
logger.debug(ex)
logger.error("Failed to communicate with server.")
sys.exit(1)
raise BadfishException
return _response

async def post_request(self, uri, payload, headers):
Expand All @@ -112,7 +116,7 @@ async def post_request(self, uri, payload, headers):
await _response.json(content_type="application/json")
except (Exception, TimeoutError):
logger.exception("Failed to communicate with server.")
sys.exit(1)
raise BadfishException
return _response

async def patch_request(self, uri, payload, headers, _continue=False):
Expand All @@ -135,7 +139,7 @@ async def patch_request(self, uri, payload, headers, _continue=False):
else:
logger.debug(ex)
logger.error("Failed to communicate with server.")
sys.exit(1)
raise BadfishException
return _response

async def delete_request(self, uri, headers):
Expand All @@ -153,7 +157,7 @@ async def delete_request(self, uri, headers):
await _response.json(content_type="application/json")
except (Exception, TimeoutError):
logger.exception("Failed to communicate with server.")
sys.exit(1)
raise BadfishException
return

async def get_boot_seq(self):
Expand All @@ -172,7 +176,7 @@ async def get_bios_boot_mode(self):
data = await _response.json(content_type="application/json")
except ValueError:
logger.error("Could not retrieve Bios Boot mode.")
sys.exit(1)
raise BadfishException

try:
bios_boot_mode = data[u"Attributes"]["BootMode"]
Expand All @@ -192,7 +196,7 @@ async def get_boot_devices(self):
else:
logger.debug(data)
logger.error("Boot order modification is not supported by this host.")
sys.exit(1)
raise BadfishException

async def get_job_queue(self):
logger.debug("Getting job queue.")
Expand Down Expand Up @@ -231,7 +235,7 @@ async def get_job_status(self, _job_id):
logger.warning("JobStatus not scheduled, current status is: %s." % data[u"Message"])

logger.error("Not able to successfully schedule the job.")
sys.exit(1)
raise BadfishException

async def get_host_type(self, _interfaces_path):
boot_devices = await self.get_boot_devices()
Expand All @@ -243,7 +247,7 @@ async def get_host_type(self, _interfaces_path):
except yaml.YAMLError as ex:
logger.error("Couldn't read file: %s" % _interfaces_path)
logger.debug(ex)
sys.exit(1)
raise BadfishException

host_model = self.host.split(".")[0].split("-")[-1]
interfaces = {}
Expand All @@ -266,13 +270,13 @@ async def find_systems_resource(self):

if response.status == 401:
logger.error(f"Failed to authenticate. Verify your credentials for {self.host}")
sys.exit(1)
raise BadfishException

if response:
data = await response.json(content_type="application/json")
if 'Systems' not in data:
logger.error("Systems resource not found")
sys.exit(1)
raise BadfishException
else:
systems = data["Systems"]["@odata.id"]
_response = await self.get_request(self.host_uri + systems)
Expand All @@ -285,15 +289,15 @@ async def find_systems_resource(self):
return systems_service
else:
logger.error("ComputerSystem's Members array is either empty or missing")
sys.exit(1)
raise BadfishException

async def find_managers_resource(self):
response = await self.get_request(self.root_uri)
if response:
data = await response.json(content_type="application/json")
if 'Managers' not in data:
logger.error("Managers resource not found")
sys.exit(1)
raise BadfishException
else:
managers = data["Managers"]["@odata.id"]
response = await self.get_request(self.host_uri + managers)
Expand All @@ -306,7 +310,7 @@ async def find_managers_resource(self):
return managers_service
else:
logger.error("Manager's Members array is either empty or missing")
sys.exit(1)
raise BadfishException

async def get_power_state(self):
_uri = '%s%s' % (self.host_uri, self.system_resource)
Expand All @@ -328,17 +332,17 @@ async def get_power_state(self):
async def change_boot(self, host_type, interfaces_path, pxe=False):
if host_type.lower() not in ("foreman", "director"):
logger.error('Expected values for -t argument are "foreman" or "director"')
sys.exit(1)
raise BadfishException

if interfaces_path:
if not os.path.exists(interfaces_path):
logger.error("No such file or directory: %s." % interfaces_path)
sys.exit(1)
raise BadfishException
else:
logger.error(
"You must provide a path to the interfaces yaml via `-i` optional argument."
)
sys.exit(1)
raise BadfishException

_type = await self.get_host_type(interfaces_path)
if _type and _type.lower() != host_type.lower():
Expand All @@ -359,7 +363,7 @@ async def change_boot(self, host_type, interfaces_path, pxe=False):

else:
logger.error("Couldn't communicate with host after %s attempts." % self.retries)
sys.exit(1)
raise BadfishException
else:
logger.warning(
"No changes were made since the boot order already matches the requested."
Expand All @@ -372,7 +376,7 @@ async def change_boot_order(self, _interfaces_path, _host_type):
definitions = yaml.safe_load(f)
except yaml.YAMLError as ex:
logger.error(ex)
sys.exit(1)
raise BadfishException

host_model = self.host.split(".")[0].split("-")[-1]
interfaces = definitions["%s_%s_interfaces" % (_host_type, host_model)].split(",")
Expand All @@ -392,7 +396,6 @@ async def change_boot_order(self, _interfaces_path, _host_type):

else:
logger.warning("No changes were made since the boot order already matches the requested.")
sys.exit()

async def patch_boot_seq(self, boot_devices):
_boot_seq = await self.get_boot_seq()
Expand Down Expand Up @@ -452,7 +455,7 @@ async def delete_job_queue(self):
logger.info("Job queue for iDRAC %s successfully cleared." % self.host)
else:
logger.error("Job queue not cleared, there was something wrong with your request.")
sys.exit(1)
raise BadfishException

async def clear_job_list(self, _job_queue):
_url = "%s%s/Jobs" % (self.host_uri, self.manager_resource)
Expand All @@ -468,7 +471,7 @@ async def clear_job_list(self, _job_queue):
logger.info("Job queue for iDRAC %s successfully cleared." % self.host)
else:
logger.error("Job queue not cleared, current job queue contains jobs: %s." % job_queue)
sys.exit(1)
raise BadfishException

async def clear_job_queue(self):
_job_queue = await self.get_job_queue()
Expand Down Expand Up @@ -573,7 +576,7 @@ async def reset_idrac(self):
else:
data = await _response.json()
logger.error("Status code %s returned, error is: \n%s." % (status_code, data))
sys.exit(1)
raise BadfishException
time.sleep(15)

logger.info("iDRAC will now reset and be back online within a few minutes.")
Expand All @@ -588,18 +591,18 @@ async def boot_to(self, device):
if job_id:
await self.get_job_status(job_id)
else:
sys.exit(1)
raise BadfishException
return True

async def boot_to_type(self, host_type, _interfaces_path):
if host_type.lower() not in ("foreman", "director"):
logger.error('Expected values for -t argument are "foreman" or "director"')
sys.exit(1)
raise BadfishException

if _interfaces_path:
if not os.path.exists(_interfaces_path):
logger.error("No such file or directory: %s." % _interfaces_path)
sys.exit(1)
raise BadfishException

device = self.get_host_type_boot_device(host_type, _interfaces_path)

Expand Down Expand Up @@ -691,12 +694,12 @@ async def get_firmware_inventory(self):
data = await _response.json(content_type="application/json")
except ValueError:
logger.error("Not able to access Firmware inventory.")
sys.exit(1)
raise BadfishException
installed_devices = []
if "error" in data:
logger.debug(data["error"])
logger.error("Not able to access Firmware inventory.")
sys.exit(1)
raise BadfishException
for device in data[u'Members']:
a = device[u'@odata.id']
a = a.replace("/redfish/v1/UpdateService/FirmwareInventory/", "")
Expand Down Expand Up @@ -759,7 +762,7 @@ async def export_configuration(self):
time.sleep(1)
else:
logger.error("Execute job ID command failed, error code is: %s" % status_code)
sys.exit(1)
raise BadfishException

logger.error("Could not export settings after %s attempts." % self.retries)

Expand All @@ -771,7 +774,7 @@ def get_host_type_boot_device(self, host_type, _interfaces_path):
except yaml.YAMLError as ex:
logger.error("Couldn't read file: %s" % _interfaces_path)
logger.debug(ex)
sys.exit(1)
raise BadfishException

host_model = self.host.split(".")[0].split("-")[-1]
return definitions["%s_%s_interfaces" % (host_type, host_model)].split(",")[0]
Expand Down
8 changes: 4 additions & 4 deletions quads/tools/move_and_rebuild_hosts.py
Expand Up @@ -8,7 +8,7 @@
from quads.config import conf
from quads.helpers import is_supported, is_supermicro, get_vlan
from quads.model import Host, Cloud
from quads.tools.badfish import badfish_factory
from quads.tools.badfish import badfish_factory, BadfishException
from quads.tools.foreman import Foreman
from quads.tools.juniper_convert_port_public import juniper_convert_port_public
from quads.tools.juniper_set_port import juniper_set_port
Expand Down Expand Up @@ -180,7 +180,7 @@ async def move_and_rebuild(host, old_cloud, new_cloud, semaphore, rebuild=False,
if is_supported(host):
try:
badfish = await badfish_factory("mgmt-%s" % host, conf["ipmi_username"], conf["ipmi_password"])
except SystemExit:
except BadfishException:
logger.error(f"Could not initialize Badfish. Verify ipmi credentials for mgmt-{host}.")
return False
try:
Expand All @@ -191,7 +191,7 @@ async def move_and_rebuild(host, old_cloud, new_cloud, semaphore, rebuild=False,
"../../conf/idrac_interfaces.yml"
)
), loop)
except (SystemExit, Exception):
except BadfishException:
logger.error(f"Could not set boot order via Badfish for mgmt-{host}.")
return False

Expand Down Expand Up @@ -226,7 +226,7 @@ async def move_and_rebuild(host, old_cloud, new_cloud, semaphore, rebuild=False,
)
)
await badfish.reboot_server(graceful=False)
except (SystemExit, Exception):
except BadfishException:
logger.error(f"Error setting PXE boot via Badfish on {host}.")
return False
else:
Expand Down

0 comments on commit f24b613

Please sign in to comment.