blob: 00e40d258861a50334f793d9e7d5f15f8f7605fa [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
Alex3ebc5632019-04-18 16:47:18 -05005from logging import DEBUG, INFO
Alex Savatieiev06ab17d2019-02-26 18:40:48 -06006
Alex Savatieievc9055712019-03-01 14:43:56 -06007from cfg_checker.common import config, logger, logger_cli
Alex3ebc5632019-04-18 16:47:18 -05008from cfg_checker.common.exception import CheckerException
Alex Savatieiev06ab17d2019-02-26 18:40:48 -06009
Alex Savatieiev5118de02019-02-20 15:50:42 -060010
11pkg_dir = os.path.dirname(__file__)
12pkg_dir = os.path.normpath(pkg_dir)
13
Alex Savatieiev9c642112019-02-26 13:55:43 -060014commands = {
15 'packages': ['report'],
16 'network': ['check', 'report'],
17 'reclass': ['list', 'diff']
18}
Alex Savatieiev5118de02019-02-20 15:50:42 -060019
Alex3ebc5632019-04-18 16:47:18 -050020
Alex Savatieiev5118de02019-02-20 15:50:42 -060021class 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 """
Alex3ebc5632019-04-18 16:47:18 -050039 Main entry point. Uses nested parsers structure
Alex Savatieiev9c642112019-02-26 13:55:43 -060040 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")
Alex3ebc5632019-04-18 16:47:18 -050046
Alex Savatieiev9c642112019-02-26 13:55:43 -060047 # 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(
Alex Savatieiev63576832019-02-27 15:46:26 -060067 '-s',
68 '--sudo',
69 action='store_true', default=True,
70 help="Use sudo for getting salt creds"
71 )
Alex Savatieiev5118de02019-02-20 15:50:42 -060072 subparsers = parser.add_subparsers(dest='command')
73 # packages
74 pkg_parser = subparsers.add_parser(
75 'packages',
76 help="Package versions check (Candidate vs Installed)"
77 )
78 pkg_subparsers = pkg_parser.add_subparsers(dest='type')
79
80 pkg_report_parser = pkg_subparsers.add_parser(
81 'report',
82 help="Report package versions to HTML file"
83 )
Alex41485522019-04-12 17:26:18 -050084 pkg_report_parser.add_argument(
85 '--full',
Alex682e7df2019-04-12 17:51:55 -050086 action="store_true", default=False,
Alex41485522019-04-12 17:26:18 -050087 help="HTML report will have all of the packages, not just errors"
88 )
89 pkg_report_parser.add_argument(
90 '--html',
91 metavar='packages_html_filename',
92 help="HTML filename to save report"
93 )
94 pkg_report_parser.add_argument(
95 '--csv',
96 metavar='packages_csv_filename',
97 help="CSV filename to save report"
98 )
Alex Savatieiev5118de02019-02-20 15:50:42 -060099
100 # networking
101 net_parser = subparsers.add_parser(
102 'network',
Alex Savatieiev9c642112019-02-26 13:55:43 -0600103 help="Network infrastructure checks and reports"
Alex Savatieiev5118de02019-02-20 15:50:42 -0600104 )
105 net_subparsers = net_parser.add_subparsers(dest='type')
106
107 net_check_parser = net_subparsers.add_parser(
108 'check',
109 help="Do network check and print the result"
110 )
Alex Savatieiev5118de02019-02-20 15:50:42 -0600111
Alex3ebc5632019-04-18 16:47:18 -0500112 net_check_parser.add_argument(
113 '--detailed',
114 action="store_true", default=False,
115 help="Print error details after summary"
116 )
117
Alex Savatieiev5118de02019-02-20 15:50:42 -0600118 net_report_parser = net_subparsers.add_parser(
119 'report',
120 help="Generate network check report"
121 )
Alex41485522019-04-12 17:26:18 -0500122
123 net_report_parser.add_argument(
124 '--html',
125 metavar='network_html_filename',
126 help="HTML filename to save report"
127 )
Alex3ebc5632019-04-18 16:47:18 -0500128
Alex Savatieiev9c642112019-02-26 13:55:43 -0600129 # reclass
130 reclass_parser = subparsers.add_parser(
131 'reclass',
132 help="Reclass related checks and reports"
133 )
134 reclass_subparsers = reclass_parser.add_subparsers(dest='type')
135 reclass_list_parser = reclass_subparsers.add_parser(
136 'list',
137 help="List models available to compare"
138 )
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600139 reclass_list_parser.add_argument(
140 "-p",
141 "--models-path",
142 default="/srv/salt/",
143 help="Global path to search models in"
144 )
Alex Savatieiev9c642112019-02-26 13:55:43 -0600145
146 reclass_diff_parser = reclass_subparsers.add_parser(
147 'diff',
148 help="List models available to compare"
149 )
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600150 reclass_diff_parser.add_argument(
151 "--model1",
152 required=True,
153 help="Model A <path>. Model name is the folder name"
154 )
155 reclass_diff_parser.add_argument(
156 "--model2",
157 required=True,
158 help="Model B <path>. Model name is the folder name"
159 )
Alex41485522019-04-12 17:26:18 -0500160 reclass_diff_parser.add_argument(
161 '--html',
162 metavar='reclass_html_filename',
163 help="HTML filename to save report"
164 )
165
Alex3ebc5632019-04-18 16:47:18 -0500166 # parse arguments
Alex Savatieiev9c642112019-02-26 13:55:43 -0600167 try:
168 args = parser.parse_args()
Alex3ebc5632019-04-18 16:47:18 -0500169 except TypeError:
Alex Savatieievc9055712019-03-01 14:43:56 -0600170 logger_cli.info("\n# Please, check arguments")
Alex Savatieiev9c642112019-02-26 13:55:43 -0600171 return
Alex Savatieiev5118de02019-02-20 15:50:42 -0600172
Alex Savatieiev63576832019-02-27 15:46:26 -0600173 # Pass externally configured values
174 config.ssh_uses_sudo = args.sudo
Alex3ebc5632019-04-18 16:47:18 -0500175
Alex Savatieiev799bee32019-02-20 17:19:26 -0600176 # Handle options
177 if args.debug:
178 logger_cli.setLevel(DEBUG)
179 else:
180 logger_cli.setLevel(INFO)
181
Alex Savatieiev9c642112019-02-26 13:55:43 -0600182 # Validate the commands
183 # check command
184 if args.command not in commands:
Alex Savatieievc9055712019-03-01 14:43:56 -0600185 logger_cli.info("\n# Please, type a command listed above")
Alex Savatieiev9c642112019-02-26 13:55:43 -0600186 return
187 elif args.type not in commands[args.command]:
188 # check type
189 logger_cli.info(
Alex Savatieievc9055712019-03-01 14:43:56 -0600190 "\n# Please, select '{}' command type listed above".format(
Alex Savatieiev9c642112019-02-26 13:55:43 -0600191 args.command
192 )
193 )
194 return
195 else:
196 # form function name to call
Alex Savatieievc9055712019-03-01 14:43:56 -0600197 _method_name = "do_" + args.type
Alex3ebc5632019-04-18 16:47:18 -0500198 _target_module = __import__(
199 "cfg_checker.modules."+args.command,
200 fromlist=[""]
201 )
Alex Savatieievc9055712019-03-01 14:43:56 -0600202 _method = getattr(_target_module, _method_name)
Alex3ebc5632019-04-18 16:47:18 -0500203
Alex Savatieiev5118de02019-02-20 15:50:42 -0600204 # Execute the command
Alex Savatieiev9c642112019-02-26 13:55:43 -0600205 result = _method(args)
Alex Savatieiev5118de02019-02-20 15:50:42 -0600206
207 logger.debug(result)
Alex Savatieiev5118de02019-02-20 15:50:42 -0600208
Alex3ebc5632019-04-18 16:47:18 -0500209
Alex Savatieiev4c406322019-02-28 17:37:09 -0600210def cli_main():
Alex Savatieieve47f7f42019-02-20 16:41:23 -0600211 try:
212 config_check_entrypoint()
Alex Savatieiev63576832019-02-27 15:46:26 -0600213 except CheckerException as e:
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600214 logger_cli.error("\nERROR: {}".format(
215 e.message
216 ))
217
Alex Savatieieve9613992019-02-21 18:20:35 -0600218 exc_type, exc_value, exc_traceback = sys.exc_info()
Alex Savatieiev06ab17d2019-02-26 18:40:48 -0600219 logger_cli.debug("\n{}".format(
Alex Savatieieve9613992019-02-21 18:20:35 -0600220 "".join(traceback.format_exception(
221 exc_type,
222 exc_value,
223 exc_traceback
224 ))
225 ))
Alex Savatieiev4c406322019-02-28 17:37:09 -0600226
Alex3ebc5632019-04-18 16:47:18 -0500227
Alex Savatieiev4c406322019-02-28 17:37:09 -0600228if __name__ == '__main__':
229 cli_main()