def main(argv=None): parser = argparse.ArgumentParser( description="Tool for managing server hardware via the Redfish API." ) parser.add_argument("-H", help="iDRAC host address") parser.add_argument("-u", help="iDRAC username", required=True) parser.add_argument("-p", help="iDRAC password", required=True) parser.add_argument("-i", help="Path to iDRAC interfaces yaml", default=None) parser.add_argument("-t", help="Type of host. Accepts: foreman, director") parser.add_argument( "-l", "--log", help="Optional argument for logging results to a file" ) parser.add_argument( "-f", "--force", dest="force", action="store_true", help="Optional argument for forced clear-jobs", ) parser.add_argument( "--host-list", help="Path to a plain text file with a list of hosts.", default=None, ) parser.add_argument( "--pxe", help="Set next boot to one-shot boot PXE", action="store_true" ) parser.add_argument( "--boot-to", help="Set next boot to one-shot boot to a specific device" ) parser.add_argument( "--boot-to-type", help="Set next boot to one-shot boot to either director or foreman", ) parser.add_argument( "--boot-to-mac", help="Set next boot to one-shot boot to a specific MAC address on the target", ) parser.add_argument( "--reboot-only", help="Flag for only rebooting the host", action="store_true" ) parser.add_argument( "--power-cycle", help="Flag for sending ForceOff instruction to the host", action="store_true", ) parser.add_argument( "--power-state", help="Get power state", action="store_true", ) parser.add_argument( "--power-on", help="Power on host", action="store_true", ) parser.add_argument( "--power-off", help="Power off host", action="store_true", ) parser.add_argument("--racreset", help="Flag for iDRAC reset", action="store_true") parser.add_argument( "--factory-reset", help="Reset BIOS to default factory settings", action="store_true", ) parser.add_argument( "--check-boot", help="Flag for checking the host boot order", action="store_true", ) parser.add_argument( "--firmware-inventory", help="Get firmware inventory", action="store_true" ) parser.add_argument( "--clear-jobs", help="Clear any scheduled jobs from the queue", action="store_true", ) parser.add_argument( "--ls-jobs", help="List any scheduled jobs in queue", action="store_true", ) parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true") parser.add_argument( "-r", "--retries", help="Number of retries for executing actions.", default=RETRIES, ) _args = vars(parser.parse_args(argv)) log_level = DEBUG if _args["verbose"] else INFO host_list = _args["host_list"] host = _args["H"] result = True if host_list: FMT = "[%(name)s] - %(levelname)-8s - %(message)s" FILEFMT = "%(asctime)-12s: [%(name)s] - %(levelname)-8s - %(message)s" else: FMT = "- %(levelname)-8s - %(message)s" FILEFMT = "%(asctime)-12s: %(levelname)-8s - %(message)s" _queue = Queue() _stream_handler = StreamHandler() _stream_handler.setFormatter(Formatter(FMT)) _queue_listener = QueueListener(_queue, _stream_handler) _logger = getLogger(__name__) _queue_handler = QueueHandler(_queue) _logger.addHandler(_queue_handler) _logger.setLevel(log_level) _queue_listener.start() if _args["log"]: file_handler = FileHandler(_args["log"]) file_handler.setFormatter(Formatter(FILEFMT)) file_handler.setLevel(log_level) _queue_listener.handlers = _queue_listener.handlers + (file_handler,) loop = asyncio.get_event_loop() tasks = [] if host_list: try: with open(host_list, "r") as _file: for _host in _file.readlines(): logger = getLogger(_host.split(".")[0]) logger.addHandler(_queue_handler) logger.setLevel(log_level) fn = functools.partial( execute_badfish, _host.strip(), _args, logger ) tasks.append(fn) except IOError as ex: _logger.debug(ex) _logger.error("There was something wrong reading from %s" % host_list) results = [] try: results = loop.run_until_complete( asyncio.gather(*[task() for task in tasks], return_exceptions=True) ) except KeyboardInterrupt: _logger.warning("\nBadfish terminated.") result = False except (asyncio.CancelledError, BadfishException) as ex: _logger.warning("There was something wrong executing Badfish.") _logger.debug(ex) result = False if results: result = True _logger.info("RESULTS:") for res in results: if len(res) > 1 and res[1]: _logger.info(f"{res[0]}: SUCCESSFUL") else: _logger.info(f"{res[0]}: FAILED") result = False elif not host: _logger.error( "You must specify at least either a host (-H) or a host list (--host-list)." ) else: try: _host, result = loop.run_until_complete( execute_badfish(host, _args, _logger) ) except KeyboardInterrupt: _logger.warning("Badfish terminated.") except BadfishException as ex: _logger.warning("There was something wrong executing Badfish.") _logger.debug(ex) result = False _queue_listener.stop() if result: return 0 return 1