8 # - Check Namen in der Variable?
10 import os
, sys
, re
, getopt
, operator
13 on_tty
= sys
.stdout
.isatty()
16 tty_black
= '\033[30m'
18 tty_green
= '\033[32m'
19 tty_yellow
= '\033[33m'
21 tty_magenta
= '\033[35m'
23 tty_white
= '\033[37m'
24 tty_bgred
= '\033[41m'
25 tty_bggreen
= '\033[42m'
26 tty_bgyellow
= '\033[43m'
27 tty_bgblue
= '\033[44m'
28 tty_bgmagenta
= '\033[45m'
29 tty_bgcyan
= '\033[46m'
30 tty_bgwhite
= '\033[47m'
32 tty_underline
= '\033[4m'
33 tty_normal
= '\033[0m'
34 tty_ok
= tty_green
+ tty_bold
+ 'OK' + tty_normal
35 tty_error
= tty_red
+ tty_bold
+ 'ERROR' + tty_normal
58 if os
.path
.exists("validate_checks"):
60 defaults_path
= 'defaults'
67 files
= os
.listdir('checks')
68 return [ f
for f
in files
if f
.endswith(".include") and not f
.startswith('.') ] + \
69 [ f
for f
in files
if not f
.endswith(".include") and not f
.startswith('.') ]
72 def get_perfometer_files():
73 files
= os
.listdir('web/plugins/perfometer')
74 return [f
for f
in files
if f
.endswith(".py") and not f
.startswith('.')]
77 def check_has_perfdata(check
):
78 return check_info
[check
].get("has_perfdata", False)
87 def is_snmp_check(check
):
88 return check
in snmp_info
91 def all_nonfunction_vars():
93 name
for name
, value
in globals().items()
94 if name
[0] != '_' and type(value
) != type(lambda: 0)
98 def get_manpage(check
):
99 if not check
in manpage
:
101 manpage
[check
] = open('checkman/%s' % check
.split('.')[0]).read()
104 return manpage
[check
]
107 def get_checkfile(check
):
108 if not check
in checkfiles
:
110 checkfiles
[check
] = open('checks/%s' % check
.split('.')[0]).read()
112 checkfiles
[check
] = ""
113 return checkfiles
[check
]
116 def grep_manpage(check
, match
, section
=None):
117 manpage
= get_manpage(check
)
119 return not re
.search(match
, manpage
) is None
122 for line
in [l
.strip() for l
in manpage
.split("\n")]:
123 if line
== '[%s]' % section
:
124 # Block starts with this line
126 elif sec_started
== True and (line
== '' or line
.startswith('[')):
127 # Reached nex section. Didn't find a match ... so return false
129 elif sec_started
== True:
130 if not re
.search(match
, line
) is None:
137 sys
.stderr
.write("%s\n" % msg
)
138 sys
.stderr
.write("\n")
139 for s
, l
, t
in _args
:
140 sys
.stderr
.write(' %3s, --%-15s %s\n' % ('-' + s
.rstrip(':'), l
, t
))
141 sys
.stderr
.write("\n")
145 ignored_variables
= [
153 # Load all checks and record global var definitions
154 # Also read the man pages
156 invalid_global_vars
= {}
157 for check
in get_checks():
158 vars_before_check
= all_nonfunction_vars()
159 execfile('checks/%s' % check
)
160 vars_after_check
= all_nonfunction_vars()
162 global_vars
[check
] = []
163 for name
in vars_after_check
:
164 if name
not in ignored_variables
and name
not in vars_before_check
:
165 global_vars
[check
] += [name
]
167 # Load all perfometers
169 for f
in get_perfometer_files():
170 execfile('web/plugins/perfometer/' + f
)
178 LINELENGTH_LIMIT
= 140
204 # #############################################################################
206 # #############################################################################
208 # Verify global vars:
209 # - Are the global configuration vars mentioned in the manpage
210 # - Are the other (internal) helper vars namend correctly
213 def is_valid_global_vars(check
):
217 def verify_global_vars(check
):
218 check_file
= check
.split('.')[0]
220 # No global vars registered by this check
221 if not check_file
in global_vars
:
224 # Loop all global vars of this check and verify them
225 for var
in global_vars
[check_file
]:
227 if not var
.islower():
230 # Documented configuration vars can be skipped
231 if not invalid
and grep_manpage(check
, "^%s" % var
, 'configuration'):
234 # Check unknown vars for correct prefix
235 if not var
.startswith('%s_' % check_file
):
239 if not check_file
in invalid_global_vars
:
240 invalid_global_vars
[check_file
] = [var
]
242 invalid_global_vars
[check_file
] += [var
]
244 return not check_file
in invalid_global_vars
248 # - Is there some code to be reindented?
251 def is_valid_reindent(check
):
255 def verify_reindent(check
):
256 f
= open('checks/%s' % check
.split('.')[0])
257 r
= reindent
.Reindenter(f
)
263 # - are there 'print' statements in the code?
264 # - are there 'sys.*.write' statements?
267 def is_valid_debug(check
):
271 def verify_debug(check
):
272 f
= open('checks/%s' % check
.split('.')[0])
273 for l
in f
.read().split("\n"):
275 if l
.startswith('print ') or l
.startswith('print('):
277 elif l
.startswith('sys.stdout.write'):
279 elif l
.startswith('sys.stderr.write'):
286 # - Are there too long lines in the check?
289 def is_valid_linelength(check
):
293 def verify_linelength(check
):
294 """ Read the checkfile and compare all lines with the maximum line length """
295 for line
in get_checkfile(check
).split("\n"):
296 if len(line
) > LINELENGTH_LIMIT
:
302 # - Does the check have a manpage?
305 def is_valid_manpage(check
):
309 def verify_manpage(check
):
310 return os
.path
.exists('checkman/%s' % check
)
313 # SNMP scan function:
314 # - Does the snmp check have a scan function?
317 def is_valid_snmp_scan(check
):
318 return is_snmp_check(check
)
321 def verify_snmp_scan(check
):
322 return check
in snmp_scan_functions
326 # Does the chekc which produces perfdata have a pnp template?
329 def is_valid_pnp_tmpl(check
):
330 return check_has_perfdata(check
)
333 def verify_pnp_tmpl(check
):
334 return os
.path
.exists('pnp-templates/check_mk-%s.php' % check
)
338 # Checks with perfdata should provide a perfometer
341 def is_valid_perfometer(check
):
342 return check_has_perfdata(check
)
345 def verify_perfometer(check
):
346 return 'check_mk-' + check
in perfometers
349 # Has this check a group assigned to?
350 def is_valid_wato(check
):
354 def verify_wato(check
):
355 group
= check_info
[check
]["group"]
356 if group
== "obsolete":
360 for line
in file("web/plugins/wato/check_parameters.py"):
362 if line
.startswith("checkgroups.append(("):
365 this_group
= line
.strip(",").strip('"').strip("'")
366 if group
== this_group
:
374 # #############################################################################
376 # #############################################################################
379 ('t:', 'tests=', 'Put one or more tests (comma separated) to limit the validations to perform'),
380 ('c:', 'checks=', 'Put one or more checks (comma separated) to limit the checks to validate'),
381 ('l:', 'score-limit=',
382 'Set an upper score limit. Only checks with a lower score will be shown'),
383 ('a', 'alternative-output', 'Choose an alternative output format (only listing the problems)'),
384 ('v', 'verbose', 'Enable verbose output'),
385 ('h', 'help', 'Show help message'),
392 _alternative_output
= False
395 opts
, args
= getopt
.getopt(sys
.argv
[1:], ''.join([x
[0] for x
in _args
]), [x
[1] for x
in _args
])
396 except getopt
.error
, msg
:
399 if o
in ('-v', '--verbose'):
401 elif o
in ('-l', '--score-limit'):
402 _score_limit
= int(a
)
403 elif o
in ('-a', '--alternative-output'):
404 _alternative_output
= True
406 elif o
in ('-c', '--checks'):
407 _checks
= a
.split(',')
408 elif o
in ('-t', '--tests'):
409 _tests
= a
.split(',')
410 TESTS
= dict([(k
, v
) for k
, v
in TESTS
.iteritems() if k
in _tests
])
411 elif o
in ('-h', '--help'):
414 usage('Unhandled parameter: %s' % str(o
))
421 for check
in get_all_checks():
422 if _checks
and not check
in _checks
:
426 check_results
= TESTS
.copy()
428 for test
in TESTS
.keys():
429 if eval('is_valid_%s(\'%s\')' % (test
, check
)):
430 if not eval('verify_%s(\'%s\')' % (test
, check
)):
431 check_results
[test
] = C_FAILED
432 score
-= WEIGHT
.get(test
, 1)
434 check_results
[test
] = C_INVALID
436 if _score_limit
is None or score
< _score_limit
:
437 results
[check
] = (score
, check_results
)
442 results
= sorted(results
.iteritems(), key
=lambda x
: (x
[1], x
[0]))
445 # 3) Output the results
447 if not _alternative_output
:
448 sys
.stdout
.write('%-25s' % 'Check')
449 for _f
in TESTS
.keys():
450 sys
.stdout
.write('%-15s' % (_f
+ ' (%d)' % WEIGHT
.get(_f
, 1)))
451 sys
.stdout
.write('%-8s' % 'Score')
452 sys
.stdout
.write("\n")
454 for check
, (score
, check_results
) in results
:
455 if score
== SCORE_START
:
462 if not _alternative_output
:
463 sys
.stdout
.write('%s%-25s%s' % (color
, check
, tty_normal
))
466 for _f
in TESTS
.keys():
467 if _alternative_output
:
468 if check_results
[_f
] == C_FAILED
:
470 sys
.stdout
.write("%-25s" % check
)
472 sys
.stdout
.write("%s " % _f
)
474 if check_results
[_f
] == C_FAILED
:
477 elif check_results
[_f
] == C_INVALID
:
478 sub_color
= tty_normal
481 sub_color
= tty_green
484 sys
.stdout
.write('%s%-15s%s' % (sub_color
, label
, tty_normal
))
486 if not _alternative_output
:
487 sys
.stdout
.write('%s%-8s%s' % (color
, score
, tty_normal
))
488 if not _alternative_output
or not first
:
489 sys
.stdout
.write("\n")
492 sys
.stdout
.write("\n")
494 "===========================================================================\n")
495 sys
.stdout
.write("Invalid global vars by check:\n")
497 "===========================================================================\n")
498 # sort checks by name
499 for check
, vars in sorted(invalid_global_vars
.iteritems(), key
=operator
.itemgetter(0)):
501 sys
.stdout
.write("%-25s: %s\n" % (check
, var
))