Module: check_mk
Branch: master
Commit: 7810a3743458e17f55649014e2ed372a9c527fe0
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=7810a3743458e1…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Wed Jul 5 11:57:48 2017 +0200
Fixed broken checks when check includes depend on other includes
Change-Id: I8acbc4919d29fe9b8db50d4059e8b0f72a7f661b
---
cmk_base/checks.py | 78 +++++++++++++++++++++----------------------
cmk_base/inventory_plugins.py | 53 +++++++++++++++++------------
2 files changed, 70 insertions(+), 61 deletions(-)
diff --git a/cmk_base/checks.py b/cmk_base/checks.py
index 7ab93a3..53a72fb 100644
--- a/cmk_base/checks.py
+++ b/cmk_base/checks.py
@@ -44,8 +44,8 @@ import cmk_base.check_api as check_api
# like for example check_exists(...)
_check_contexts = {} # The checks are loaded into this dictionary. Each check
- # becomes a separat sub-dictionary, named by the check name
-_include_contexts = {} # These are the contexts of the check include files
+ # has a separate sub-dictionary, named by the check name.
+ # It is populated with the includes and the check itself.
# The following data structures will be filled by the checks
check_info = {} # all known checks
@@ -94,11 +94,7 @@ def get_plugin_paths(*dirs):
filelist = []
for dir in dirs:
filelist += _plugin_pathnames_in_directory(dir)
-
- # read include files always first, but still in the sorted
- # order with local ones last (possibly overriding variables)
- return [ f for f in filelist if f.endswith(".include") ] + \
- [ f for f in filelist if not f.endswith(".include") ]
+ return filelist
# Now read in all checks. Note: this is done *before* reading the
@@ -115,7 +111,6 @@ def load_checks(filelist):
continue # ignore editor backup / temp files
file_name = os.path.basename(f)
- is_include = file_name.endswith(".include")
if file_name in loaded_files:
continue # skip already loaded files (e.g. from local)
@@ -125,6 +120,8 @@ def load_checks(filelist):
known_vars = check_context.keys()
known_checks = check_info.keys()
+ load_check_includes(f, check_context)
+
execfile(f, check_context)
loaded_files.add(file_name)
@@ -136,12 +133,10 @@ def load_checks(filelist):
continue
new_checks = set(check_info.keys()).difference(known_checks)
- if is_include:
- _include_contexts[file_name] = check_context
- else:
- # Now store the check context for all checks found in this file
- for check_name in new_checks:
- _check_contexts[check_name] = check_context
+
+ # Now store the check context for all checks found in this file
+ for check_name in new_checks:
+ _check_contexts[check_name] = check_context
# Collect all variables that the check file did introduce compared to the
# default check context
@@ -171,17 +166,7 @@ def load_checks(filelist):
# Keep track of which variable needs to be set to which context
context_ident_list = _check_variables.setdefault(varname, [])
- if is_include:
- context_ident_list.append(file_name)
- else:
- context_ident_list += new_checks
-
- # Hack to make dependencies between multiple includes work. In case we
- # need more here we need to find another solution.
- # TODO(lm): This needs to be cleaned up. Try to move the includes to
- # python modules that are separated from each other and can refer to
- # each other.
- _include_contexts["if64.include"].update(_include_contexts["if.include"])
+ context_ident_list += new_checks
config.add_check_variables(check_variable_defaults)
@@ -214,19 +199,35 @@ def _new_check_context(check_file_path):
for k, v in check_api._get_check_context():
context[k] = v
- # Load the definitions of the required include files for this check
- # Working with imports when specifying the includes would be much cleaner,
- # sure. But we need to deal with the current check API.
- if check_file_path and not check_file_path.endswith(".include"):
- for include_file_name in includes_of_plugin(check_file_path):
- try:
- context.update(_include_contexts[include_file_name])
- except KeyError, e:
- raise MKGeneralException("The include file %s does not exist" % include_file_name)
-
return context
+# Load the definitions of the required include files for this check
+# Working with imports when specifying the includes would be much cleaner,
+# sure. But we need to deal with the current check API.
+def load_check_includes(check_file_path, check_context):
+ for include_file_name in includes_of_plugin(check_file_path):
+ include_file_path = check_include_file_path(include_file_name)
+ try:
+ execfile(include_file_path, check_context)
+ except Exception, e:
+ console.error("Error in check include file %s: %s\n", include_file_path, e)
+ if cmk.debug.enabled():
+ raise
+ else:
+ continue
+
+
+def check_include_file_path(include_file_name):
+ include_file_path = os.path.join(cmk.paths.checks_dir, include_file_name)
+
+ local_path = os.path.join(cmk.paths.local_checks_dir, include_file_name)
+ if os.path.exists(local_path):
+ include_file_path = local_path
+
+ return include_file_path
+
+
# Parse the check file without executing the code to find the check include
# files the check uses. The following statements are extracted:
# check_info[...] = { "includes": [...] }
@@ -276,7 +277,7 @@ def _plugin_pathnames_in_directory(path):
return sorted([
path + "/" + f
for f in os.listdir(path)
- if not f.startswith(".")
+ if not f.startswith(".") and not f.endswith(".include")
])
else:
return []
@@ -301,10 +302,7 @@ def get_include_context(include_file_name):
def set_check_variable(varname, value):
globals()[varname] = value
for context_ident in _check_variables[varname]:
- if context_ident.endswith(".include"):
- _include_contexts[context_ident][varname] = value
- else:
- _check_contexts[context_ident][varname] = value
+ _check_contexts[context_ident][varname] = value
# FIXME: Clear / unset all legacy variables to prevent confusions in other code trying to
diff --git a/cmk_base/inventory_plugins.py b/cmk_base/inventory_plugins.py
index 43b396a..221ec20 100644
--- a/cmk_base/inventory_plugins.py
+++ b/cmk_base/inventory_plugins.py
@@ -57,13 +57,15 @@ def load(): # pylint: disable=function-redefined
continue # ignore editor backup / temp files
file_name = os.path.basename(f)
- is_include = file_name.endswith(".include")
if file_name in loaded_files:
continue # skip already loaded files (e.g. from local)
try:
plugin_context = _new_inv_context(f)
known_plugins = inv_info.keys()
+
+ load_plugin_includes(f, check_context)
+
execfile(f, plugin_context)
loaded_files.add(file_name)
except Exception, e:
@@ -73,12 +75,9 @@ def load(): # pylint: disable=function-redefined
else:
continue
- if is_include:
- _include_contexts[file_name] = plugin_context
- else:
- # Now store the check context for all plugins found in this file
- for check_name in set(inv_info.keys()).difference(known_plugins):
- _plugin_contexts[check_name] = plugin_context
+ # Now store the check context for all plugins found in this file
+ for check_name in set(inv_info.keys()).difference(known_plugins):
+ _plugin_contexts[check_name] = plugin_context
def _new_inv_context(plugin_file_path):
@@ -95,23 +94,35 @@ def _new_inv_context(plugin_file_path):
for k, v in check_api._get_check_context() + _get_inventory_context():
context[k] = v
- # Load the definitions of the required include files for this check
- # Working with imports when specifying the includes would be much cleaner,
- # sure. But we need to deal with the current check API.
- if plugin_file_path and not plugin_file_path.endswith(".include"):
- for include_file_name in checks.includes_of_plugin(plugin_file_path):
- try:
- context.update(_include_contexts[include_file_name])
- except KeyError, e:
- # inventory plugins may also use check includes. Try to find one.
- try:
- context.update(checks.get_include_context(include_file_name))
- except KeyError, e:
- raise MKGeneralException("The include file %s does not exist" % include_file_name)
-
return context
+# Load the definitions of the required include files for this check
+# Working with imports when specifying the includes would be much cleaner,
+# sure. But we need to deal with the current check API.
+def load_plugin_includes(check_file_path, plugin_context):
+ for include_file_name in checks.includes_of_plugin(check_file_path):
+ include_file_path = os.path.join(cmk.paths.inventory_dir, include_file_name)
+
+ local_path = os.path.join(cmk.paths.local_inventory_dir, include_file_name)
+ if os.path.exists(local_path):
+ include_file_path = local_path
+
+ # inventory plugins may also use check includes. Try to find one.
+ if not os.path.exists(include_file_path):
+ include_file_path = check_include_file_path(include_file_name)
+
+ try:
+ execfile(include_file_path, check_context)
+ except Exception, e:
+ console.error("Error in include file %s: %s\n", include_file_path, e)
+ if cmk.debug.enabled():
+ raise
+ else:
+ continue
+
+
+
def is_snmp_plugin(plugin_type):
info_type = plugin_type.split(".")[0]
return "snmp_info" in inv_info.get(info_type, {})
Module: check_mk
Branch: master
Commit: 59f9eede8ab8dab32d5e192f7f5cb26e4ba3cb85
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=59f9eede8ab8da…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Tue Jul 4 22:03:38 2017 +0200
4937 SNMP bulk walk: Size of bulks can now be configured
When communicating with hosts using SNMP bulk walks the requested
bulks had a fixed maximum size of 10 OIDs. This can now be configured
using the ruleset "Bulk walk: Number of OIDs per bulk".
Change-Id: Ia1f9225a3d5dfe21d8c810ef2ee93a19daf3a128
---
.werks/4937 | 12 ++++++++++++
cmk_base/classic_snmp.py | 5 ++++-
cmk_base/config.py | 8 ++++++++
cmk_base/default_config/base.py | 1 +
web/plugins/wato/check_mk_configuration.py | 21 ++++++++++++++++++++-
5 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/.werks/4937 b/.werks/4937
new file mode 100644
index 0000000..f3195d0
--- /dev/null
+++ b/.werks/4937
@@ -0,0 +1,12 @@
+Title: SNMP bulk walk: Size of bulks can now be configured
+Level: 1
+Component: core
+Compatible: compat
+Edition: cre
+Version: 1.5.0i1
+Date: 1499198496
+Class: feature
+
+When communicating with hosts using SNMP bulk walks the requested
+bulks had a fixed maximum size of 10 OIDs. This can now be configured
+using the ruleset "Bulk walk: Number of OIDs per bulk".
diff --git a/cmk_base/classic_snmp.py b/cmk_base/classic_snmp.py
index 1afb356..82cff9f 100644
--- a/cmk_base/classic_snmp.py
+++ b/cmk_base/classic_snmp.py
@@ -182,16 +182,19 @@ def _snmp_walk_command(hostname):
# (5) privacy protocol (DES|AES) (-x)
# (6) privacy protocol pass phrase (-X)
def _snmp_base_command(what, hostname):
+ options = []
+
if what == 'get':
command = [ 'snmpget' ]
elif what == 'getnext':
command = [ 'snmpgetnext', '-Cf' ]
elif config.is_bulkwalk_host(hostname):
command = [ 'snmpbulkwalk' ]
+
+ options.append("-Cr%d" % config.bulk_walk_size_of(hostname))
else:
command = [ 'snmpwalk' ]
- options = []
credentials = config.snmp_credentials_of(hostname)
if type(credentials) in [ str, unicode ]:
diff --git a/cmk_base/config.py b/cmk_base/config.py
index 05298b5..77623a6 100644
--- a/cmk_base/config.py
+++ b/cmk_base/config.py
@@ -756,6 +756,14 @@ def is_bulkwalk_host(hostname):
return False
+def bulk_walk_size_of(hostname):
+ bulk_sizes = rulesets.host_extra_conf(hostname, snmp_bulk_size)
+ if not bulk_sizes:
+ return 10
+ else:
+ return bulk_sizes[0]
+
+
def is_snmpv2c_host(hostname):
return is_bulkwalk_host(hostname) or \
rulesets.in_binary_hostlist(hostname, snmpv2c_hosts)
diff --git a/cmk_base/default_config/base.py b/cmk_base/default_config/base.py
index ef4cbdc..e78b6b9 100644
--- a/cmk_base/default_config/base.py
+++ b/cmk_base/default_config/base.py
@@ -68,6 +68,7 @@ non_inline_snmp_hosts = [] # Ruleset to disable Inline-SNMP per hos
# use_inline_snmp is enabled.
snmp_limit_oid_range = [] # Ruleset to recduce fetched OIDs of a check, only inline SNMP
+snmp_bulk_size = [] # Ruleset to customize bulk size
record_inline_snmp_stats = False
snmp_default_community = 'public'
snmp_communities = []
diff --git a/web/plugins/wato/check_mk_configuration.py b/web/plugins/wato/check_mk_configuration.py
index 1cb61fb..aa91c4a 100644
--- a/web/plugins/wato/check_mk_configuration.py
+++ b/web/plugins/wato/check_mk_configuration.py
@@ -2348,7 +2348,7 @@ register_rule(group,
register_rule(group,
"bulkwalk_hosts",
- title = _("Hosts using SNMP bulk walk (enforces SNMP v2c)"),
+ title = _("Bulk walk: Hosts using bulk walk (enforces SNMP v2c)"),
help = _("Most SNMP hosts support SNMP version 2c. However, Check_MK defaults to version 1, "
"in order to support as many devices as possible. Please use this ruleset in order "
"to configure SNMP v2c for as many hosts as possible. That version has two advantages: "
@@ -2358,6 +2358,25 @@ register_rule(group,
"bulk walk but behave very bad when it is used. When you want to enable v2c while not using "
"bulk walk, please use the rule set snmpv2c_hosts instead."))
+
+register_rule(group,
+ "snmp_bulk_size",
+ Integer(
+ title = _("Bulk walk: Number of OIDs per bulk"),
+ label = _("Number of OIDs to request per bulk: "),
+ minvalue = 10,
+ maxvalue = 100,
+ default_value = 10,
+ ),
+ help = _("This variable allows you to configure the numbr of OIDs Check_MK should request "
+ "at once. This rule only applies to SNMP hosts that are configured to be bulk walk "
+ "hosts."
+ "You may want to use this rule to tune SNMP performance. Be aware: A higher value "
+ "is not always better. It may decrease the transactions between Check_MK and the "
+ "target system, but may increase the OID overhead in case you only need a small "
+ "amount of OIDs."),
+)
+
register_rule(group,
"snmp_without_sys_descr",
title = _("Hosts without system description OID"),
Module: check_mk
Branch: master
Commit: c3c3c980e524367ebd9b2d1bf6d3371690c9f89d
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=c3c3c980e52436…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Wed Jul 5 09:49:37 2017 +0200
Fixed access to factory_settings default levels after cmk_base refactoring
Change-Id: I81ea96dc514b232a404097d248476cfed69f1945
---
checks/rmon_stats | 1 +
cmk_base/checks.py | 22 +++++++++++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/checks/rmon_stats b/checks/rmon_stats
index d580a18..70f49b9 100644
--- a/checks/rmon_stats
+++ b/checks/rmon_stats
@@ -29,6 +29,7 @@
# statistics(1). etherStatsTable(1). etherStatsEntry(1)
# The MIB is called RMON-MIB
+inventory_if_rules = []
def inventory_rmon_stats(info):
settings = host_extra_conf_merged(host_name(), inventory_if_rules)
diff --git a/cmk_base/checks.py b/cmk_base/checks.py
index ba0e41b..7ab93a3 100644
--- a/cmk_base/checks.py
+++ b/cmk_base/checks.py
@@ -143,9 +143,29 @@ def load_checks(filelist):
for check_name in new_checks:
_check_contexts[check_name] = check_context
+ # Collect all variables that the check file did introduce compared to the
+ # default check context
+ new_check_vars = {}
for varname in set(check_context.keys()).difference(known_vars):
- value = check_context[varname]
+ new_check_vars[varname] = check_context[varname]
+
+ # The default_levels_variable of check_info also declares use of a global
+ # variable. Register it here for this context.
+ for check_name in new_checks:
+ # The check_info is not converted yet (convert_check_info()). This means we need
+ # to deal with old style tuple configured checks
+ if type(check_info[check_name]) == tuple:
+ default_levels_varname = check_default_levels.get(check_name)
+ else:
+ default_levels_varname = check_info[check_name].get("default_levels_variable")
+
+ if default_levels_varname:
+ new_check_vars[default_levels_varname] = \
+ factory_settings.get(default_levels_varname, {})
+ # Save check variables for e.g. after config loading that the config can
+ # be added to the check contexts
+ for varname, value in new_check_vars.items():
if varname[0] != '_' and type(value) not in ignored_variable_types:
check_variable_defaults[varname] = value
Module: check_mk
Branch: master
Commit: 963ec80629dd4e666216f14015cbc8be7015beff
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=963ec80629dd4e…
Author: Sven Rueß <sr(a)mathias-kettner.de>
Date: Wed Jul 5 08:51:59 2017 +0200
New bug related to agent updater
Change-Id: I6647733590f57386cb38995803800e80f3462dbd
---
.bugs/2926 | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/.bugs/2926 b/.bugs/2926
new file mode 100644
index 0000000..d073eb2
--- /dev/null
+++ b/.bugs/2926
@@ -0,0 +1,10 @@
+Title: Permission for agent registration
+Component: wato
+State: open
+Date: 2017-07-05 08:48:58
+Targetversion: future
+Class: todo
+
+There is the permission missing, that created users can only be used for registration of new update agents.
+Customers want to use it for automatic deployment and the user should only be possible to registrate the host
+for automatic updates.