Cleanup config.nodes_of
[check_mk.git] / cmk_base / modes / check_mk.py
blob0c521d4419d5725b1784c9a6915e72ab7f6626f8
1 #!/usr/bin/env python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
16 # check_mk is free software; you can redistribute it and/or modify it
17 # under the terms of the GNU General Public License as published by
18 # the Free Software Foundation in version 2. check_mk is distributed
19 # in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
20 # out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
21 # PARTICULAR PURPOSE. See the GNU General Public License for more de-
22 # tails. You should have received a copy of the GNU General Public
23 # License along with GNU Make; see the file COPYING. If not, write
24 # to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25 # Boston, MA 02110-1301 USA.
27 import os
28 import sys
29 from typing import List # pylint: disable=unused-import
31 import cmk
32 import cmk.utils.tty as tty
33 import cmk.utils.paths
34 import cmk.utils.log
35 import cmk.utils.debug
36 from cmk.utils.exceptions import MKBailOut
38 import cmk_base.data_sources as data_sources
39 import cmk_base.console as console
40 import cmk_base.config as config
41 import cmk_base.discovery as discovery
42 import cmk_base.inventory as inventory
43 import cmk_base.inventory_plugins as inventory_plugins
44 import cmk_base.check_api as check_api
45 import cmk_base.piggyback as piggyback
46 import cmk_base.snmp as snmp
47 import cmk_base.ip_lookup as ip_lookup
48 import cmk_base.profiling as profiling
49 import cmk_base.core
50 import cmk_base.data_sources.abstract
51 import cmk_base.core_nagios
52 import cmk_base.parent_scan
53 import cmk_base.dump_host
54 import cmk_base.backup
55 import cmk_base.packaging
56 import cmk_base.localize
58 from cmk_base.modes import (
59 modes,
60 Mode,
61 Option,
62 keepalive_option,
64 import cmk_base.check_utils
65 from cmk_base.core_factory import create_core
67 # TODO: Investigate all modes and try to find out whether or not we can
68 # set needs_checks=False for them. This would save a lot of IO/time for
69 # these modes.
72 # .--General options-----------------------------------------------------.
73 # | ____ _ _ |
74 # | / ___| ___ _ __ ___ _ __ __ _| | ___ _ __ | |_ ___ |
75 # | | | _ / _ \ '_ \ / _ \ '__/ _` | | / _ \| '_ \| __/ __| |
76 # | | |_| | __/ | | | __/ | | (_| | | | (_) | |_) | |_\__ \_ |
77 # | \____|\___|_| |_|\___|_| \__,_|_| \___/| .__/ \__|___(_) |
78 # | |_| |
79 # +----------------------------------------------------------------------+
80 # | The general options that are available for all Check_MK modes. Only |
81 # | add new general options in case they are really affecting basic |
82 # | things and used by the most of the modes. |
83 # '----------------------------------------------------------------------'
85 _verbosity = 0
88 def option_verbosity():
89 global _verbosity
90 _verbosity += 1
91 cmk.utils.log.set_verbosity(verbosity=_verbosity)
94 modes.register_general_option(
95 Option(
96 long_option="verbose",
97 short_option="v",
98 short_help="Enable verbose output (Use twice for more)",
99 handler_function=option_verbosity,
102 _verbosity = 0
105 def option_cache():
106 data_sources.abstract.DataSource.set_may_use_cache_file()
107 data_sources.abstract.DataSource.set_use_outdated_cache_file()
110 modes.register_general_option(
111 Option(
112 long_option="cache",
113 short_help="Read info from data source cache files when existant, even when it "
114 "is outdated. Only contact the data sources when the cache file "
115 "is absent",
116 handler_function=option_cache,
120 def option_no_cache():
121 cmk_base.data_sources.abstract.DataSource.disable_data_source_cache()
124 modes.register_general_option(
125 Option(
126 long_option="no-cache",
127 short_help="Never use cached information",
128 handler_function=option_no_cache,
132 def option_no_tcp():
133 data_sources.tcp.TCPDataSource.use_only_cache()
136 # TODO: Check whether or not this is used only for -I as written in the help.
137 # Does it affect inventory/checking too?
138 modes.register_general_option(
139 Option(
140 long_option="no-tcp",
141 short_help="For -I: Only use cache files. Skip hosts without cache files.",
142 handler_function=option_no_tcp,
146 def option_usewalk():
147 snmp.enforce_use_stored_walks()
148 ip_lookup.enforce_localhost()
151 modes.register_general_option(
152 Option(
153 long_option="usewalk",
154 short_help="Use snmpwalk stored with --snmpwalk",
155 handler_function=option_usewalk,
159 def option_debug():
160 cmk.utils.debug.enable()
163 modes.register_general_option(
164 Option(
165 long_option="debug",
166 short_help="Let most Python exceptions raise through",
167 handler_function=option_debug,
171 def option_profile():
172 profiling.enable()
175 modes.register_general_option(
176 Option(
177 long_option="profile",
178 short_help="Enable profiling mode",
179 handler_function=option_profile,
183 def option_fake_dns(a):
184 ip_lookup.enforce_fake_dns(a)
187 modes.register_general_option(
188 Option(
189 long_option="fake-dns",
190 short_help="Fake IP addresses of all hosts to be IP. This "
191 "prevents DNS lookups.",
192 handler_function=option_fake_dns,
193 argument=True,
194 argument_descr="IP",
199 # .--list-hosts----------------------------------------------------------.
200 # | _ _ _ _ _ |
201 # | | (_)___| |_ | |__ ___ ___| |_ ___ |
202 # | | | / __| __|____| '_ \ / _ \/ __| __/ __| |
203 # | | | \__ \ ||_____| | | | (_) \__ \ |_\__ \ |
204 # | |_|_|___/\__| |_| |_|\___/|___/\__|___/ |
205 # | |
206 # '----------------------------------------------------------------------'
209 def mode_list_hosts(options, args):
210 hosts = _list_all_hosts(args, options)
211 console.output("\n".join(hosts))
212 if hosts:
213 console.output("\n")
216 # TODO: Does not care about internal group "check_mk"
217 def _list_all_hosts(hostgroups, options):
218 config_cache = config.get_config_cache()
220 hostnames = set()
222 if options.get("all-sites"):
223 hostnames.update(config_cache.all_configured_hosts()) # Return all hosts, including offline
224 if not "include-offline" in options:
225 hostnames -= config.all_configured_offline_hosts()
226 else:
227 hostnames.update(config_cache.all_active_hosts())
228 if "include-offline" in options:
229 hostnames.update(config.all_offline_hosts())
231 if not hostgroups:
232 return sorted(hostnames)
234 hostlist = []
235 for hn in hostnames:
236 for hg in config.hostgroups_of(hn):
237 if hg in hostgroups:
238 hostlist.append(hn)
239 break
241 return sorted(hostlist)
244 modes.register(
245 Mode(
246 long_option="list-hosts",
247 short_option="l",
248 handler_function=mode_list_hosts,
249 argument=True,
250 argument_descr="G1 G2...",
251 argument_optional=True,
252 short_help="Print list of all hosts or members of host groups",
253 long_help=[
254 "Called without argument lists all hosts. You may "
255 "specify one or more host groups to restrict the output to hosts "
256 "that are in at least one of those groups.",
258 sub_options=[
259 Option(
260 long_option="all-sites",
261 short_help="Include hosts of foreign sites",
263 Option(
264 long_option="include-offline",
265 short_help="Include offline hosts",
270 # .--list-tag------------------------------------------------------------.
271 # | _ _ _ _ |
272 # | | (_)___| |_ | |_ __ _ __ _ |
273 # | | | / __| __|____| __/ _` |/ _` | |
274 # | | | \__ \ ||_____| || (_| | (_| | |
275 # | |_|_|___/\__| \__\__,_|\__, | |
276 # | |___/ |
277 # '----------------------------------------------------------------------'
280 def mode_list_tag(args):
281 hosts = _list_all_hosts_with_tags(args)
282 console.output("\n".join(hosts))
283 if hosts:
284 console.output("\n")
287 def _list_all_hosts_with_tags(tags):
288 config_cache = config.get_config_cache()
289 hosts = []
291 if "offline" in tags:
292 hostlist = config.all_offline_hosts()
293 else:
294 hostlist = config_cache.all_active_hosts()
296 config_cache = config.get_config_cache()
297 for h in hostlist:
298 if config.hosttags_match_taglist(config_cache.tag_list_of_host(h), tags):
299 hosts.append(h)
300 return hosts
303 modes.register(
304 Mode(
305 long_option="list-tag",
306 handler_function=mode_list_tag,
307 argument=True,
308 argument_descr="TAG1 TAG2...",
309 argument_optional=True,
310 short_help="List hosts having certain tags",
311 long_help=["Prints all hosts that have all of the specified tags at once."]))
314 # .--list-checks---------------------------------------------------------.
315 # | _ _ _ _ _ |
316 # | | (_)___| |_ ___| |__ ___ ___| | _____ |
317 # | | | / __| __|____ / __| '_ \ / _ \/ __| |/ / __| |
318 # | | | \__ \ ||_____| (__| | | | __/ (__| <\__ \ |
319 # | |_|_|___/\__| \___|_| |_|\___|\___|_|\_\___/ |
320 # | |
321 # '----------------------------------------------------------------------'
324 def mode_list_checks():
325 import cmk.utils.man_pages as man_pages
326 all_check_manuals = man_pages.all_man_pages()
328 checks_sorted = config.check_info.items() + \
329 [ ("check_" + name, entry) for (name, entry) in config.active_check_info.items() ]
330 checks_sorted.sort()
331 for check_plugin_name, check in checks_sorted:
332 man_filename = all_check_manuals.get(check_plugin_name)
333 try:
334 if 'command_line' in check:
335 what = 'active'
336 ty_color = tty.blue
337 elif cmk_base.check_utils.is_snmp_check(check_plugin_name):
338 what = 'snmp'
339 ty_color = tty.magenta
340 else:
341 what = 'tcp'
342 ty_color = tty.yellow
344 if man_filename:
345 title = file(man_filename).readlines()[0].split(":", 1)[1].strip()
346 else:
347 title = "(no man page present)"
349 console.output((tty.bold + "%-44s" + tty.normal
350 + ty_color + " %-6s " + tty.normal
351 + "%s\n") % \
352 (check_plugin_name, what, title))
353 except Exception as e:
354 console.error("ERROR in check %r: %s\n" % (check_plugin_name, e))
357 modes.register(
358 Mode(
359 long_option="list-checks",
360 short_option="L",
361 handler_function=mode_list_checks,
362 needs_config=False,
363 short_help="List all available Check_MK checks",
367 # .--dump-agent----------------------------------------------------------.
368 # | _ _ |
369 # | __| |_ _ _ __ ___ _ __ __ _ __ _ ___ _ __ | |_ |
370 # | / _` | | | | '_ ` _ \| '_ \ _____ / _` |/ _` |/ _ \ '_ \| __| |
371 # | | (_| | |_| | | | | | | |_) |_____| (_| | (_| | __/ | | | |_ |
372 # | \__,_|\__,_|_| |_| |_| .__/ \__,_|\__, |\___|_| |_|\__| |
373 # | |_| |___/ |
374 # '----------------------------------------------------------------------'
377 def mode_dump_agent(hostname):
378 try:
379 config_cache = config.get_config_cache()
380 host_config = config_cache.get_host_config(hostname)
382 if host_config.is_cluster:
383 raise MKBailOut("Can not be used with cluster hosts")
385 ipaddress = ip_lookup.lookup_ip_address(hostname)
387 output = ""
389 sources = data_sources.DataSources(hostname, ipaddress)
390 sources.set_max_cachefile_age(config.check_max_cachefile_age)
392 for source in sources.get_data_sources():
393 if isinstance(source, data_sources.abstract.CheckMKAgentDataSource):
394 output += source.run_raw()
396 # Show errors of problematic data sources
397 has_errors = False
398 for source in sources.get_data_sources():
399 source_state, source_output, _source_perfdata = source.get_summary_result_for_checking()
400 if source_state != 0:
401 console.error("ERROR [%s]: %s\n" % (source.id(), source_output))
402 has_errors = True
404 console.output(output)
405 if has_errors:
406 sys.exit(1)
407 except Exception as e:
408 if cmk.utils.debug.enabled():
409 raise
410 raise MKBailOut("Unhandled exception: %s" % e)
413 modes.register(
414 Mode(
415 long_option="dump-agent",
416 short_option="d",
417 handler_function=mode_dump_agent,
418 argument=True,
419 argument_descr="HOSTNAME|ADDRESS",
420 short_help="Show raw information from agent",
421 long_help=[
422 "Shows the raw information received from the given host. For regular "
423 "hosts it shows the agent output plus possible piggyback information. "
424 "Does not work on clusters but only on real hosts. "
428 # .--dump----------------------------------------------------------------.
429 # | _ |
430 # | __| |_ _ _ __ ___ _ __ |
431 # | / _` | | | | '_ ` _ \| '_ \ |
432 # | | (_| | |_| | | | | | | |_) | |
433 # | \__,_|\__,_|_| |_| |_| .__/ |
434 # | |_| |
435 # '----------------------------------------------------------------------'
438 def mode_dump_hosts(hostlist):
439 config_cache = config.get_config_cache()
440 if not hostlist:
441 hostlist = config_cache.all_active_hosts()
443 for hostname in sorted(hostlist):
444 cmk_base.dump_host.dump_host(hostname)
447 modes.register(
448 Mode(
449 long_option="dump",
450 short_option="D",
451 handler_function=mode_dump_hosts,
452 argument=True,
453 argument_descr="H1 H2...",
454 argument_optional=True,
455 short_help="Dump info about all or some hosts",
456 long_help=[
457 "Dumps out the complete configuration and information "
458 "about one, several or all hosts. It shows all services, hostgroups, "
459 "contacts and other information about that host.",
463 # .--paths---------------------------------------------------------------.
464 # | _ _ |
465 # | _ __ __ _| |_| |__ ___ |
466 # | | '_ \ / _` | __| '_ \/ __| |
467 # | | |_) | (_| | |_| | | \__ \ |
468 # | | .__/ \__,_|\__|_| |_|___/ |
469 # | |_| |
470 # '----------------------------------------------------------------------'
473 def mode_paths():
474 inst = 1
475 conf = 2
476 data = 3
477 pipe = 4
478 local = 5
479 directory = 1
480 fil = 2
482 paths = [
483 (cmk.utils.paths.modules_dir, directory, inst, "Main components of check_mk"),
484 (cmk.utils.paths.checks_dir, directory, inst, "Checks"),
485 (cmk.utils.paths.notifications_dir, directory, inst, "Notification scripts"),
486 (cmk.utils.paths.inventory_dir, directory, inst, "Inventory plugins"),
487 (cmk.utils.paths.agents_dir, directory, inst, "Agents for operating systems"),
488 (cmk.utils.paths.doc_dir, directory, inst, "Documentation files"),
489 (cmk.utils.paths.web_dir, directory, inst, "Check_MK's web pages"),
490 (cmk.utils.paths.check_manpages_dir, directory, inst, "Check manpages (for check_mk -M)"),
491 (cmk.utils.paths.lib_dir, directory, inst, "Binary plugins (architecture specific)"),
492 (cmk.utils.paths.pnp_templates_dir, directory, inst, "Templates for PNP4Nagios"),
494 if config.monitoring_core == "nagios":
495 paths += [
496 (cmk.utils.paths.nagios_startscript, fil, inst, "Startscript for Nagios daemon"),
497 (cmk.utils.paths.nagios_binary, fil, inst, "Path to Nagios executable"),
498 (cmk.utils.paths.nagios_config_file, fil, conf, "Main configuration file of Nagios"),
499 (cmk.utils.paths.nagios_conf_dir, directory, conf,
500 "Directory where Nagios reads all *.cfg files"),
501 (cmk.utils.paths.nagios_objects_file, fil, data,
502 "File into which Nagios configuration is written"),
503 (cmk.utils.paths.nagios_status_file, fil, data, "Path to Nagios status.dat"),
504 (cmk.utils.paths.nagios_command_pipe_path, fil, pipe, "Nagios' command pipe"),
505 (cmk.utils.paths.check_result_path, fil, pipe, "Nagios' check results directory"),
508 paths += [
509 (cmk.utils.paths.default_config_dir, directory, conf, "Directory that contains main.mk"),
510 (cmk.utils.paths.check_mk_config_dir, directory, conf,
511 "Directory containing further *.mk files"),
512 (cmk.utils.paths.apache_config_dir, directory, conf,
513 "Directory where Apache reads all config files"),
514 (cmk.utils.paths.htpasswd_file, fil, conf, "Users/Passwords for HTTP basic authentication"),
515 (cmk.utils.paths.var_dir, directory, data, "Base working directory for variable data"),
516 (cmk.utils.paths.autochecks_dir, directory, data, "Checks found by inventory"),
517 (cmk.utils.paths.precompiled_hostchecks_dir, directory, data, "Precompiled host checks"),
518 (cmk.utils.paths.snmpwalks_dir, directory, data, "Stored snmpwalks (output of --snmpwalk)"),
519 (cmk.utils.paths.counters_dir, directory, data, "Current state of performance counters"),
520 (cmk.utils.paths.tcp_cache_dir, directory, data, "Cached output from agents"),
521 (cmk.utils.paths.logwatch_dir, directory, data,
522 "Unacknowledged logfiles of logwatch extension"),
523 (cmk.utils.paths.livestatus_unix_socket, fil, pipe,
524 "Socket of Check_MK's livestatus module"),
525 (cmk.utils.paths.local_checks_dir, directory, local, "Locally installed checks"),
526 (cmk.utils.paths.local_notifications_dir, directory, local,
527 "Locally installed notification scripts"),
528 (cmk.utils.paths.local_inventory_dir, directory, local,
529 "Locally installed inventory plugins"),
530 (cmk.utils.paths.local_check_manpages_dir, directory, local,
531 "Locally installed check man pages"),
532 (cmk.utils.paths.local_agents_dir, directory, local,
533 "Locally installed agents and plugins"),
534 (cmk.utils.paths.local_web_dir, directory, local, "Locally installed Multisite addons"),
535 (cmk.utils.paths.local_pnp_templates_dir, directory, local,
536 "Locally installed PNP templates"),
537 (cmk.utils.paths.local_doc_dir, directory, local, "Locally installed documentation"),
538 (cmk.utils.paths.local_locale_dir, directory, local, "Locally installed localizations"),
541 def show_paths(title, t):
542 if t != inst:
543 console.output("\n")
544 console.output(tty.bold + title + tty.normal + "\n")
545 for path, filedir, typp, descr in paths:
546 if typp == t:
547 if filedir == directory:
548 path += "/"
549 console.output(" %-47s: %s%s%s\n" % (descr, tty.bold + tty.blue, path, tty.normal))
551 for title, t in [
552 ("Files copied or created during installation", inst),
553 ("Configuration files edited by you", conf),
554 ("Data created by Nagios/Check_MK at runtime", data),
555 ("Sockets and pipes", pipe),
556 ("Locally installed addons", local),
558 show_paths(title, t)
561 modes.register(
562 Mode(
563 long_option="paths",
564 handler_function=mode_paths,
565 needs_config=False,
566 short_help="List all pathnames and directories",
570 # .--backup/restore------------------------------------------------------.
571 # | _ _ __ _ |
572 # | | |__ __ _ ___| | ___ _ _ __ / / __ ___ ___| |_ |
573 # | | '_ \ / _` |/ __| |/ / | | | '_ \ / / '__/ _ \/ __| __| |
574 # | | |_) | (_| | (__| <| |_| | |_) / /| | | __/\__ \ |_ _ |
575 # | |_.__/ \__,_|\___|_|\_\\__,_| .__/_/ |_| \___||___/\__(_) |
576 # | |_| |
577 # '----------------------------------------------------------------------'
580 def mode_backup(*args):
581 cmk_base.backup.do_backup(*args)
584 modes.register(
585 Mode(
586 long_option="backup",
587 handler_function=mode_backup,
588 argument=True,
589 argument_descr="BACKUPFILE.tar.gz",
590 short_help="make backup of configuration and data",
591 long_help=[
592 "Saves all configuration and runtime data to a gzip "
593 "compressed tar file to the path specified as argument.",
598 def mode_restore(*args):
599 cmk_base.backup.do_restore(*args)
602 modes.register(
603 Mode(
604 long_option="restore",
605 handler_function=mode_restore,
606 argument=True,
607 argument_descr="BACKUPFILE.tar.gz",
608 short_help="restore configuration and data",
609 long_help=[
610 "*Erases* the current configuration and data and replaces "
611 "it with that from the backup file."
616 # .--package-------------------------------------------------------------.
617 # | _ |
618 # | _ __ __ _ ___| | ____ _ __ _ ___ |
619 # | | '_ \ / _` |/ __| |/ / _` |/ _` |/ _ \ |
620 # | | |_) | (_| | (__| < (_| | (_| | __/ |
621 # | | .__/ \__,_|\___|_|\_\__,_|\__, |\___| |
622 # | |_| |___/ |
623 # '----------------------------------------------------------------------'
626 def mode_packaging(*args):
627 cmk_base.packaging.do_packaging(*args)
630 modes.register(
631 Mode(
632 long_option="package",
633 short_option="P",
634 handler_function=mode_packaging,
635 argument=True,
636 argument_descr="COMMAND",
637 argument_optional=True,
638 short_help="Do package operations",
639 long_help=[
640 "Brings you into packager mode. Packages are "
641 "used to ship inofficial extensions of Check_MK. Call without "
642 "arguments for a help on packaging."
644 needs_config=False,
648 # .--localize------------------------------------------------------------.
649 # | _ _ _ |
650 # | | | ___ ___ __ _| (_)_______ |
651 # | | |/ _ \ / __/ _` | | |_ / _ \ |
652 # | | | (_) | (_| (_| | | |/ / __/ |
653 # | |_|\___/ \___\__,_|_|_/___\___| |
654 # | |
655 # '----------------------------------------------------------------------'
658 def mode_localize(*args):
659 cmk_base.localize.do_localize(*args)
662 modes.register(
663 Mode(
664 long_option="localize",
665 handler_function=mode_localize,
666 needs_config=False,
667 argument=True,
668 argument_descr="COMMAND",
669 argument_optional=True,
670 short_help="Do localization operations",
671 long_help=[
672 "Brings you into localization mode. You can create "
673 "and/or improve the localization of Check_MKs GUI. "
674 "Call without arguments for a help on localization."
679 # .--config-check--------------------------------------------------------.
680 # | __ _ _ _ |
681 # | ___ ___ _ __ / _(_) __ _ ___| |__ ___ ___| | __ |
682 # | / __/ _ \| '_ \| |_| |/ _` |_____ / __| '_ \ / _ \/ __| |/ / |
683 # | | (_| (_) | | | | _| | (_| |_____| (__| | | | __/ (__| < |
684 # | \___\___/|_| |_|_| |_|\__, | \___|_| |_|\___|\___|_|\_\ |
685 # | |___/ |
686 # '----------------------------------------------------------------------'
687 # TODO: Can we remove this?
689 modes.register(
690 Mode(
691 long_option="config-check",
692 short_option="X",
693 handler_function=lambda: None,
694 short_help="Check configuration for invalid vars",
698 # .--update-dns-cache----------------------------------------------------.
699 # | _ _ |
700 # | _ _ _ __ __| | __| |_ __ ___ ___ |
701 # | | | | | '_ \ / _` | _____ / _` | '_ \/ __|_____ / __| |
702 # | | |_| | |_) | (_| ||_____| (_| | | | \__ \_____| (__ _ |
703 # | \__,_| .__/ \__,_(_) \__,_|_| |_|___/ \___(_) |
704 # | |_| |
705 # '----------------------------------------------------------------------'
708 def mode_update_dns_cache():
709 ip_lookup.update_dns_cache()
712 modes.register(
713 Mode(
714 long_option="update-dns-cache",
715 handler_function=mode_update_dns_cache,
716 short_help="Update IP address lookup cache",
720 # .--clean.-piggyb.------------------------------------------------------.
721 # | _ _ _ |
722 # | ___| | ___ __ _ _ __ _ __ (_) __ _ __ _ _ _| |__ |
723 # | / __| |/ _ \/ _` | '_ \ _____| '_ \| |/ _` |/ _` | | | | '_ \ |
724 # | | (__| | __/ (_| | | | ||_____| |_) | | (_| | (_| | |_| | |_) | |
725 # | \___|_|\___|\__,_|_| |_(_) | .__/|_|\__, |\__, |\__, |_.__(_) |
726 # | |_| |___/ |___/ |___/ |
727 # '----------------------------------------------------------------------'
730 def mode_cleanup_piggyback():
731 from cmk_base.piggyback import cleanup_piggyback_files
732 cleanup_piggyback_files(config.piggyback_max_cachefile_age)
735 modes.register(
736 Mode(
737 long_option="cleanup-piggyback",
738 handler_function=mode_cleanup_piggyback,
739 short_help="Cleanup outdated piggyback files",
743 # .--scan-parents--------------------------------------------------------.
744 # | _ |
745 # | ___ ___ __ _ _ __ _ __ __ _ _ __ ___ _ __ | |_ ___ |
746 # | / __|/ __/ _` | '_ \ _____| '_ \ / _` | '__/ _ \ '_ \| __/ __| |
747 # | \__ \ (_| (_| | | | |_____| |_) | (_| | | | __/ | | | |_\__ \ |
748 # | |___/\___\__,_|_| |_| | .__/ \__,_|_| \___|_| |_|\__|___/ |
749 # | |_| |
750 # '----------------------------------------------------------------------'
753 def mode_scan_parents(options, args):
754 config.load(exclude_parents_mk=True)
756 if "procs" in options:
757 config.max_num_processes = options["procs"]
759 cmk_base.parent_scan.do_scan_parents(args)
762 modes.register(
763 Mode(
764 long_option="scan-parents",
765 handler_function=mode_scan_parents,
766 needs_config=False,
767 # TODO: Sadly needs to be True because the checks need to initialize the check specific
768 # configuration variables before the config can be loaded.
769 needs_checks=True,
770 argument=True,
771 argument_descr="HOST1 HOST2...",
772 argument_optional=True,
773 short_help="Autoscan parents, create conf.d/parents.mk",
774 long_help=[
775 "Uses traceroute in order to automatically detect hosts's parents. "
776 "It creates the file conf.d/parents.mk which "
777 "defines gateway hosts and parent declarations.",
779 sub_options=[
780 Option(
781 long_option="procs",
782 argument=True,
783 argument_descr="N",
784 argument_conv=int,
785 short_help="Start up to N processes in parallel. Defaults to 50.",
790 # .--snmptranslate-------------------------------------------------------.
791 # | _ _ _ |
792 # | ___ _ __ _ __ ___ _ __ | |_ _ __ __ _ _ __ ___| | __ _| |_ ___ |
793 # | / __| '_ \| '_ ` _ \| '_ \| __| '__/ _` | '_ \/ __| |/ _` | __/ _ \ |
794 # | \__ \ | | | | | | | | |_) | |_| | | (_| | | | \__ \ | (_| | || __/ |
795 # | |___/_| |_|_| |_| |_| .__/ \__|_| \__,_|_| |_|___/_|\__,_|\__\___| |
796 # | |_| |
797 # '----------------------------------------------------------------------'
800 def mode_snmptranslate(*args):
801 snmp.do_snmptranslate(*args)
803 modes.register(Mode(
804 long_option="snmptranslate",
805 handler_function=mode_snmptranslate,
806 needs_config=False,
807 argument=True,
808 argument_descr="HOST",
809 short_help="Do snmptranslate on walk",
810 long_help=[
811 "Does not contact the host again, but reuses the hosts walk from the "
812 "directory %s. You can add further MIBs to the directory %s." % \
813 (cmk.utils.paths.snmpwalks_dir, cmk.utils.paths.local_mibs_dir)
818 # .--snmpwalk------------------------------------------------------------.
819 # | _ _ |
820 # | ___ _ __ _ __ ___ _ ____ ____ _| | | __ |
821 # | / __| '_ \| '_ ` _ \| '_ \ \ /\ / / _` | | |/ / |
822 # | \__ \ | | | | | | | | |_) \ V V / (_| | | < |
823 # | |___/_| |_|_| |_| |_| .__/ \_/\_/ \__,_|_|_|\_\ |
824 # | |_| |
825 # '----------------------------------------------------------------------'
827 _oids = [] # type: List[str]
828 _extra_oids = [] # type: List[str]
831 def mode_snmpwalk(options, args):
832 if _oids:
833 options["oids"] = _oids
834 if _extra_oids:
835 options["extraoids"] = _extra_oids
837 snmp.do_snmpwalk(options, args)
840 modes.register(
841 Mode(
842 long_option="snmpwalk",
843 handler_function=mode_snmpwalk,
844 argument=True,
845 argument_descr="HOST1 HOST2...",
846 argument_optional=True,
847 short_help="Do snmpwalk on one or more hosts",
848 long_help=[
849 "Does a complete snmpwalk for the specified hosts both "
850 "on the standard MIB and the enterprises MIB and stores the "
851 "result in the directory '%s'. Use the option --oid one or several "
852 "times in order to specify alternative OIDs to walk. You need to "
853 "specify numeric OIDs. If you want to keep the two standard OIDS "
854 ".1.3.6.1.2.1 and .1.3.6.1.4.1 then use --extraoid for just adding "
855 "additional OIDs to walk." % cmk.utils.paths.snmpwalks_dir,
857 sub_options=[
858 Option(
859 long_option="extraoid",
860 argument=True,
861 argument_descr="A",
862 argument_conv=_extra_oids.append,
863 short_help="Walk also on this OID, in addition to mib-2 and "
864 "enterprises. You can specify this option multiple "
865 "times.",
867 Option(
868 long_option="oid",
869 argument=True,
870 argument_descr="A",
871 argument_conv=_oids.append,
872 short_help="Walk on this OID instead of mib-2 and enterprises. "
873 "You can specify this option multiple times."),
878 # .--snmpget-------------------------------------------------------------.
879 # | _ |
880 # | ___ _ __ _ __ ___ _ __ __ _ ___| |_ |
881 # | / __| '_ \| '_ ` _ \| '_ \ / _` |/ _ \ __| |
882 # | \__ \ | | | | | | | | |_) | (_| | __/ |_ |
883 # | |___/_| |_|_| |_| |_| .__/ \__, |\___|\__| |
884 # | |_| |___/ |
885 # '----------------------------------------------------------------------'
888 def mode_snmpget(*args):
889 snmp.do_snmpget(*args)
892 modes.register(
893 Mode(
894 long_option="snmpget",
895 handler_function=mode_snmpget,
896 argument=True,
897 argument_descr="OID [HOST1 HOST2...]",
898 argument_optional=True,
899 short_help="Fetch single OID from one or multiple hosts",
900 long_help=[
901 "Does a snmpget on the given OID on one or multiple hosts. In case "
902 "no host is given, all known SNMP hosts are queried."
907 # .--flush---------------------------------------------------------------.
908 # | __ _ _ |
909 # | / _| |_ _ ___| |__ |
910 # | | |_| | | | / __| '_ \ |
911 # | | _| | |_| \__ \ | | | |
912 # | |_| |_|\__,_|___/_| |_| |
913 # | |
914 # '----------------------------------------------------------------------'
917 def mode_flush(hosts):
918 config_cache = config.get_config_cache()
920 if not hosts:
921 hosts = config_cache.all_active_hosts()
923 for host in hosts:
924 host_config = config_cache.get_host_config(host)
926 console.output("%-20s: " % host)
927 flushed = False
929 # counters
930 try:
931 os.remove(cmk.utils.paths.counters_dir + "/" + host)
932 console.output(tty.bold + tty.blue + " counters")
933 flushed = True
934 except:
935 pass
937 # cache files
938 d = 0
939 cache_dir = cmk.utils.paths.tcp_cache_dir
940 if os.path.exists(cache_dir):
941 for f in os.listdir(cache_dir):
942 if f == host or f.startswith(host + "."):
943 try:
944 os.remove(cache_dir + "/" + f)
945 d += 1
946 flushed = True
947 except:
948 pass
949 if d == 1:
950 console.output(tty.bold + tty.green + " cache")
951 elif d > 1:
952 console.output(tty.bold + tty.green + " cache(%d)" % d)
954 # piggy files from this as source host
955 d = piggyback.remove_source_status_file(host)
956 if d:
957 console.output(tty.bold + tty.magenta + " piggyback(1)")
959 # logfiles
960 log_dir = cmk.utils.paths.logwatch_dir + "/" + host
961 if os.path.exists(log_dir):
962 d = 0
963 for f in os.listdir(log_dir):
964 if f not in [".", ".."]:
965 try:
966 os.remove(log_dir + "/" + f)
967 d += 1
968 flushed = True
969 except:
970 pass
971 if d > 0:
972 console.output(tty.bold + tty.magenta + " logfiles(%d)" % d)
974 # autochecks
975 count = discovery.remove_autochecks_of(host_config)
976 if count:
977 flushed = True
978 console.output(tty.bold + tty.cyan + " autochecks(%d)" % count)
980 # inventory
981 path = cmk.utils.paths.var_dir + "/inventory/" + host
982 if os.path.exists(path):
983 os.remove(path)
984 console.output(tty.bold + tty.yellow + " inventory")
986 if not flushed:
987 console.output("(nothing)")
989 console.output(tty.normal + "\n")
992 modes.register(
993 Mode(
994 long_option="flush",
995 handler_function=mode_flush,
996 argument=True,
997 argument_descr="HOST1 HOST2...",
998 argument_optional=True,
999 needs_config=False,
1000 short_help="Flush all data of some or all hosts",
1001 long_help=[
1002 "Deletes all runtime data belonging to a host. This includes "
1003 "the inventorized checks, the state of performance counters, "
1004 "cached agent output, and logfiles. Precompiled host checks "
1005 "are not deleted.",
1010 # .--nagios-config-------------------------------------------------------.
1011 # | _ __ _ |
1012 # | _ __ __ _ __ _(_) ___ ___ ___ ___ _ __ / _(_) __ _ |
1013 # | | '_ \ / _` |/ _` | |/ _ \/ __|_____ / __/ _ \| '_ \| |_| |/ _` | |
1014 # | | | | | (_| | (_| | | (_) \__ \_____| (_| (_) | | | | _| | (_| | |
1015 # | |_| |_|\__,_|\__, |_|\___/|___/ \___\___/|_| |_|_| |_|\__, | |
1016 # | |___/ |___/ |
1017 # '----------------------------------------------------------------------'
1020 def mode_dump_nagios_config(args):
1021 from cmk_base.core_nagios import create_config
1022 create_config(sys.stdout, args if len(args) else None)
1025 modes.register(
1026 Mode(
1027 long_option="nagios-config",
1028 short_option="N",
1029 handler_function=mode_dump_nagios_config,
1030 argument=True,
1031 argument_descr="HOST1 HOST2...",
1032 argument_optional=True,
1033 short_help="Output Nagios configuration",
1034 long_help=[
1035 "Outputs the Nagios configuration. You may optionally add a list "
1036 "of hosts. In that case the configuration is generated only for "
1037 "that hosts (useful for debugging).",
1042 def mode_update_no_precompile(options):
1043 from cmk_base.core_config import do_update
1044 do_update(create_core(options), with_precompile=False)
1047 modes.register(
1048 Mode(
1049 long_option="update-no-precompile",
1050 short_option="B",
1051 handler_function=mode_update_no_precompile,
1052 short_help="Create configuration for core",
1053 long_help=[
1054 "Updates the configuration for the monitoring core. In case of Nagios, "
1055 "the file etc/nagios/conf.d/check_mk_objects.cfg is updated. In case of "
1056 "the Microcore, either the file var/check_mk/core/config or the file "
1057 "specified with the option --cmc-file is written.",
1059 sub_options=[
1060 Option(
1061 long_option="cmc-file",
1062 argument=True,
1063 argument_descr="X",
1064 short_help="Relative filename for CMC config file",
1070 # .--compile-------------------------------------------------------------.
1071 # | _ _ |
1072 # | ___ ___ _ __ ___ _ __ (_) | ___ |
1073 # | / __/ _ \| '_ ` _ \| '_ \| | |/ _ \ |
1074 # | | (_| (_) | | | | | | |_) | | | __/ |
1075 # | \___\___/|_| |_| |_| .__/|_|_|\___| |
1076 # | |_| |
1077 # '----------------------------------------------------------------------'
1080 def mode_compile():
1081 cmk_base.core_nagios.precompile_hostchecks()
1084 modes.register(
1085 Mode(
1086 long_option="compile",
1087 short_option="C",
1088 handler_function=mode_compile,
1089 short_help="Precompile host checks",
1093 # .--update--------------------------------------------------------------.
1094 # | _ _ |
1095 # | _ _ _ __ __| | __ _| |_ ___ |
1096 # | | | | | '_ \ / _` |/ _` | __/ _ \ |
1097 # | | |_| | |_) | (_| | (_| | || __/ |
1098 # | \__,_| .__/ \__,_|\__,_|\__\___| |
1099 # | |_| |
1100 # '----------------------------------------------------------------------'
1103 def mode_update(options):
1104 from cmk_base.core_config import do_update
1105 do_update(create_core(options), with_precompile=True)
1108 modes.register(
1109 Mode(
1110 long_option="update",
1111 short_option="U",
1112 handler_function=mode_update,
1113 short_help="Precompile + create config for core",
1114 long_help=[
1115 "Updates the core configuration based on the current Check_MK "
1116 "configuration. When using the Nagios core, the precompiled host "
1117 "checks are created and the nagios configuration is updated. "
1118 "CEE only: When using the Check_MK Microcore, the core is created "
1119 "and the configuration for the Check_MK check helpers is being created.",
1120 "The agent bakery is updating the agents.",
1122 sub_options=[
1123 Option(
1124 long_option="cmc-file",
1125 argument=True,
1126 argument_descr="X",
1127 short_help="Relative filename for CMC config file",
1133 # .--restart-------------------------------------------------------------.
1134 # | _ _ |
1135 # | _ __ ___ ___| |_ __ _ _ __| |_ |
1136 # | | '__/ _ \/ __| __/ _` | '__| __| |
1137 # | | | | __/\__ \ || (_| | | | |_ |
1138 # | |_| \___||___/\__\__,_|_| \__| |
1139 # | |
1140 # '----------------------------------------------------------------------'
1143 def mode_restart():
1144 cmk_base.core.do_restart(create_core())
1147 modes.register(
1148 Mode(
1149 long_option="restart",
1150 short_option="R",
1151 handler_function=mode_restart,
1152 short_help="Precompile + config + core restart",
1156 # .--reload--------------------------------------------------------------.
1157 # | _ _ |
1158 # | _ __ ___| | ___ __ _ __| | |
1159 # | | '__/ _ \ |/ _ \ / _` |/ _` | |
1160 # | | | | __/ | (_) | (_| | (_| | |
1161 # | |_| \___|_|\___/ \__,_|\__,_| |
1162 # | |
1163 # '----------------------------------------------------------------------'
1166 def mode_reload():
1167 cmk_base.core.do_reload(create_core())
1170 modes.register(
1171 Mode(
1172 long_option="reload",
1173 short_option="O",
1174 handler_function=mode_reload,
1175 short_help="Precompile + config + core reload",
1179 # .--man-----------------------------------------------------------------.
1180 # | |
1181 # | _ __ ___ __ _ _ __ |
1182 # | | '_ ` _ \ / _` | '_ \ |
1183 # | | | | | | | (_| | | | | |
1184 # | |_| |_| |_|\__,_|_| |_| |
1185 # | |
1186 # '----------------------------------------------------------------------'
1189 def mode_man(*args):
1190 import cmk.utils.man_pages as man_pages
1191 if args[0]:
1192 man_pages.print_man_page(args[0][0])
1193 else:
1194 man_pages.print_man_page_table()
1197 modes.register(
1198 Mode(
1199 long_option="man",
1200 short_option="M",
1201 handler_function=mode_man,
1202 argument=True,
1203 argument_descr="CHECKTYPE",
1204 argument_optional=True,
1205 needs_config=False,
1206 short_help="Show manpage for check CHECKTYPE",
1207 long_help=[
1208 "Shows documentation about a check type. If /usr/bin/less is "
1209 "available it is used as pager. Exit by pressing Q. "
1210 "Use -M without an argument to show a list of all manual pages."
1215 # .--browse-man----------------------------------------------------------.
1216 # | _ |
1217 # | | |__ _ __ _____ _____ ___ _ __ ___ __ _ _ __ |
1218 # | | '_ \| '__/ _ \ \ /\ / / __|/ _ \_____| '_ ` _ \ / _` | '_ \ |
1219 # | | |_) | | | (_) \ V V /\__ \ __/_____| | | | | | (_| | | | | |
1220 # | |_.__/|_| \___/ \_/\_/ |___/\___| |_| |_| |_|\__,_|_| |_| |
1221 # | |
1222 # '----------------------------------------------------------------------'
1225 def mode_browse_man():
1226 import cmk.utils.man_pages as man_pages
1227 man_pages.print_man_page_browser()
1230 modes.register(
1231 Mode(
1232 long_option="browse-man",
1233 short_option="m",
1234 handler_function=mode_browse_man,
1235 needs_config=False,
1236 short_help="Open interactive manpage browser",
1240 # .--inventory-----------------------------------------------------------.
1241 # | _ _ |
1242 # | (_)_ ____ _____ _ __ | |_ ___ _ __ _ _ |
1243 # | | | '_ \ \ / / _ \ '_ \| __/ _ \| '__| | | | |
1244 # | | | | | \ V / __/ | | | || (_) | | | |_| | |
1245 # | |_|_| |_|\_/ \___|_| |_|\__\___/|_| \__, | |
1246 # | |___/ |
1247 # '----------------------------------------------------------------------'
1250 def mode_inventory(options, args):
1251 inventory_plugins.load_plugins(check_api.get_check_api_context, inventory.get_inventory_context)
1252 config_cache = config.get_config_cache()
1254 if args:
1255 hostnames = modes.parse_hostname_list(args, with_clusters=True)
1256 console.verbose("Doing HW/SW inventory on: %s\n" % ", ".join(hostnames))
1257 else:
1258 # No hosts specified: do all hosts and force caching
1259 hostnames = config_cache.all_active_hosts()
1260 data_sources.abstract.DataSource.set_may_use_cache_file(
1261 not data_sources.abstract.DataSource.is_agent_cache_disabled())
1262 console.verbose("Doing HW/SW inventory on all hosts\n")
1264 if "force" in options:
1265 data_sources.abstract.CheckMKAgentDataSource.use_outdated_persisted_sections()
1267 inventory.do_inv(hostnames)
1270 modes.register(
1271 Mode(
1272 long_option="inventory",
1273 short_option="i",
1274 handler_function=mode_inventory,
1275 argument=True,
1276 argument_descr="HOST1 HOST2...",
1277 argument_optional=True,
1278 short_help="Do a HW/SW-Inventory on some ar all hosts",
1279 long_help=[
1280 "Does a HW/SW-Inventory for all, one or several "
1281 "hosts. If you add the option -f, --force then persisted sections "
1282 "will be used even if they are outdated."
1284 sub_options=[
1285 Option(
1286 long_option="force",
1287 short_option="f",
1288 short_help="Use cached agent data even if it's outdated.",
1293 # .--inventory-as-check--------------------------------------------------.
1294 # | _ _ _ _ |
1295 # |(_)_ ____ _____ _ __ | |_ ___ _ __ _ _ ___| |__ | | __ |
1296 # || | '_ \ \ / / _ \ '_ \| __/ _ \| '__| | | |_____ / __| '_ \| |/ / |
1297 # || | | | \ V / __/ | | | || (_) | | | |_| |_____| (__| | | | < _ |
1298 # ||_|_| |_|\_/ \___|_| |_|\__\___/|_| \__, | \___|_| |_|_|\_(_) |
1299 # | |___/ |
1300 # '----------------------------------------------------------------------'
1303 def mode_inventory_as_check(options, hostname):
1304 inventory_plugins.load_plugins(check_api.get_check_api_context, inventory.get_inventory_context)
1306 return inventory.do_inv_check(hostname, options)
1309 modes.register(
1310 Mode(
1311 long_option="inventory-as-check",
1312 handler_function=mode_inventory_as_check,
1313 argument=True,
1314 argument_descr="HOST",
1315 short_help="Do HW/SW-Inventory, behave like check plugin",
1316 sub_options=[
1317 Option(
1318 long_option="hw-changes",
1319 argument=True,
1320 argument_descr="S",
1321 argument_conv=int,
1322 short_help="Use monitoring state S for HW changes",
1324 Option(
1325 long_option="sw-changes",
1326 argument=True,
1327 argument_descr="S",
1328 argument_conv=int,
1329 short_help="Use monitoring state S for SW changes",
1331 Option(
1332 long_option="sw-missing",
1333 argument=True,
1334 argument_descr="S",
1335 argument_conv=int,
1336 short_help="Use monitoring state S for missing SW packages info",
1338 Option(
1339 long_option="inv-fail-status",
1340 argument=True,
1341 argument_descr="S",
1342 argument_conv=int,
1343 short_help="Use monitoring state S in case of error",
1349 # .--automation----------------------------------------------------------.
1350 # | _ _ _ |
1351 # | __ _ _ _| |_ ___ _ __ ___ __ _| |_(_) ___ _ __ |
1352 # | / _` | | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \ |
1353 # | | (_| | |_| | || (_) | | | | | | (_| | |_| | (_) | | | | |
1354 # | \__,_|\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_| |
1355 # | |
1356 # '----------------------------------------------------------------------'
1359 def mode_automation(args):
1360 import cmk_base.automations as automations
1362 if not args:
1363 raise automations.MKAutomationError("You need to provide arguments")
1365 sys.exit(automations.automations.execute(args[0], args[2:]))
1368 modes.register(
1369 Mode(
1370 long_option="automation",
1371 handler_function=mode_automation,
1372 needs_config=False,
1373 needs_checks=False,
1374 argument=True,
1375 argument_descr="COMMAND...",
1376 argument_optional=True,
1377 short_help="Internal helper to invoke Check_MK actions",
1381 # .--notify--------------------------------------------------------------.
1382 # | _ _ __ |
1383 # | _ __ ___ | |_(_)/ _|_ _ |
1384 # | | '_ \ / _ \| __| | |_| | | | |
1385 # | | | | | (_) | |_| | _| |_| | |
1386 # | |_| |_|\___/ \__|_|_| \__, | |
1387 # | |___/ |
1388 # '----------------------------------------------------------------------'
1391 def mode_notify(options, *args):
1392 import cmk_base.notify as notify
1393 config.load(with_conf_d=True, validate_hosts=False)
1394 # TODO: Fix the code and remove the pragma below!
1395 return notify.do_notify(options, *args) # pylint: disable=no-value-for-parameter
1398 modes.register(
1399 Mode(
1400 long_option="notify",
1401 handler_function=mode_notify,
1402 needs_config=False,
1403 # TODO: Sadly needs to be True because the checks need to initialize the check specific
1404 # configuration variables before the config can be loaded.
1405 needs_checks=True,
1406 argument=True,
1407 argument_descr="MODE",
1408 argument_optional=True,
1409 short_help="Used to send notifications from core",
1410 # TODO: Write long help
1411 sub_options=[
1412 Option(
1413 long_option="log-to-stdout",
1414 short_help="Also write log messages to console",
1416 keepalive_option,
1421 # .--discover-marked-hosts-----------------------------------------------.
1422 # | _ _ _ _ |
1423 # | __| (_)___ ___ _ __ ___ __ _ _ __| | _____ __| | |
1424 # | / _` | / __|/ __| | '_ ` _ \ / _` | '__| |/ / _ \/ _` | |
1425 # | | (_| | \__ \ (__ _| | | | | | (_| | | | < __/ (_| | |
1426 # | \__,_|_|___/\___(_)_| |_| |_|\__,_|_| |_|\_\___|\__,_| |
1427 # | |
1428 # '----------------------------------------------------------------------'
1431 def mode_discover_marked_hosts():
1432 discovery.discover_marked_hosts(create_core())
1435 modes.register(
1436 Mode(
1437 long_option="discover-marked-hosts",
1438 handler_function=mode_discover_marked_hosts,
1439 short_help="Run discovery for hosts known to have changed services",
1440 long_help=[
1441 "Run actual service discovery on all hosts that "
1442 "are known to have new/vanished services due to an earlier run of "
1443 "check-discovery. The results of this discovery may be activated "
1444 "automatically if configured.",
1449 # .--check-discovery-----------------------------------------------------.
1450 # | _ _ _ _ |
1451 # | ___| |__ | | __ __| (_)___ ___ _____ _____ _ __ _ _ |
1452 # | / __| '_ \| |/ / _____ / _` | / __|/ __/ _ \ \ / / _ \ '__| | | | |
1453 # | | (__| | | | < |_____| (_| | \__ \ (_| (_) \ V / __/ | | |_| | |
1454 # | \___|_| |_|_|\_(_) \__,_|_|___/\___\___/ \_/ \___|_| \__, | |
1455 # | |___/ |
1456 # '----------------------------------------------------------------------'
1459 def mode_check_discovery(hostname):
1460 return discovery.check_discovery(hostname, ipaddress=None)
1463 modes.register(
1464 Mode(
1465 long_option="check-discovery",
1466 handler_function=mode_check_discovery,
1467 argument=True,
1468 argument_descr="HOSTNAME",
1469 short_help="Check for not yet monitored services",
1470 long_help=[
1471 "Make Check_MK behave as monitoring plugins that checks if an "
1472 "inventory would find new or vanished services for the host. "
1473 "If configured to do so, this will queue those hosts for automatic "
1474 "discover-marked-hosts"
1479 # .--discover------------------------------------------------------------.
1480 # | _ _ |
1481 # | __| (_)___ ___ _____ _____ _ __ |
1482 # | / _` | / __|/ __/ _ \ \ / / _ \ '__| |
1483 # | | (_| | \__ \ (_| (_) \ V / __/ | |
1484 # | \__,_|_|___/\___\___/ \_/ \___|_| |
1485 # | |
1486 # '----------------------------------------------------------------------'
1489 def mode_discover(options, args):
1490 hostnames = modes.parse_hostname_list(args)
1491 if not hostnames:
1492 # In case of discovery without host restriction, use the cache file
1493 # by default. Otherwise Check_MK would have to connect to ALL hosts.
1494 # This will make Check_MK only contact hosts in case the cache is not
1495 # new enough.
1496 data_sources.abstract.DataSource.set_may_use_cache_file(
1497 not data_sources.abstract.DataSource.is_agent_cache_disabled())
1499 discovery.do_discovery(hostnames, options.get("checks"), options["discover"] == 1)
1502 modes.register(
1503 Mode(
1504 long_option="discover",
1505 short_option="I",
1506 handler_function=mode_discover,
1507 argument=True,
1508 argument_descr="[-I] HOST1 HOST2...",
1509 argument_optional=True,
1510 short_help="Find new services",
1511 long_help=[
1512 "Make Check_MK behave as monitoring plugins that checks if an "
1513 "inventory would find new or vanished services for the host. "
1514 "If configured to do so, this will queue those hosts for automatic "
1515 "discover-marked-hosts",
1516 "Can be restricted to certain check types. Write '--checks df -I' if "
1517 "you just want to look for new filesystems. Use 'check_mk -L' for a "
1518 "list of all check types. Use 'tcp' for all TCP based checks and "
1519 "'snmp' for all SNMP based checks.",
1520 "-II does the same as -I but deletes all existing checks of the "
1521 "specified types and hosts."
1523 sub_options=[
1524 Option(
1525 long_option="discover",
1526 short_option="I",
1527 short_help="Delete existing services before starting discovery",
1528 count=True,
1530 Option(
1531 long_option="checks",
1532 short_help="Restrict discovery to certain check types",
1533 argument=True,
1534 argument_descr="C",
1535 argument_conv=lambda x: config.check_info.keys() if x == "@all" else x.split(","),
1540 # .--check---------------------------------------------------------------.
1541 # | _ _ |
1542 # | ___| |__ ___ ___| | __ |
1543 # | / __| '_ \ / _ \/ __| |/ / |
1544 # | | (__| | | | __/ (__| < |
1545 # | \___|_| |_|\___|\___|_|\_\ |
1546 # | |
1547 # '----------------------------------------------------------------------'
1550 def mode_check(options, args):
1551 import cmk_base.checking as checking
1552 import cmk_base.item_state as item_state
1553 try:
1554 import cmk_base.cee.keepalive as keepalive
1555 except ImportError:
1556 keepalive = None
1558 if keepalive and "keepalive" in options:
1559 # handle CMC check helper
1560 keepalive.enable()
1561 if "keepalive-fd" in options:
1562 keepalive.set_keepalive_fd(options["keepalive-fd"])
1564 keepalive.do_check_keepalive()
1565 return
1567 if "perfdata" in options:
1568 checking.show_perfdata()
1570 if "no-submit" in options:
1571 checking.disable_submit()
1572 item_state.continue_on_counter_wrap()
1574 # handle adhoc-check
1575 hostname = args[0]
1576 if len(args) == 2:
1577 ipaddress = args[1]
1578 else:
1579 ipaddress = None
1581 return checking.do_check(hostname, ipaddress, options.get("checks"))
1584 modes.register(
1585 Mode(
1586 long_option="check",
1587 handler_function=mode_check,
1588 argument=True,
1589 argument_descr="HOST [IPADDRESS]",
1590 argument_optional=True,
1591 short_help="Check all services on the given HOST",
1592 long_help=[
1593 "Execute all checks on the given HOST. Optionally you can specify "
1594 "a second argument, the IPADDRESS. If you don't set this, the "
1595 "configured IP address of the HOST is used.",
1596 "By default the check results are sent to the core. If you provide "
1597 "the option '-n', the results will not be sent to the core and the "
1598 "counters of the check will not be stored.",
1599 "You can use '-v' to see the results of the checks. Add '-p' to "
1600 "also see the performance data of the checks."
1601 "Can be restricted to certain check types. Write '--checks df -I' if "
1602 "you just want to look for new filesystems. Use 'check_mk -L' for a "
1603 "list of all check types. Use 'tcp' for all TCP based checks and "
1604 "'snmp' for all SNMP based checks.",
1606 sub_options=[
1607 Option(
1608 long_option="no-submit",
1609 short_option="n",
1610 short_help="Do not submit results to core, do not save counters",
1612 Option(
1613 long_option="perfdata",
1614 short_option="p",
1615 short_help="Also show performance data (use with -v)",
1617 Option(
1618 long_option="checks",
1619 short_help="Restrict discovery to certain check types",
1620 argument=True,
1621 argument_descr="C",
1622 argument_conv=lambda x: config.check_info.keys() if x == "@all" else x.split(","),
1624 keepalive_option,
1625 Option(
1626 long_option="keepalive-fd",
1627 argument=True,
1628 argument_descr="I",
1629 argument_conv=int,
1630 short_help="File descriptor to send output to",
1635 # .--version-------------------------------------------------------------.
1636 # | _ |
1637 # | __ _____ _ __ ___(_) ___ _ __ |
1638 # | \ \ / / _ \ '__/ __| |/ _ \| '_ \ |
1639 # | \ V / __/ | \__ \ | (_) | | | | |
1640 # | \_/ \___|_| |___/_|\___/|_| |_| |
1641 # | |
1642 # '----------------------------------------------------------------------'
1645 def mode_version():
1646 console.output("""This is Check_MK version %s %s
1647 Copyright (C) 2009 Mathias Kettner
1649 This program is free software; you can redistribute it and/or modify
1650 it under the terms of the GNU General Public License as published by
1651 the Free Software Foundation; either version 2 of the License, or
1652 (at your option) any later version.
1654 This program is distributed in the hope that it will be useful,
1655 but WITHOUT ANY WARRANTY; without even the implied warranty of
1656 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1657 GNU General Public License for more details.
1659 You should have received a copy of the GNU General Public License
1660 along with this program; see the file COPYING. If not, write to
1661 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1662 Boston, MA 02111-1307, USA.
1664 """ % (cmk.__version__, cmk.edition_short().upper()))
1667 modes.register(
1668 Mode(
1669 long_option="version",
1670 short_option="V",
1671 handler_function=mode_version,
1672 short_help="Print the version of Check_MK",
1673 needs_config=False,
1674 needs_checks=False,
1678 # .--help----------------------------------------------------------------.
1679 # | _ _ |
1680 # | | |__ ___| |_ __ |
1681 # | | '_ \ / _ \ | '_ \ |
1682 # | | | | | __/ | |_) | |
1683 # | |_| |_|\___|_| .__/ |
1684 # | |_| |
1685 # '----------------------------------------------------------------------'
1688 def mode_help():
1689 console.output("""WAYS TO CALL:
1692 OPTIONS:
1695 NOTES:
1698 """ % (
1699 modes.short_help(),
1700 modes.general_option_help(),
1701 modes.long_help(),
1705 modes.register(
1706 Mode(
1707 long_option="help",
1708 short_option="h",
1709 handler_function=mode_help,
1710 short_help="Print this help",
1711 needs_config=False,
1712 needs_checks=False,