Unified command execution and unit tests
- All arguments inits moved to own clases
- Added unified way to execute commands
- Unit test structure and very basic tests
- Command line script to test coverage
- Argument parsers moved to corresponding commands
- Automatic parsers and command mapping
Change-Id: Id099d14702d9590729583dfd9574bd57022efac5
Related-PROD: PROD-28199
diff --git a/cfg_checker/modules/network/__init__.py b/cfg_checker/modules/network/__init__.py
index 78df6c6..075dccf 100644
--- a/cfg_checker/modules/network/__init__.py
+++ b/cfg_checker/modules/network/__init__.py
@@ -3,6 +3,37 @@
import checker
+command_help = "Network infrastructure checks and reports"
+
+
+def init_parser(_parser):
+ # network subparser
+ net_subparsers = _parser.add_subparsers(dest='type')
+
+ net_check_parser = net_subparsers.add_parser(
+ 'check',
+ help="Do network check and print the result"
+ )
+
+ net_check_parser.add_argument(
+ '--detailed',
+ action="store_true", default=False,
+ help="Print error details after summary"
+ )
+
+ net_report_parser = net_subparsers.add_parser(
+ 'report',
+ help="Generate network check report"
+ )
+
+ net_report_parser.add_argument(
+ '--html',
+ metavar='network_html_filename',
+ help="HTML filename to save report"
+ )
+
+ return _parser
+
def _prepare_check():
_checker_class = checker.NetworkChecker()
@@ -11,7 +42,16 @@
return _checker_class
+def _prepare_map():
+ _map_class = None
+
+ return _map_class
+
+
def do_check(args):
+ # Net Checks
+ # should not print map, etc...
+ # Just bare summary and errors
logger_cli.info("# Network check to console")
netChecker = _prepare_check()
netChecker.print_network_report()
@@ -28,7 +68,11 @@
def do_report(args):
- logger_cli.info("# Network report")
+ # Network Report
+ # should generate Static HTML page
+ # with node/network map and values
+
+ logger_cli.info("# Network report (check, node map")
_filename = args_utils.get_arg(args, 'html')
@@ -36,3 +80,35 @@
netChecker.create_html_report(_filename)
return
+
+
+def do_map(args):
+ # Network Map
+ # Should generate network map to console or HTML
+ logger_cli.info("# Network report")
+
+ _type, _filename = args_utils.get_network_map_type_and_filename(args)
+ # networkMap = _prepare_map
+
+ # TODO: Create map class to generate network map
+
+ return
+
+
+def do_ping(args):
+ # Network pinger
+ # Checks if selected nodes are pingable
+ # with a desireble parameters: MTU, Frame, etc
+
+ # TODO: Simple ping based on parameters
+
+ return
+
+
+def do_trace(args):
+ # Network packet tracer
+ # Check if packet is delivered to proper network host
+
+ # TODO: Packet tracer
+
+ return
diff --git a/cfg_checker/modules/network/checker.py b/cfg_checker/modules/network/checker.py
index 48e7acb..7e6a239 100644
--- a/cfg_checker/modules/network/checker.py
+++ b/cfg_checker/modules/network/checker.py
@@ -115,6 +115,11 @@
for _ip_str in _ip4s:
# create interface class
_if = ipaddress.IPv4Interface(_ip_str)
+ # check if this is a VIP
+ # ...all those will have /32 mask
+ net_data['vip'] = None
+ if _if.network.prefixlen == 32:
+ net_data['vip'] = str(_if.exploded)
if 'name' not in net_data:
net_data['name'] = net_name
if 'ifs' not in net_data:
@@ -303,47 +308,44 @@
_name = _host['name']
_rc_mtu = _r['mtu'] if 'mtu' in _r else None
-
- # Check if this is a VIP
- if _if.network.prefixlen == 32:
- _name = " "*20
- _ip_str += " VIP"
- _rc_mtu = "(-)"
- _enabled = "(-)"
- _r_gate = "-"
-
- # Check if this is a default MTU
- elif _host['mtu'] == '1500':
- # reclass is empty if MTU is untended to be 1500
- _rc_mtu = "(-)"
- elif _rc_mtu:
- _rc_mtu_s = str(_rc_mtu)
- # if there is an MTU value, match it
- if _host['mtu'] != _rc_mtu_s:
+ _rc_mtu_s = str(_rc_mtu) if _rc_mtu else '(-)'
+ # check if this is a VIP address
+ # no checks needed if yes.
+ if _host['vip'] != _ip_str:
+ if _rc_mtu:
+ # if there is an MTU value, match it
+ if _host['mtu'] != _rc_mtu_s:
+ self.errors.add_error(
+ self.errors.NET_MTU_MISMATCH,
+ host=hostname,
+ if_name=_name,
+ if_cidr=_ip_str,
+ reclass_mtu=_rc_mtu,
+ runtime_mtu=_host['mtu']
+ )
+ elif _host['mtu'] != '1500':
+ # there is no MTU value in reclass
+ # and runtime value is not default
self.errors.add_error(
- self.errors.NET_MTU_MISMATCH,
+ self.errors.NET_MTU_EMPTY,
host=hostname,
if_name=_name,
if_cidr=_ip_str,
- reclass_mtu=_rc_mtu,
- runtime_mtu=_host['mtu']
+ if_mtu=_host['mtu']
)
else:
- # there is no MTU value in reclass
- self.errors.add_error(
- self.errors.NET_MTU_EMPTY,
- host=hostname,
- if_name=_name,
- if_cidr=_ip_str,
- if_mtu=_host['mtu']
- )
+ # this is a VIP
+ _name = " "*20
+ _ip_str += " VIP"
+ _enabled = "(-)"
+ _r_gate = "-"
_text = "{0:25} {1:19} {2:5}{3:10} {4:4}{5:10} " \
"{6} / {7} / {8}".format(
_name,
_ip_str,
_host['mtu'],
- "("+_rc_mtu_s+")" if _rc_mtu else "(No!)",
+ _rc_mtu_s,
_host['state'],
_enabled,
_gate,
diff --git a/cfg_checker/modules/packages/__init__.py b/cfg_checker/modules/packages/__init__.py
index 5e717d6..a4a81bd 100644
--- a/cfg_checker/modules/packages/__init__.py
+++ b/cfg_checker/modules/packages/__init__.py
@@ -2,6 +2,35 @@
import checker
+command_help = "Package versions check (Candidate vs Installed)"
+
+
+def init_parser(_parser):
+ # packages subparser
+ pkg_subparsers = _parser.add_subparsers(dest='type')
+
+ pkg_report_parser = pkg_subparsers.add_parser(
+ 'report',
+ help="Report package versions to HTML file"
+ )
+ pkg_report_parser.add_argument(
+ '--full',
+ action="store_true", default=False,
+ help="HTML report will have all of the packages, not just errors"
+ )
+ pkg_report_parser.add_argument(
+ '--html',
+ metavar='packages_html_filename',
+ help="HTML filename to save report"
+ )
+ pkg_report_parser.add_argument(
+ '--csv',
+ metavar='packages_csv_filename',
+ help="CSV filename to save report"
+ )
+
+ return _parser
+
def do_report(args):
"""Create package versions report, HTML
@@ -9,7 +38,7 @@
:args: - parser arguments
:return: - no return value
"""
- _type, _filename = args_utils.get_report_type_and_filename(args)
+ _type, _filename = args_utils.get_package_report_type_and_filename(args)
# init connection to salt and collect minion data
pChecker = checker.CloudPackageChecker()
diff --git a/cfg_checker/modules/reclass/__init__.py b/cfg_checker/modules/reclass/__init__.py
index adae6df..4b8b667 100644
--- a/cfg_checker/modules/reclass/__init__.py
+++ b/cfg_checker/modules/reclass/__init__.py
@@ -8,6 +8,45 @@
import validator
+command_help = "Reclass related checks and reports"
+
+
+def init_parser(_parser):
+ # reclass subparsers
+ reclass_subparsers = _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"
+ )
+ reclass_diff_parser.add_argument(
+ '--html',
+ metavar='reclass_html_filename',
+ help="HTML filename to save report"
+ )
+
+ return _parser
+
def do_list(args):
logger_cli.info("# Reclass list")