Parsing Ping return codes and saving iteration details
- ping command detects error types and saves events
- exit on no packets to send
- ping now uses runtime map (as reclass can have DHCP set)
Change-Id: Iad66bd90d0c5a43e04fd785f02f8e1c2769dda62
Related-PROD: PROD-28199
diff --git a/cfg_checker/modules/network/pinger.py b/cfg_checker/modules/network/pinger.py
index 6d0287b..351c05a 100644
--- a/cfg_checker/modules/network/pinger.py
+++ b/cfg_checker/modules/network/pinger.py
@@ -1,18 +1,16 @@
import ipaddress
import json
-from cfg_checker.common import logger, logger_cli
+from cfg_checker.common import logger_cli
from cfg_checker.helpers.console_utils import Progress
from cfg_checker.modules.network.mapper import NetworkMapper
+from cfg_checker.modules.network.network_errors import NetworkErrors
from cfg_checker.nodes import salt_master
-# ping -s 9072 -M do -n -c 1 -w 1 -W 1 ctl01
-
-
# This is independent class with a salt.nodes input
class NetworkPinger(object):
- def __init__(self, mtu=None, detailed=False):
+ def __init__(self, mtu=None, detailed=False, errors_class=None):
logger_cli.info("# Initializing")
# all active nodes in the cloud
self.target_nodes = salt_master.get_nodes()
@@ -22,11 +20,17 @@
self.packet_size = int(self.target_mtu) - 20 - 8
self.detailed_summary = detailed
+ if errors_class:
+ self.errors = errors_class
+ else:
+ logger_cli.debug("... init error logs folder")
+ self.errors = NetworkErrors()
+
def _collect_node_addresses(self, target_net):
# use reclass model and standard methods
# to create list of nodes with target network
- _mapper = NetworkMapper()
- _reclass = _mapper.map_network(_mapper.RECLASS)
+ _mapper = NetworkMapper(errors_class=self.errors)
+ _reclass = _mapper.map_network(_mapper.RUNTIME)
if target_net in _reclass:
return _reclass[target_net]
else:
@@ -90,11 +94,17 @@
pass
logger_cli.info("-> {} packets to send".format(_count))
+ if not _count:
+ logger_cli.warning(
+ "\n# WARNING: No packets to send for '{}', "
+ "check network configuration\n".format(network_cidr_str)
+ )
+
+ return -1
+
# do ping of packets
logger_cli.info("# Pinging nodes: MTU={}".format(self.target_mtu))
salt_master.prepare_script_on_active_nodes("ping.py")
- _errors = []
- _success = []
_progress = Progress(_count)
_progress_index = 0
_node_index = 0
@@ -144,37 +154,53 @@
if len(_params["stderr"]) > 0:
_stderr = "stderr:\n{}\n".format(_params["stderr"])
- if _params["returncode"]:
- _errors.append("FAIL: {}{}{}".format(
- _body,
- _stdout,
- _stderr
- ))
+ if not _params["returncode"]:
+ # 0
+ self.errors.add_error(
+ self.errors.NET_PING_SUCCESS,
+ ping_path=_body,
+ stdout=_stdout,
+ stderr=_stderr
+ )
+ elif _params["returncode"] == 68:
+ # 68 is a 'can't resove host error'
+ self.errors.add_error(
+ self.errors.NET_PING_NOT_RESOLVED,
+ ping_path=_body,
+ stdout=_stdout,
+ stderr=_stderr
+ )
+ elif _params["returncode"] > 1:
+ # >1 is when no actial (any) response
+ self.errors.add_error(
+ self.errors.NET_PING_ERROR,
+ ping_path=_body,
+ stdout=_stdout,
+ stderr=_stderr
+ )
else:
- _success.append("PASS: {}{}{}".format(
- _body,
- _stdout,
- _stderr
- ))
+ # 1 is for timeouts amd/or packet lost
+ self.errors.add_error(
+ self.errors.NET_PING_TIMEOUT,
+ ping_path=_body,
+ stdout=_stdout,
+ stderr=_stderr
+ )
# Parse results back in place
src_data["targets"] = _result
_progress.end()
- if self.detailed_summary:
- logger_cli.info("\n{:=^8s}".format("PASS"))
- logger_cli.info("\n".join(_success))
- else:
- logger.info("\n{:=^8s}".format("PASS"))
- logger.info("\n".join(_success))
- if len(_errors) > 0:
- logger_cli.info("\n{:=^8s}".format("FAIL"))
- logger_cli.info("\n".join(_errors))
+ return 0
+ def print_summary(self):
+ logger_cli.info(self.errors.get_summary(print_zeros=False))
+
+ def print_details(self):
+ # Detailed errors
logger_cli.info(
- "# {} failed, {} passed".format(
- len(_errors),
- len(_success)
+ "\n{}\n".format(
+ self.errors.get_errors()
)
)