Multi env support and Kube client integration
Kube friendly Beta
Package versions supports Kube env
Added:
- Env type detection
- New option: --use-env, for selecting env
when function supports multiple detected envs
- Updated config loading
- Each module and command type has supported env check
and stops execution if it is on unsupported env
- Functions can support multiple envs
- Kubernetes dependency
- Kubenernetes API detection: local and remote
- Package checking class hierachy for using Salt or Kube
- Remote pod execution routine
- Flexible SSH/SSH Forwarder classes: with, ssh,do(), etc
- Multithreaded SSH script execution
- Number of workers parameter, default 5
Fixed:
- Config dependency
- Command loading with supported envs list
- Unittests structure and execution flow updated
- Unittests fixes
- Fixed debug mode handling
- Unified command type/support routine
- Nested attrs getter/setter
Change-Id: I3ade693ac21536e2b5dcee4b24d511749dc72759
Related-PROD: PROD-35811
diff --git a/cfg_checker/modules/network/mapper.py b/cfg_checker/modules/network/mapper.py
index 51f52bb..fd19864 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 salt_master
+from cfg_checker.nodes import SaltNodes
# TODO: use templated approach
# net interface structure should be the same
@@ -33,19 +33,21 @@
def __init__(
self,
+ config,
errors_class=None,
skip_list=None,
skip_list_file=None
):
+ self.salt_master = SaltNodes(config)
logger_cli.info("# Initializing mapper")
# init networks and nodes
self.networks = {}
- self.nodes = salt_master.get_nodes(
+ self.nodes = self.salt_master.get_nodes(
skip_list=skip_list,
skip_list_file=skip_list_file
)
- self.cluster = salt_master.get_info()
- self.domain = salt_master.domain
+ self.cluster = self.salt_master.get_info()
+ self.domain = self.salt_master.domain
# init and pre-populate interfaces
self.interfaces = {k: {} for k in self.nodes}
# Init errors class
@@ -113,13 +115,14 @@
# class uses nodes from self.nodes dict
_reclass = {}
# Get required pillars
- salt_master.get_specific_pillar_for_nodes("linux:network")
- for node in salt_master.nodes.keys():
+ self.salt_master.get_specific_pillar_for_nodes("linux:network")
+ for node in self.salt_master.nodes.keys():
# check if this node
- if not salt_master.is_node_available(node):
+ if not self.salt_master.is_node_available(node):
continue
# get the reclass value
- _pillar = salt_master.nodes[node]['pillars']['linux']['network']
+ _pillar = \
+ self.salt_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:
@@ -169,14 +172,14 @@
# class uses nodes from self.nodes dict
_runtime = {}
logger_cli.info("# Mapping node runtime network data")
- salt_master.prepare_script_on_active_nodes("ifs_data.py")
- _result = salt_master.execute_script_on_active_nodes(
+ self.salt_master.prepare_script_on_active_nodes("ifs_data.py")
+ _result = self.salt_master.execute_script_on_active_nodes(
"ifs_data.py",
args=["json"]
)
- for key in salt_master.nodes.keys():
+ for key in self.salt_master.nodes.keys():
# check if we are to work with this node
- if not salt_master.is_node_available(key):
+ if not self.salt_master.is_node_available(key):
continue
# due to much data to be passed from salt_master,
# it is happening in order
@@ -191,21 +194,21 @@
)
)
_dict = json.loads(_text[_text.find('{'):])
- salt_master.nodes[key]['routes'] = _dict.pop("routes")
- salt_master.nodes[key]['networks'] = _dict
+ self.salt_master.nodes[key]['routes'] = _dict.pop("routes")
+ self.salt_master.nodes[key]['networks'] = _dict
else:
- salt_master.nodes[key]['networks'] = {}
- salt_master.nodes[key]['routes'] = {}
+ self.salt_master.nodes[key]['networks'] = {}
+ self.salt_master.nodes[key]['routes'] = {}
logger_cli.debug("... {} has {} networks".format(
key,
- len(salt_master.nodes[key]['networks'].keys())
+ len(self.salt_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 salt_master.nodes.items():
- if not salt_master.is_node_available(host):
+ for host, node_data in self.salt_master.nodes.items():
+ if not self.salt_master.is_node_available(host):
continue
for net_name, net_data in node_data['networks'].items():
@@ -460,7 +463,7 @@
for hostname in names:
_notes = []
node = hostname.split('.')[0]
- if not salt_master.is_node_available(hostname, log=False):
+ if not self.salt_master.is_node_available(hostname, log=False):
logger_cli.info(
" {0:8} {1}".format(node, "node not available")
)
@@ -513,7 +516,7 @@
# get gate and routes if proto is static
if _proto == 'static':
# get the gateway for current net
- _routes = salt_master.nodes[hostname]['routes']
+ _routes = self.salt_master.nodes[hostname]['routes']
_route = _routes[_net] if _net in _routes else None
# get the default gateway
if 'default' in _routes: