def do_snmptranslate(walk_filename): # type: (str) -> None if not walk_filename: raise MKGeneralException("Please provide the name of a SNMP walk file") walk_path = "%s/%s" % (cmk.utils.paths.snmpwalks_dir, walk_filename) if not os.path.exists(walk_path): raise MKGeneralException("The walk '%s' does not exist" % walk_path) def translate(lines): # type: (List[bytes]) -> List[Tuple[bytes, bytes]] result_lines = [] try: oids_for_command = [] for line in lines: oids_for_command.append(line.split(b" ")[0]) command = [ b"snmptranslate", b"-m", b"ALL", b"-M+%s" % cmk.utils.paths.local_mib_dir ] + oids_for_command p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=open(os.devnull, "w"), close_fds=True) p.wait() if p.stdout is None: raise RuntimeError() output = p.stdout.read() result = output.split(b"\n")[0::2] for idx, line in enumerate(result): result_lines.append((line.strip(), lines[idx].strip())) except Exception as e: console.error("%s\n" % e) return result_lines # Translate n-oid's per cycle entries_per_cycle = 500 translated_lines = [] # type: List[Tuple[bytes, bytes]] walk_lines = open(walk_path).readlines() console.error("Processing %d lines.\n" % len(walk_lines)) i = 0 while i < len(walk_lines): console.error("\r%d to go... " % (len(walk_lines) - i)) process_lines = walk_lines[i:i + entries_per_cycle] # FIXME: This encoding ping-pong os horrible... translated = translate([six.ensure_binary(pl) for pl in process_lines]) i += len(translated) translated_lines += translated console.error("\rfinished. \n") # Output formatted for translation, line in translated_lines: console.output("%s --> %s\n" % (six.ensure_str(line), six.ensure_str(translation)))
def wrapped_check_func(hostname, *args, **kwargs): # type: (HostName, Any, Any) -> int host_config = config.get_config_cache().get_host_config(hostname) exit_spec = host_config.exit_code_spec() status, infotexts, long_infotexts, perfdata = 0, [], [], [] try: status, infotexts, long_infotexts, perfdata = check_func( hostname, *args, **kwargs) except SystemExit: raise except MKTimeout: if _in_keepalive_mode(): raise else: infotexts.append("Timed out") status = max(status, cast(int, exit_spec.get("timeout", 2))) except (MKAgentError, MKSNMPError, MKIPAddressLookupError) as e: infotexts.append("%s" % e) status = cast(int, exit_spec.get("connection", 2)) except MKGeneralException as e: infotexts.append("%s" % e) status = max(status, cast(int, exit_spec.get("exception", 3))) except Exception: if cmk.utils.debug.enabled(): raise crash_output = cmk.base.crash_reporting.create_check_crash_dump( hostname, check_plugin_name, None, False, None, description, []) infotexts.append( crash_output.replace("Crash dump:\n", "Crash dump:\\n")) status = max(status, cast(int, exit_spec.get("exception", 3))) # Produce the service check result output output_txt = "%s - %s" % (defines.short_service_state_name(status), ", ".join(infotexts)) if perfdata: output_txt += " | %s" % " ".join(perfdata) if long_infotexts: output_txt = "%s\n%s" % (output_txt, "\n".join(long_infotexts)) output_txt += "\n" if _in_keepalive_mode(): keepalive.add_keepalive_active_check_result( hostname, output_txt) console.verbose(output_txt.encode("utf-8")) else: console.output(output_txt.encode("utf-8")) return status
def do_create_config(core, with_agents): console.output("Generating configuration for core (type %s)..." % config.monitoring_core) create_core_config(core) console.output(tty.ok + "\n") if with_agents: try: import cmk.base.cee.agent_bakery # pylint: disable=redefined-outer-name cmk.base.cee.agent_bakery.bake_on_restart() # pylint: disable=no-member except ImportError: pass
def _get_filepaths(self): # type: () -> List[Path] console.output("Collect diagnostics information:\n") filepaths = [] for element in self.elements: filepath = element.add_or_get_file(self.tmp_dump_folder) if filepath is None: console.verbose(" %s: No informations\n" % element.ident) continue console.output(" %s\n" % element.description) filepaths.append(filepath) return filepaths
def do_snmptranslate(walk_filename): if not walk_filename: raise MKGeneralException("Please provide the name of a SNMP walk file") walk_path = "%s/%s" % (cmk.utils.paths.snmpwalks_dir, walk_filename) if not os.path.exists(walk_path): raise MKGeneralException("The walk '%s' does not exist" % walk_path) def translate(lines): result_lines = [] try: oids_for_command = [] for line in lines: oids_for_command.append(line.split(" ")[0]) command = [ "snmptranslate", "-m", "ALL", "-M+%s" % cmk.utils.paths.local_mib_dir ] + oids_for_command p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=open(os.devnull, "w"), close_fds=True) p.wait() output = p.stdout.read() result = output.split("\n")[0::2] for idx, line in enumerate(result): result_lines.append((line.strip(), lines[idx].strip())) except Exception as e: console.error("%s\n" % e) return result_lines # Translate n-oid's per cycle entries_per_cycle = 500 translated_lines = [] walk_lines = open(walk_path).readlines() console.error("Processing %d lines.\n" % len(walk_lines)) i = 0 while i < len(walk_lines): console.error("\r%d to go... " % (len(walk_lines) - i)) process_lines = walk_lines[i:i + entries_per_cycle] translated = translate(process_lines) i += len(translated) translated_lines += translated console.error("\rfinished. \n") # Output formatted for translation, line in translated_lines: console.output("%s --> %s\n" % (line, translation))
def do_create_config(core, with_agents): # type: (MonitoringCore, bool) -> None console.output("Generating configuration for core (type %s)..." % config.monitoring_core) create_core_config(core) console.output(tty.ok + "\n") if with_agents: try: import cmk.base.cee.agent_bakery # pylint: disable=redefined-outer-name,import-outside-toplevel cmk.base.cee.agent_bakery.bake_on_restart() except ImportError: pass
def _create_tarfile(self): # type: () -> None filepaths = self._get_filepaths() console.verbose("Pack temporary files:\n") tarfile_filepath = self.dump_folder.joinpath(str( uuid.uuid4())).with_suffix(SUFFIX) with tarfile.open(name=tarfile_filepath, mode='w:gz') as tar: for filepath in filepaths: console.verbose(" '%s'\n" % self._get_short_filepath(filepath)) tar.add(str(filepath)) console.output("Created diagnostics dump:\n") console.output(" '%s'\n" % self._get_short_filepath(tarfile_filepath))
def do_snmpget(oid, hostnames): # type: (OID, List[HostName]) -> None config_cache = config.get_config_cache() if not hostnames: hostnames = [] for host in config_cache.all_active_realhosts(): host_config = config_cache.get_host_config(host) if host_config.is_snmp_host: hostnames.append(host) for hostname in hostnames: #TODO what about SNMP management boards? snmp_config = create_snmp_host_config(hostname) initialize_single_oid_cache(snmp_config) value = get_single_oid(snmp_config, oid) console.output("%s (%s): %r\n" % (hostname, snmp_config.ipaddress, value)) cmk.base.cleanup.cleanup_globals()
def output_profile(): if not _profile: return _profile.dump_stats(_profile_path) show_profile = os.path.join(os.path.dirname(_profile_path), "show_profile.py") with open(show_profile, "w") as f: f.write("#!/usr/bin/env python\n" "import sys\n" "import pstats\n" "try:\n" " profile_file = sys.argv[1]\n" "except IndexError:\n" " profile_file = %r\n" "stats = pstats.Stats(profile_file)\n" "stats.sort_stats('time').print_stats()\n" % _profile_path) os.chmod(show_profile, 0o755) console.output("Profile '%s' written. Please run %s.\n" % (_profile_path, show_profile), stream=sys.stderr)
def do_core_action(action, quiet=False): # type: (str, bool) -> None if not quiet: console.output("%sing monitoring core..." % action.title()) if config.monitoring_core == "nagios": os.putenv("CORE_NOVERIFY", "yes") command = ["%s/etc/init.d/core" % cmk.utils.paths.omd_root, action] else: command = ["omd", action, "cmc"] p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) result = p.wait() if result != 0: assert p.stdout is not None output = p.stdout.read() if not quiet: console.output("ERROR: %r\n" % output) raise MKGeneralException("Cannot %s the monitoring core: %r" % (action, output)) if not quiet: console.output(tty.ok + "\n")
def execute(self, cmd, args): # type: (str, List[str]) -> Any self._handle_generic_arguments(args) try: try: automation = self._automations[cmd] except KeyError: raise MKAutomationError( "Automation command '%s' is not implemented." % cmd) if automation.needs_checks: config.load_all_checks(check_api.get_check_api_context) if automation.needs_config: config.load(validate_hosts=False) result = automation.execute(args) except (MKAutomationError, MKTimeout) as e: console.error("%s\n" % e) if cmk.utils.debug.enabled(): raise return 1 except Exception as e: if cmk.utils.debug.enabled(): raise console.error("%s\n" % e) return 2 finally: profiling.output_profile() if cmk.utils.debug.enabled(): console.output(pprint.pformat(result) + "\n") else: console.output("%r\n" % (result, )) return 0
def output_profile(): # type: () -> None if not _profile: return _profile.dump_stats(str(_profile_path)) show_profile = _profile_path.with_name("show_profile.py") # TODO Change shebang as soon as we migrate to Python 3 with show_profile.open("w") as f: f.write("""#!/usr/bin/env python import sys import pstats try: profile_file = sys.argv[1] except IndexError: profile_file = %s stats = pstats.Stats(profile_file) stats.sort_stats('time').print_stats()""" % _profile_path) show_profile.chmod(0o755) console.output("Profile '%s' written. Please run %s.\n" % (_profile_path, show_profile), stream=sys.stderr)
def do_snmpget(*args): if not args[0]: raise MKBailOut("You need to specify an OID.") oid = args[0][0] config_cache = config.get_config_cache() hostnames = args[0][1:] if not hostnames: hostnames = [] for host in config_cache.all_active_realhosts(): host_config = config_cache.get_host_config(host) if host_config.is_snmp_host: hostnames.append(host) for hostname in hostnames: #TODO what about SNMP management boards? snmp_config = create_snmp_host_config(hostname) value = get_single_oid(snmp_config, oid) console.output("%s (%s): %r\n" % (hostname, snmp_config.ipaddress, value)) cmk.base.cleanup.cleanup_globals()
def create_diagnostics_dump(): # type: () -> None dump = DiagnosticsDump() dump.create() console.output("Created diagnostics dump:\n") console.output(" '%s'\n" % _get_short_filepath(dump.tarfile_path))
def do_scan_parents(hosts): config_cache = config.get_config_cache() if not hosts: hosts = config_cache.all_active_realhosts() parent_hosts = [] parent_ips = {} parent_rules = [] gateway_hosts = set([]) if config.max_num_processes < 1: config.max_num_processes = 1 outfilename = cmk.utils.paths.check_mk_config_dir + "/parents.mk" if not traceroute_available(): raise MKGeneralException('The program "traceroute" was not found.\n' 'The parent scan needs this program.\n' 'Please install it and try again.') if os.path.exists(outfilename): first_line = open(outfilename, "r").readline() if not first_line.startswith( '# Automatically created by --scan-parents at'): raise MKGeneralException( "conf.d/parents.mk seems to be created manually.\n\n" "The --scan-parents function would overwrite this file.\n" "Please rename it to keep the configuration or delete " "the file and try again.") console.output("Scanning for parents (%d processes)..." % config.max_num_processes) while hosts: chunk = [] while len(chunk) < config.max_num_processes and len(hosts) > 0: host = hosts.pop() host_config = config_cache.get_host_config(host) # skip hosts that already have a parent if host_config.parents: console.verbose("(manual parent) ") continue chunk.append(host) gws = scan_parents_of(config_cache, chunk) for host, (gw, _unused_state, _unused_ping_fails, _unused_message) in zip(chunk, gws): if gw: gateway, gateway_ip, dns_name = gw if not gateway: # create artificial host if dns_name: gateway = dns_name else: gateway = "gw-%s" % (gateway_ip.replace(".", "-")) if gateway not in gateway_hosts: gateway_hosts.add(gateway) parent_hosts.append("%s|parent|ping" % gateway) parent_ips[gateway] = gateway_ip if config.monitoring_host: parent_rules.append( (config.monitoring_host, [gateway])) # make Nagios a parent of gw parent_rules.append((gateway, [host])) elif host != config.monitoring_host and config.monitoring_host: # make monitoring host the parent of all hosts without real parent parent_rules.append((config.monitoring_host, [host])) with open(outfilename, "w") as out: out.write("# Automatically created by --scan-parents at %s\n\n" % time.asctime()) out.write("# Do not edit this file. If you want to convert an\n") out.write("# artificial gateway host into a permanent one, then\n") out.write("# move its definition into another *.mk file\n") out.write("# Parents which are not listed in your all_hosts:\n") out.write("all_hosts += %s\n\n" % pprint.pformat(parent_hosts)) out.write("# IP addresses of parents not listed in all_hosts:\n") out.write("ipaddresses.update(%s)\n\n" % pprint.pformat(parent_ips)) out.write("# Parent definitions\n") out.write("parents += %s\n\n" % pprint.pformat(parent_rules)) console.output("\nWrote %s\n" % outfilename)
def dot(color, dot='o'): if not silent: console.output(tty.bold + color + dot + tty.normal)
def dump_host(hostname): # type: (HostName) -> None config_cache = config.get_config_cache() host_config = config_cache.get_host_config(hostname) console.output("\n") if host_config.is_cluster: nodes = host_config.nodes if nodes is None: raise RuntimeError() color = tty.bgmagenta add_txt = " (cluster of " + (", ".join(nodes)) + ")" else: color = tty.bgblue add_txt = "" console.output( "%s%s%s%-78s %s\n" % (color, tty.bold, tty.white, hostname + add_txt, tty.normal)) ipaddress = _ip_address_for_dump_host(host_config) addresses = "" # type: Optional[str] if not host_config.is_ipv4v6_host: addresses = ipaddress else: try: if host_config.is_ipv6_primary: secondary = _ip_address_for_dump_host(host_config, 4) else: secondary = _ip_address_for_dump_host(host_config, 6) except Exception: secondary = "X.X.X.X" addresses = "%s, %s" % (ipaddress, secondary) if host_config.is_ipv6_primary: addresses += " (Primary: IPv6)" else: addresses += " (Primary: IPv4)" console.output(tty.yellow + "Addresses: " + tty.normal + (addresses if addresses is not None else "No IP") + "\n") tag_template = tty.bold + "[" + tty.normal + "%s" + tty.bold + "]" + tty.normal tags = [(tag_template % ":".join(t)) for t in sorted(host_config.tag_groups.iteritems())] console.output(tty.yellow + "Tags: " + tty.normal + ", ".join(tags) + "\n") labels = [(tag_template % ":".join(l)).encode("utf-8") for l in sorted(host_config.labels.iteritems())] console.output(tty.yellow + "Labels: " + tty.normal + ", ".join(labels) + "\n") # TODO: Clean this up once cluster parent handling has been moved to HostConfig if host_config.is_cluster: parents_list = host_config.nodes if parents_list is None: raise RuntimeError() else: parents_list = host_config.parents if len(parents_list) > 0: console.output(tty.yellow + "Parents: " + tty.normal + ", ".join(parents_list) + "\n") console.output(tty.yellow + "Host groups: " + tty.normal + make_utf8(", ".join(host_config.hostgroups)) + "\n") console.output(tty.yellow + "Contact groups: " + tty.normal + make_utf8(", ".join(host_config.contactgroups)) + "\n") agenttypes = [] sources = data_sources.DataSources(hostname, ipaddress) for source in sources.get_data_sources(): agenttypes.append(source.describe()) if host_config.is_ping_host: agenttypes.append('PING only') console.output(tty.yellow + "Agent mode: " + tty.normal) console.output(sources.describe_data_sources() + "\n") console.output(tty.yellow + "Type of agent: " + tty.normal) if len(agenttypes) == 1: console.output(agenttypes[0] + "\n") else: console.output("\n ") console.output("\n ".join(agenttypes) + "\n") console.output(tty.yellow + "Services:" + tty.normal + "\n") headers = ["checktype", "item", "params", "description", "groups"] colors = [tty.normal, tty.blue, tty.normal, tty.green, tty.normal] table_data = [] # type: tty.TableRows for service in sorted(check_table.get_check_table(hostname).values(), key=lambda s: s.description): table_data.append( (service.check_plugin_name, make_utf8("%s" % service.item), _evaluate_params(service.parameters), make_utf8(service.description), make_utf8(",".join( config_cache.servicegroups_of_service(hostname, service.description))))) tty.print_table(headers, colors, table_data, " ")
def precompile(self): # type: () -> None console.output("Precompiling host checks...") precompile_hostchecks() console.output(tty.ok + "\n")
def dot(color, dot='o'): # type: (str, str) -> None if not silent: console.output(tty.bold + color + dot + tty.normal)