Licenses: Updated the list of licenses and added a PDF containing all license texts
[check_mk.git] / bin / livedump
blob1d032d4d348c853676c1afd84903ca4321948ae2
1 #!/usr/bin/env python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
10 # | Copyright Mathias Kettner 2012 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 getopt
28 import os
29 import sys
30 import time
32 import livestatus
34 # These variable will be substituted at 'make dist' time
35 __version__ = "1.6.0i1"
38 def dump_templates():
39 check_interval = ""
40 if opt_check_interval is not None:
41 check_interval = "check_interval %d" % opt_check_interval
43 sys.stdout.write("""define host {
44 name livedump-host
45 use check_mk_default
46 register 0
47 active_checks_enabled 0
48 passive_checks_enabled 1
52 define service {
53 name livedump-service
54 register 0
55 active_checks_enabled 0
56 passive_checks_enabled 1
57 check_period 0x0
61 define command {
62 command_name check-livedump
63 command_line echo "WARN - You did an active check, but this check is passive" ; exit 1
66 define timeperiod {
67 timeperiod_name 0x0
68 alias Never ever
71 """ % (check_interval, check_interval))
74 def encode_row(row):
75 for key, val in row.items():
76 if isinstance(val, unicode):
77 row[key] = val.encode("utf-8")
80 # .-Livedump-------------------------------------------------------------.
81 # | _ _ _ |
82 # | | | (_)_ _____ __| |_ _ _ __ ___ _ __ |
83 # | | | | \ \ / / _ \/ _` | | | | '_ ` _ \| '_ \ |
84 # | | |___| |\ V / __/ (_| | |_| | | | | | | |_) | |
85 # | |_____|_| \_/ \___|\__,_|\__,_|_| |_| |_| .__/ |
86 # | |_| |
87 # +----------------------------------------------------------------------+
88 # | The actual livedump |
89 # '----------------------------------------------------------------------'
91 g_connection = None
92 opt_socket = None
95 def connect():
96 global g_connection, opt_socket
98 # TODO: Fix the code and remove the pragma below!
99 if not opt_socket and not omd_root(): # pylint: disable=used-before-assignment
100 bail_out("Please specify the URL of the livestatus socket.")
101 elif omd_root():
102 opt_socket = "unix:%s/tmp/run/live" % omd_root()
104 g_connection = livestatus.SingleSiteConnection(opt_socket)
107 def livedump_config():
108 if opt_dump_templates:
109 dump_templates()
111 check_commands = set([])
113 def prepare_row(row):
114 encode_row(row)
115 check_commands.add(row["check_command"])
116 row["contactsstring"] = (",".join(row["contacts"])).encode("utf-8")
117 if "contact_groups" in row:
118 row["contact_groups"] = (",".join(row["contact_groups"])).encode("utf-8")
120 # Dump host config
121 query = \
122 "GET hosts\n" \
123 "Columns: name alias address groups check_command icon_image " \
124 "max_check_attempts contacts contact_groups\n" + \
125 opt_host_headers + \
126 opt_host_only_headers
127 for row in g_connection.query_table_assoc(query):
128 prepare_row(row)
129 row["groupstring"] = ",".join(row["groups"])
130 sys.stdout.write("define host {\n" " use livedump-host\n")
132 if opt_prefix:
133 sys.stdout.write(" host_name %s%s\n" % (opt_prefix, row["name"]))
134 else:
135 sys.stdout.write(" host_name %s\n" % row["name"])
137 sys.stdout.write(" alias %(alias)s\n"
138 " address %(address)s\n"
139 " host_groups %(groupstring)s\n"
140 " check_command %(check_command)s\n"
141 " max_check_attempts %(max_check_attempts)d\n" % row)
143 if opt_groups:
144 sys.stdout.write(" contacts %s\n" % row["contactsstring"])
145 else:
146 sys.stdout.write(" contact_groups %s\n" % row["contact_groups"])
148 if opt_host_icon:
149 if row.get("icon_image"):
150 sys.stdout.write(" icon_image %s\n" % row["icon_image"])
152 sys.stdout.write("}\n\n")
154 # Dump service config
155 query = \
156 "GET services\n" \
157 "Columns: host_name description groups check_command " \
158 "max_check_attempts contacts\n" + \
159 opt_host_headers + \
160 opt_service_headers
161 for row in g_connection.query_table_assoc(query):
162 prepare_row(row)
163 if row["groups"]:
164 row["groupstring"] = "service_groups " + ",".join(row["groups"])
165 else:
166 row["groupstring"] = ""
167 row["contactsstring"] = (",".join(row["contacts"])).encode("utf-8")
168 sys.stdout.write("define service {\n" " use livedump-service\n")
170 if opt_prefix:
171 sys.stdout.write(" host_name %s%s\n" % (opt_prefix, row["host_name"]))
172 else:
173 sys.stdout.write(" host_name %s\n" % row["host_name"])
175 sys.stdout.write(" description %(description)s\n"
176 " %(groupstring)s\n"
177 " check_command check-livedump\n"
178 " contacts %(contactsstring)s\n"
179 " max_check_attempts %(max_check_attempts)d\n"
180 "}\n\n" % row)
183 def livedump_state():
184 now = time.time()
185 # Dump hosts
186 query = \
187 "GET hosts\n" \
188 "Columns: name state plugin_output perf_data latency\n" \
189 + opt_host_headers \
190 + opt_host_only_headers
192 for row in g_connection.query_table_assoc(query):
193 encode_row(row)
194 row["now"] = now
196 if opt_prefix:
197 sys.stdout.write("host_name=%s%s" % (opt_prefix, row["name"]))
198 else:
199 sys.stdout.write("host_name=%s" % row["name"])
201 sys.stdout.write("""
202 check_type=1
203 check_options=0
204 reschedule_check
205 latency=%(latency).2f
206 start_time=%(now).1f
207 finish_time=%(now).1f
208 return_code=%(state)d
209 output=%(plugin_output)s|%(perf_data)s
211 """ % row)
213 query = \
214 "GET services\n" \
215 "Columns: host_name description state plugin_output perf_data latency\n" \
216 + opt_host_headers \
217 + opt_service_headers
219 for row in g_connection.query_table_assoc(query):
220 row["now"] = now
221 encode_row(row)
223 if opt_prefix:
224 sys.stdout.write("host_name=%s%s" % (opt_prefix, row["host_name"]))
225 else:
226 sys.stdout.write("host_name=%s" % row["host_name"])
228 sys.stdout.write("""
229 service_description=%(description)s
230 check_type=1
231 check_options=0
232 reschedule_check
233 latency=%(latency).2f
234 start_time=%(now).1f
235 finish_time=%(now).1f
236 return_code=%(state)d
237 output=%(plugin_output)s|%(perf_data)s
239 """ % row)
243 # .-Helpers--------------------------------------------------------------.
244 # | _ _ _ |
245 # | | | | | ___| |_ __ ___ _ __ ___ |
246 # | | |_| |/ _ \ | '_ \ / _ \ '__/ __| |
247 # | | _ | __/ | |_) | __/ | \__ \ |
248 # | |_| |_|\___|_| .__/ \___|_| |___/ |
249 # | |_| |
250 # +----------------------------------------------------------------------+
251 # | Various helper functions |
252 # '----------------------------------------------------------------------'
255 def omd_root():
256 return os.getenv("OMD_ROOT")
259 def omd_site():
260 return os.getenv("OMD_SITE")
263 def verbose(x):
264 if opt_verbose:
265 sys.stderr.write("%s\n" % x)
268 def bail_out(x):
269 sys.stderr.write("%s\n" % x)
270 sys.exit(1)
273 def usage():
274 sys.stderr.write("""Usage: %s [OPTION]...
276 -s, --socket S Connect to Livestatus-socket at S
277 -s tcp:10.11.0.55:6557
278 -s unix:/var/run/nagios/rw/live
280 -C, --config Dump configuration (instead of state)
282 -T, --dump-templates Also dump host/service templates
284 -M, --mark-mode Puts the mode (state/configuration dump) in the first
285 line for use with livedump-ssh-recv and similar scripts
287 -p, --prefix P Add a prefix P to hostnames. Use this option to dump live
288 data from multiple sites with duplicated hostnames
290 -O, --host-only-header H Add header H to host queries only (usually Filter: ...)
292 -H, --host-header H Add header H to host queries (usually Filter: ...)
293 This header is also used in service queries
295 -S, --service-header H Add header H to service queries (usually Filter: ...)
297 -i, --interval I Assume this check interval for hosts/services. This is
298 used in nagios config definition "check_interval".
299 Will be used for staleness checks on the server. This
300 option is only used when dumping the config together
301 with templates (-C -T)
303 -G, --include-groups Use contact groups instead of contacts on dumping config
305 --include-host-icon Add host icon_image to config
307 -V, --version Show version and exit
308 -h, --help Show this help
309 -v, --verbose Output debug information on stderr
310 --debug Do not catch Python exceptions
311 """ % os.path.split(sys.argv[0])[1])
314 def print_version():
315 sys.stdout.write("This is livedump version %s\n" % __version__)
319 # .-main-----------------------------------------------------------------.
320 # | _ |
321 # | _ __ ___ __ _(_)_ __ |
322 # | | '_ ` _ \ / _` | | '_ \ |
323 # | | | | | | | (_| | | | | | |
324 # | |_| |_| |_|\__,_|_|_| |_| |
325 # | |
326 # +----------------------------------------------------------------------+
327 # | Main entry point, getopt, etc. |
328 # '----------------------------------------------------------------------'
330 short_options = 'ChVTMp:s:O:H:S:i:vG'
331 long_options = [
332 "config", "help", "version", "dump-templates", "mark-mode", "prefix=", "socket=",
333 "host-only-header=", "host-header=", "service-header=", "interval=", "verbose",
334 "include-groups", "include-host-icon", "debug"
337 opt_verbose = False
338 opt_debug = False
339 opt_socket = None
340 opt_mark_mode = False
341 opt_prefix = ""
342 opt_host_headers = ""
343 opt_host_only_headers = ""
344 opt_service_headers = ""
345 opt_dump_templates = False
346 opt_groups = False
347 opt_host_icon = False
348 opt_check_interval = None
350 try:
351 opts, args = getopt.getopt(sys.argv[1:], short_options, long_options)
352 except getopt.GetoptError, err:
353 sys.stderr.write("%s\n\n" % err)
354 usage()
355 sys.exit(1)
357 for o, a in opts:
358 # Docu modes
359 if o in ['-h', '--help']:
360 usage()
361 sys.exit(0)
362 elif o in ['-V', '--version']:
363 print_version()
364 sys.exit(0)
366 # Modifiers
367 elif o in ['-T', '--dump-templates']:
368 opt_dump_templates = True
369 elif o in ['-M', '--mark-mode']:
370 opt_mark_mode = True
371 elif o in ['-p', '--prefix']:
372 opt_prefix = a
373 elif o in ['-s', '--socket']:
374 opt_socket = a
375 elif o in ['-O', '--host-only-header']:
376 opt_host_only_headers += a + "\n"
377 elif o in ['-H', '--host-header']:
378 opt_host_headers += a + "\n"
379 elif o in ['-S', '--service-header']:
380 opt_service_headers += a + "\n"
381 elif o in ['-i', '--interval']:
382 opt_check_interval = int(a)
383 elif o in ['-v', '--verbose']:
384 opt_verbose = True
385 elif o in ['-G', '--include-groups']:
386 opt_groups = True
387 elif o in ['--include-host-icon']:
388 opt_host_icon = True
389 elif o == '--debug':
390 opt_debug = True
392 # Main modes
393 try:
394 connect()
395 for o, a in opts:
396 if o in ['-C', '--config']:
397 if opt_mark_mode:
398 sys.stdout.write("config %s\n" % omd_site())
399 livedump_config()
400 sys.exit(0)
401 if opt_mark_mode:
402 sys.stdout.write("status\n")
403 livedump_state()
405 except Exception, e:
406 if opt_debug:
407 raise
408 bail_out(e)