Exemplo n.º 1
0
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