Network Module class structure for Kube support
Related-PROD: PROD-35903
Change-Id: I474a347452b472df3e2272357d1a036b4893e844
diff --git a/cfg_checker/common/settings.py b/cfg_checker/common/settings.py
index 89457d7..1a30ac0 100644
--- a/cfg_checker/common/settings.py
+++ b/cfg_checker/common/settings.py
@@ -252,9 +252,9 @@
self.kube_node_user
)
else:
- # Init keys for nodes in case of remote env
- # KUBE_NODE_KEYPATH is provided in case of nodes key would be
- # different to master nodes key, which is supplied
+ # Init key for nodes
+ # KUBE_NODE_KEYPATH is provided in case of node keys would be
+ # different to master node key, which is supplied
# using MCP_SSH_KEY (mandatory) and, for the most cases,
# should be the same for remote envs
if not self.kube_node_keypath and not self.force_no_key:
diff --git a/cfg_checker/modules/network/__init__.py b/cfg_checker/modules/network/__init__.py
index dd8cc98..0245e06 100644
--- a/cfg_checker/modules/network/__init__.py
+++ b/cfg_checker/modules/network/__init__.py
@@ -1,5 +1,6 @@
from cfg_checker.common import logger_cli
from cfg_checker.common.settings import ENV_TYPE_SALT
+from cfg_checker.common.exception import CheckerException
from cfg_checker.helpers import args_utils
from cfg_checker.modules.network import checker, mapper, pinger
@@ -8,6 +9,45 @@
supported_envs = [ENV_TYPE_SALT]
+def _selectClass(_env, strClassHint="checker"):
+ _class = None
+ if _env == ENV_TYPE_SALT:
+ if strClassHint == "checker":
+ _class = checker.SaltNetworkChecker
+ elif strClassHint == "mapper":
+ _class = mapper.SaltNetworkMapper
+ elif _env == ENV_TYPE_KUBE:
+ if strClassHint == "checker":
+ _class = checker.KubeNetworkChecker
+ elif strClassHint == "mapper":
+ _class = mapper.KubeNetworkMapper
+ if not _class:
+ raise CheckerException(
+ "Unknown hint for selecting Network handler Class: '{}'".format(
+ strClassHint
+ )
+ )
+ else:
+ return _class
+
+
+def _selectChecker(_env):
+ pChecker = None
+ if _env == ENV_TYPE_SALT:
+ pChecker = checker.SaltNetworkChecker(
+ config,
+ skip_list=_skip,
+ skip_list_file=_skip_file
+ )
+ elif _env == ENV_TYPE_KUBE:
+ pChecker = checker.KubeNetworkChecker(
+ config,
+ skip_list=_skip,
+ skip_list_file=_skip_file
+ )
+ return pChecker
+
+
def init_parser(_parser):
# network subparser
net_subparsers = _parser.add_subparsers(dest='type')
@@ -73,11 +113,12 @@
# should not print map, etc...
# Just bare summary and errors
# Check if there is supported env found
- args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
+ _env = args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
# Start command
logger_cli.info("# Network check to console")
_skip, _skip_file = args_utils.get_skip_args(args)
- netChecker = checker.NetworkChecker(
+ _class = _selectClass(_env)
+ netChecker = _class(
config,
skip_list=_skip,
skip_list_file=_skip_file
@@ -98,13 +139,14 @@
def do_report(args, config):
# Network Report
# Check if there is supported env found
- args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
+ _env = args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
# Start command
logger_cli.info("# Network report (check, node map")
_filename = args_utils.get_arg(args, 'html')
_skip, _skip_file = args_utils.get_skip_args(args)
- netChecker = checker.NetworkChecker(
+ _class = _selectClass(_env)
+ netChecker = _class(
config,
skip_list=_skip,
skip_list_file=_skip_file
@@ -121,11 +163,12 @@
def do_map(args, config):
# Network Map
# Check if there is supported env found
- args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
+ _env = args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
# Start command
logger_cli.info("# Network report")
_skip, _skip_file = args_utils.get_skip_args(args)
- networkMap = mapper.NetworkMapper(
+ _class = _selectClass(_env, strClassHint="mapper")
+ networkMap = _class(
config,
skip_list=_skip,
skip_list_file=_skip_file
@@ -140,10 +183,11 @@
def do_list(args, config):
# Network List
# Check if there is supported env found
- args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
+ _env = args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
# Start command
_skip, _skip_file = args_utils.get_skip_args(args)
- _map = mapper.NetworkMapper(
+ _class = _selectClass(_env, strClassHint="mapper")
+ _map = _class(
config,
skip_list=_skip,
skip_list_file=_skip_file
@@ -166,7 +210,7 @@
# Checks if selected nodes are pingable
# with a desireble parameters: MTU, Frame, etc
# Check if there is supported env found
- args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
+ _env = args_utils.check_supported_env(ENV_TYPE_SALT, args, config)
# Start command
if not args.cidr:
logger_cli.error("\n# Use mcp-check network list to get list of CIDRs")
diff --git a/cfg_checker/modules/network/checker.py b/cfg_checker/modules/network/checker.py
index eaa2428..f7b55db 100644
--- a/cfg_checker/modules/network/checker.py
+++ b/cfg_checker/modules/network/checker.py
@@ -1,24 +1,14 @@
from cfg_checker.common import logger_cli
-from cfg_checker.modules.network.mapper import NetworkMapper
+from cfg_checker.modules.network.mapper import SaltNetworkMapper, \
+ KubeNetworkMapper
from cfg_checker.modules.network.network_errors import NetworkErrors
from cfg_checker.reports import reporter
class NetworkChecker(object):
- def __init__(
- self,
- config,
- skip_list=None,
- skip_list_file=None
- ):
+ def __init__(self):
logger_cli.debug("... init error logs folder")
self.errors = NetworkErrors()
- self.mapper = NetworkMapper(
- config,
- errors_class=self.errors,
- skip_list=skip_list,
- skip_list_file=skip_list_file
- )
def check_networks(self, map=True):
self.mapper.map_network(self.mapper.RECLASS)
@@ -47,7 +37,7 @@
"""
logger_cli.info("### Generating report to '{}'".format(filename))
_report = reporter.ReportToFile(
- reporter.HTMLNetworkReport(self.mapper.salt_master),
+ reporter.HTMLNetworkReport(self.mapper.master),
filename
)
_report(
@@ -60,3 +50,34 @@
}
)
logger_cli.info("-> Done")
+
+
+class SaltNetworkChecker(NetworkChecker):
+ def __init__(
+ self,
+ config,
+ skip_list=None,
+ skip_list_file=None
+ ):
+ super(SaltNetworkChecker, self).__init__()
+ self.mapper = SaltNetworkMapper(
+ config,
+ errors_class=self.errors,
+ skip_list=skip_list,
+ skip_list_file=skip_list_file
+ )
+
+class KubeNetworkChecker(NetworkChecker):
+ def __init__(
+ self,
+ config,
+ skip_list=None,
+ skip_list_file=None
+ ):
+ super(SaltNetworkChecker, self).__init__()
+ self.mapper = KubeNetworkMapper(
+ config,
+ errors_class=self.errors,
+ skip_list=skip_list,
+ skip_list_file=skip_list_file
+ )
\ No newline at end of file
diff --git a/cfg_checker/modules/network/mapper.py b/cfg_checker/modules/network/mapper.py
index fd19864..2e925f2 100644
--- a/cfg_checker/modules/network/mapper.py
+++ b/cfg_checker/modules/network/mapper.py
@@ -5,7 +5,7 @@
from cfg_checker.common import logger_cli
from cfg_checker.common.exception import InvalidReturnException
from cfg_checker.modules.network.network_errors import NetworkErrors
-from cfg_checker.nodes import SaltNodes
+from cfg_checker.nodes import SaltNodes, KubeNodes
# TODO: use templated approach
# net interface structure should be the same
@@ -38,16 +38,16 @@
skip_list=None,
skip_list_file=None
):
- self.salt_master = SaltNodes(config)
logger_cli.info("# Initializing mapper")
+ self.env_config = config
# init networks and nodes
self.networks = {}
- self.nodes = self.salt_master.get_nodes(
+ self.nodes = self.master.get_nodes(
skip_list=skip_list,
skip_list_file=skip_list_file
)
- self.cluster = self.salt_master.get_info()
- self.domain = self.salt_master.domain
+ self.cluster = self.master.get_info()
+ self.domain = self.master.domain
# init and pre-populate interfaces
self.interfaces = {k: {} for k in self.nodes}
# Init errors class
@@ -115,14 +115,14 @@
# class uses nodes from self.nodes dict
_reclass = {}
# Get required pillars
- self.salt_master.get_specific_pillar_for_nodes("linux:network")
- for node in self.salt_master.nodes.keys():
+ self.master.get_specific_pillar_for_nodes("linux:network")
+ for node in self.master.nodes.keys():
# check if this node
- if not self.salt_master.is_node_available(node):
+ if not self.master.is_node_available(node):
continue
# get the reclass value
_pillar = \
- self.salt_master.nodes[node]['pillars']['linux']['network']
+ self.master.nodes[node]['pillars']['linux']['network']
# we should be ready if there is no interface in reclass for a node
# for example on APT node
if 'interface' in _pillar:
@@ -172,16 +172,16 @@
# class uses nodes from self.nodes dict
_runtime = {}
logger_cli.info("# Mapping node runtime network data")
- self.salt_master.prepare_script_on_active_nodes("ifs_data.py")
- _result = self.salt_master.execute_script_on_active_nodes(
+ self.master.prepare_script_on_active_nodes("ifs_data.py")
+ _result = self.master.execute_script_on_active_nodes(
"ifs_data.py",
args=["json"]
)
- for key in self.salt_master.nodes.keys():
+ for key in self.master.nodes.keys():
# check if we are to work with this node
- if not self.salt_master.is_node_available(key):
+ if not self.master.is_node_available(key):
continue
- # due to much data to be passed from salt_master,
+ # due to much data to be passed from master,
# it is happening in order
if key in _result:
_text = _result[key]
@@ -194,21 +194,21 @@
)
)
_dict = json.loads(_text[_text.find('{'):])
- self.salt_master.nodes[key]['routes'] = _dict.pop("routes")
- self.salt_master.nodes[key]['networks'] = _dict
+ self.master.nodes[key]['routes'] = _dict.pop("routes")
+ self.master.nodes[key]['networks'] = _dict
else:
- self.salt_master.nodes[key]['networks'] = {}
- self.salt_master.nodes[key]['routes'] = {}
+ self.master.nodes[key]['networks'] = {}
+ self.master.nodes[key]['routes'] = {}
logger_cli.debug("... {} has {} networks".format(
key,
- len(self.salt_master.nodes[key]['networks'].keys())
+ len(self.master.nodes[key]['networks'].keys())
))
logger_cli.info("-> done collecting networks data")
logger_cli.info("-> mapping IPs")
# match interfaces by IP subnets
- for host, node_data in self.salt_master.nodes.items():
- if not self.salt_master.is_node_available(host):
+ for host, node_data in self.master.nodes.items():
+ if not self.master.is_node_available(host):
continue
for net_name, net_data in node_data['networks'].items():
@@ -463,7 +463,7 @@
for hostname in names:
_notes = []
node = hostname.split('.')[0]
- if not self.salt_master.is_node_available(hostname, log=False):
+ if not self.master.is_node_available(hostname, log=False):
logger_cli.info(
" {0:8} {1}".format(node, "node not available")
)
@@ -516,7 +516,7 @@
# get gate and routes if proto is static
if _proto == 'static':
# get the gateway for current net
- _routes = self.salt_master.nodes[hostname]['routes']
+ _routes = self.master.nodes[hostname]['routes']
_route = _routes[_net] if _net in _routes else None
# get the default gateway
if 'default' in _routes:
@@ -732,3 +732,37 @@
# " {0:8} {1}".format(hostname.split('.')[0], _text)
# )
# logger_cli.info("\n")
+
+
+class SaltNetworkMapper(NetworkMapper):
+ def __init__(
+ self,
+ config,
+ errors_class=None,
+ skip_list=None,
+ skip_list_file=None
+ ):
+ self.master = SaltNodes(config)
+ super(SaltNetworkMapper, self).__init__(
+ config,
+ errors_class=errors_class,
+ skip_list=skip_list,
+ skip_list_file=skip_list_file
+ )
+
+
+class KubeNetworkMapper(NetworkMapper):
+ def __init__(
+ self,
+ config,
+ errors_class=None,
+ skip_list=None,
+ skip_list_file=None
+ ):
+ self.master = KubeNodes(config)
+ super(KubeNetworkMapper, self).__init__(
+ config,
+ errors_class=errors_class,
+ skip_list=skip_list,
+ skip_list_file=skip_list_file
+ )
diff --git a/cfg_checker/nodes.py b/cfg_checker/nodes.py
index e568cec..615a1a4 100644
--- a/cfg_checker/nodes.py
+++ b/cfg_checker/nodes.py
@@ -196,6 +196,9 @@
logger_cli.warning(
"Multiple domains detected: {}".format(",".join(_domains))
)
+ # TODO: Use domain with biggest node count by default
+ # or force it via config option
+
else:
self.domain = _domains[0]
logger_cli.info("-> {} nodes inactive".format(len(self.skip_list)))