blob: a0df7e6a65ce3103e59773a6c8fd9095e9f0e1d4 [file] [log] [blame]
Alex Savatieiev5118de02019-02-20 15:50:42 -06001import argparse
2import os
3import sys
Alex Savatieieve9613992019-02-21 18:20:35 -06004import traceback
Alex Savatieiev06ab17d2019-02-26 18:40:48 -06005
Alex Savatieiev799bee32019-02-20 17:19:26 -06006from logging import INFO, DEBUG
Alex Savatieiev5118de02019-02-20 15:50:42 -06007
Alex Savatieievc9055712019-03-01 14:43:56 -06008from cfg_checker.common.exception import CheckerException
9from cfg_checker.common import config, logger, logger_cli
Alex Savatieiev06ab17d2019-02-26 18:40:48 -060010
Alex Savatieiev5118de02019-02-20 15:50:42 -060011
12pkg_dir = os.path.dirname(__file__)
13pkg_dir = os.path.normpath(pkg_dir)
14
Alex Savatieiev9c642112019-02-26 13:55:43 -060015commands = {
16 'packages': ['report'],
17 'network': ['check', 'report'],
18 'reclass': ['list', 'diff']
19}
Alex Savatieiev5118de02019-02-20 15:50:42 -060020
21class MyParser(argparse.ArgumentParser):
22 def error(self, message):
23 sys.stderr.write('Error: {0}\n\n'.format(message))
24 self.print_help()
25
26
Alex Savatieiev5118de02019-02-20 15:50:42 -060027def help_message():
28 print"""
29 Please, use following examples to generate info reports:\n
30 cfg_checker packages report\n
31 cfg_checker network check\n
32 cfg_checker network report\n
33 """
34 return
35
Alex Savatieiev9c642112019-02-26 13:55:43 -060036
Alex Savatieiev5118de02019-02-20 15:50:42 -060037def config_check_entrypoint():
Alex Savatieiev9c642112019-02-26 13:55:43 -060038 """
39 Main entry point. Uses nested parsers structure
40 with a default function to execute the comand
41
42 :return: - no return value
43 """
Alex Savatieiev4c406322019-02-28 17:37:09 -060044 # Main entrypoint
45 parser = MyParser(prog="# Mirantis Cloud configuration checker")
Alex Savatieiev9c642112019-02-26 13:55:43 -060046
47 # Parsers (each parser can have own arguments)
48 # - subparsers (command)
49 # |- pkg_parser
50 # | - pkg_subparsers (type)
51 # | - pkg_report_parser (default func - pkg_check)
52 # |- net_parser
53 # | - net_subparsers (type)
54 # | - net_check_parser (default func - net_check)
55 # | - net_report_parser (default func - net_report)
56 # - reclass_parser
57 # - reclass_list (default func - reclass_list)
58 # - reclass_compare (default func - reclass_diff)
59
Alex Savatieiev799bee32019-02-20 17:19:26 -060060 parser.add_argument(
61 "-d",
62 "--debug",
63 action="store_true", default=False,
64 help="Set CLI logging level to DEBUG"
65 )
Alex Savatieiev9c642112019-02-26 13:55:43 -060066 parser.add_argument(
67 '-f',
68 '--file',
69 help="HTML filename to save report"
70 )
Alex Savatieiev63576832019-02-27 15:46:26 -060071 parser.add_argument(
72 '-s',
73 '--sudo',
74 action='store_true', default=True,
75 help="Use sudo for getting salt creds"
76 )
Alex Savatieiev5118de02019-02-20 15:50:42 -060077 subparsers = parser.add_subparsers(dest='command')
78 # packages
79 pkg_parser = subparsers.add_parser(
80 'packages',
81 help="Package versions check (Candidate vs Installed)"
82 )
83 pkg_subparsers = pkg_parser.add_subparsers(dest='type')
84
85 pkg_report_parser = pkg_subparsers.add_parser(
86 'report',
87 help="Report package versions to HTML file"
88 )
Alex Savatieiev5118de02019-02-20 15:50:42 -060089
90 # networking
91 net_parser = subparsers.add_parser(
92 'network',
Alex Savatieiev9c642112019-02-26 13:55:43 -060093 help="Network infrastructure checks and reports"
Alex Savatieiev5118de02019-02-20 15:50:42 -060094 )
95 net_subparsers = net_parser.add_subparsers(dest='type')
96
97 net_check_parser = net_subparsers.add_parser(
98 'check',
99 help="Do network check and print the result"
100 )
Alex Savatieiev5118de02019-02-20 15:50:42 -0600101
102 net_report_parser = net_subparsers.add_parser(
103 'report',
104 help="Generate network check report"
105 )
Alex Savatieiev5118de02019-02-20 15:50:42 -0600106
Alex Savatieiev9c642112019-02-26 13:55:43 -0600107 # reclass
108 reclass_parser = subparsers.add_parser(
109 'reclass',
110 help="Reclass related checks and reports"
111 )
112 reclass_subparsers = reclass_parser.add_subparsers(dest='type')
113 reclass_list_parser = reclass_subparsers.add_parser(
114 'list',
115 help="List models available to compare"
116 )
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600117 reclass_list_parser.add_argument(
118 "-p",
119 "--models-path",
120 default="/srv/salt/",
121 help="Global path to search models in"
122 )
Alex Savatieiev9c642112019-02-26 13:55:43 -0600123
124 reclass_diff_parser = reclass_subparsers.add_parser(
125 'diff',
126 help="List models available to compare"
127 )
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600128 reclass_diff_parser.add_argument(
129 "--model1",
130 required=True,
131 help="Model A <path>. Model name is the folder name"
132 )
133 reclass_diff_parser.add_argument(
134 "--model2",
135 required=True,
136 help="Model B <path>. Model name is the folder name"
137 )
138
Alex Savatieiev9c642112019-02-26 13:55:43 -0600139
Alex Savatieiev5118de02019-02-20 15:50:42 -0600140 #parse arguments
Alex Savatieiev9c642112019-02-26 13:55:43 -0600141 try:
142 args = parser.parse_args()
143 except TypeError as e:
Alex Savatieievc9055712019-03-01 14:43:56 -0600144 logger_cli.info("\n# Please, check arguments")
Alex Savatieiev9c642112019-02-26 13:55:43 -0600145 return
Alex Savatieiev5118de02019-02-20 15:50:42 -0600146
Alex Savatieiev63576832019-02-27 15:46:26 -0600147 # Pass externally configured values
148 config.ssh_uses_sudo = args.sudo
149
Alex Savatieiev799bee32019-02-20 17:19:26 -0600150 # Handle options
151 if args.debug:
152 logger_cli.setLevel(DEBUG)
153 else:
154 logger_cli.setLevel(INFO)
155
Alex Savatieiev9c642112019-02-26 13:55:43 -0600156 # Validate the commands
157 # check command
158 if args.command not in commands:
Alex Savatieievc9055712019-03-01 14:43:56 -0600159 logger_cli.info("\n# Please, type a command listed above")
Alex Savatieiev9c642112019-02-26 13:55:43 -0600160 return
161 elif args.type not in commands[args.command]:
162 # check type
163 logger_cli.info(
Alex Savatieievc9055712019-03-01 14:43:56 -0600164 "\n# Please, select '{}' command type listed above".format(
Alex Savatieiev9c642112019-02-26 13:55:43 -0600165 args.command
166 )
167 )
168 return
169 else:
170 # form function name to call
Alex Savatieievc9055712019-03-01 14:43:56 -0600171 _method_name = "do_" + args.type
172 _target_module = __import__("cfg_checker.modules."+args.command, fromlist=[""])
173 _method = getattr(_target_module, _method_name)
Alex Savatieiev9c642112019-02-26 13:55:43 -0600174
Alex Savatieiev5118de02019-02-20 15:50:42 -0600175 # Execute the command
Alex Savatieiev9c642112019-02-26 13:55:43 -0600176 result = _method(args)
Alex Savatieiev5118de02019-02-20 15:50:42 -0600177
178 logger.debug(result)
Alex Savatieiev5118de02019-02-20 15:50:42 -0600179
Alex Savatieiev4c406322019-02-28 17:37:09 -0600180def cli_main():
Alex Savatieieve47f7f42019-02-20 16:41:23 -0600181 try:
182 config_check_entrypoint()
Alex Savatieiev63576832019-02-27 15:46:26 -0600183 except CheckerException as e:
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600184 logger_cli.error("\nERROR: {}".format(
185 e.message
186 ))
187
Alex Savatieieve9613992019-02-21 18:20:35 -0600188 exc_type, exc_value, exc_traceback = sys.exc_info()
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600189 logger_cli.debug("\n{}".format(
Alex Savatieieve9613992019-02-21 18:20:35 -0600190 "".join(traceback.format_exception(
191 exc_type,
192 exc_value,
193 exc_traceback
194 ))
195 ))
Alex Savatieiev4c406322019-02-28 17:37:09 -0600196
197if __name__ == '__main__':
198 cli_main()