| import argparse |
| import os |
| import sys |
| import traceback |
| |
| from logging import INFO, DEBUG |
| |
| from cfg_checker.common.exception import CheckerException |
| from cfg_checker.common import config, logger, logger_cli |
| |
| |
| pkg_dir = os.path.dirname(__file__) |
| pkg_dir = os.path.normpath(pkg_dir) |
| |
| commands = { |
| 'packages': ['report'], |
| 'network': ['check', 'report'], |
| 'reclass': ['list', 'diff'] |
| } |
| |
| class MyParser(argparse.ArgumentParser): |
| def error(self, message): |
| sys.stderr.write('Error: {0}\n\n'.format(message)) |
| self.print_help() |
| |
| |
| def help_message(): |
| print""" |
| Please, use following examples to generate info reports:\n |
| cfg_checker packages report\n |
| cfg_checker network check\n |
| cfg_checker network report\n |
| """ |
| return |
| |
| |
| def config_check_entrypoint(): |
| """ |
| Main entry point. Uses nested parsers structure |
| with a default function to execute the comand |
| |
| :return: - no return value |
| """ |
| # Main entrypoint |
| parser = MyParser(prog="# Mirantis Cloud configuration checker") |
| |
| # Parsers (each parser can have own arguments) |
| # - subparsers (command) |
| # |- pkg_parser |
| # | - pkg_subparsers (type) |
| # | - pkg_report_parser (default func - pkg_check) |
| # |- net_parser |
| # | - net_subparsers (type) |
| # | - net_check_parser (default func - net_check) |
| # | - net_report_parser (default func - net_report) |
| # - reclass_parser |
| # - reclass_list (default func - reclass_list) |
| # - reclass_compare (default func - reclass_diff) |
| |
| parser.add_argument( |
| "-d", |
| "--debug", |
| action="store_true", default=False, |
| help="Set CLI logging level to DEBUG" |
| ) |
| parser.add_argument( |
| '-f', |
| '--file', |
| help="HTML filename to save report" |
| ) |
| parser.add_argument( |
| '-s', |
| '--sudo', |
| action='store_true', default=True, |
| help="Use sudo for getting salt creds" |
| ) |
| subparsers = parser.add_subparsers(dest='command') |
| # packages |
| pkg_parser = subparsers.add_parser( |
| 'packages', |
| help="Package versions check (Candidate vs Installed)" |
| ) |
| pkg_subparsers = pkg_parser.add_subparsers(dest='type') |
| |
| pkg_report_parser = pkg_subparsers.add_parser( |
| 'report', |
| help="Report package versions to HTML file" |
| ) |
| |
| # networking |
| net_parser = subparsers.add_parser( |
| 'network', |
| help="Network infrastructure checks and reports" |
| ) |
| net_subparsers = net_parser.add_subparsers(dest='type') |
| |
| net_check_parser = net_subparsers.add_parser( |
| 'check', |
| help="Do network check and print the result" |
| ) |
| |
| net_report_parser = net_subparsers.add_parser( |
| 'report', |
| help="Generate network check report" |
| ) |
| |
| # reclass |
| reclass_parser = subparsers.add_parser( |
| 'reclass', |
| help="Reclass related checks and reports" |
| ) |
| reclass_subparsers = reclass_parser.add_subparsers(dest='type') |
| reclass_list_parser = reclass_subparsers.add_parser( |
| 'list', |
| help="List models available to compare" |
| ) |
| reclass_list_parser.add_argument( |
| "-p", |
| "--models-path", |
| default="/srv/salt/", |
| help="Global path to search models in" |
| ) |
| |
| reclass_diff_parser = reclass_subparsers.add_parser( |
| 'diff', |
| help="List models available to compare" |
| ) |
| reclass_diff_parser.add_argument( |
| "--model1", |
| required=True, |
| help="Model A <path>. Model name is the folder name" |
| ) |
| reclass_diff_parser.add_argument( |
| "--model2", |
| required=True, |
| help="Model B <path>. Model name is the folder name" |
| ) |
| |
| |
| #parse arguments |
| try: |
| args = parser.parse_args() |
| except TypeError as e: |
| logger_cli.info("\n# Please, check arguments") |
| return |
| |
| # Pass externally configured values |
| config.ssh_uses_sudo = args.sudo |
| |
| # Handle options |
| if args.debug: |
| logger_cli.setLevel(DEBUG) |
| else: |
| logger_cli.setLevel(INFO) |
| |
| # Validate the commands |
| # check command |
| if args.command not in commands: |
| logger_cli.info("\n# Please, type a command listed above") |
| return |
| elif args.type not in commands[args.command]: |
| # check type |
| logger_cli.info( |
| "\n# Please, select '{}' command type listed above".format( |
| args.command |
| ) |
| ) |
| return |
| else: |
| # form function name to call |
| _method_name = "do_" + args.type |
| _target_module = __import__("cfg_checker.modules."+args.command, fromlist=[""]) |
| _method = getattr(_target_module, _method_name) |
| |
| # Execute the command |
| result = _method(args) |
| |
| logger.debug(result) |
| |
| def cli_main(): |
| try: |
| config_check_entrypoint() |
| except CheckerException as e: |
| logger_cli.error("\nERROR: {}".format( |
| e.message |
| )) |
| |
| exc_type, exc_value, exc_traceback = sys.exc_info() |
| logger_cli.debug("\n{}".format( |
| "".join(traceback.format_exception( |
| exc_type, |
| exc_value, |
| exc_traceback |
| )) |
| )) |
| |
| if __name__ == '__main__': |
| cli_main() |