Module: check_mk
Branch: master
Commit: 5cea2e0d39c7019c6d65295e9e0a599514f50525
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=5cea2e0d39c701…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Tue Jul 17 08:47:12 2018 +0200
6345 FIX Fixed invisible/lost notification rules when editing notification rules
When cloning notification rules or creating notification rules with identical
parameters only one of the rules was shown. The others could be hidden, but
still be in existing.
In other situations, when a user with limited permissions on notification plugins
edits the notification rules, it could happen that all notification rules that
use other plugins were deleted by accident.
These problems were introduced with werk #4167.
CMK-556
Change-Id: Icf56d0dca51d47e89a0c402819b73aaa39952704
---
.werks/6345 | 30 ++++++++++++++++++++++++++++++
cmk/gui/wato/__init__.py | 11 ++++-------
2 files changed, 34 insertions(+), 7 deletions(-)
diff --git a/.werks/6345 b/.werks/6345
new file mode 100644
index 0000000..8365bfc
--- /dev/null
+++ b/.werks/6345
@@ -0,0 +1,30 @@
+Title: Fixed invisible/lost notification rules when editing notification rules
+Level: 2
+Component: notifications
+Class: fix
+Compatible: compat
+Edition: cre
+State: unknown
+Version: 1.6.0i1
+Date: 1531472133
+
+Since werk #4167 it was possible to prevent users from configuring specific
+notification plugins by setting the notification plugin permissions to "no". As
+a result all notification rules that use the not permitted notification plugin
+were not visible anymore to this user.
+
+This hiding of rules could be confusing and lead to bugs. We decided to show all
+rules now but prevent modifications of these rules when the user is not permitted
+to perform the modifications.
+
+When cloning notification rules or creating notification rules with identical
+parameters only one of the rules was shown. The others could be hidden, but
+still be in existing.
+
+In other situations, when a user with limited permissions on notification plugins
+edits the notification rules, it could happen that all notification rules that
+use other plugins were deleted by accident.
+
+These problems were introduced with werk #4167.
+
+CMK-556
diff --git a/cmk/gui/wato/__init__.py b/cmk/gui/wato/__init__.py
index 26dbcc9..c8f051e 100644
--- a/cmk/gui/wato/__init__.py
+++ b/cmk/gui/wato/__init__.py
@@ -7763,7 +7763,9 @@ class NotificationsMode(EventsMode):
else:
listmode = "notifications"
- if show_buttons:
+ actions_allowed = config.user.may("notification_plugin.%s" % rule['notify_plugin'][0])
+
+ if show_buttons and actions_allowed:
anavar = html.var("analyse", "")
delete_url = make_action_link([("mode", listmode), ("user", userid), ("_delete", nr)])
drag_url = make_action_link([("mode", listmode), ("analyse", anavar), ("user", userid), ("_move", nr)])
@@ -7944,12 +7946,7 @@ class ModeNotifications(NotificationsMode):
def _get_notification_rules(self):
- rules = []
- for rule in watolib.load_notification_rules():
- if config.user.may("notification_plugin.%s" % rule['notify_plugin'][0]) and \
- rule not in rules:
- rules.append(rule)
- return rules
+ return watolib.load_notification_rules()
def _save_notification_display_options(self):
Module: check_mk
Branch: master
Commit: 7b7a7da9af8bb4807081403c05737d59ae4df774
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=7b7a7da9af8bb4…
Author: Moritz Kiemer <mo(a)mathias-kettner.de>
Date: Mon Jul 16 09:07:03 2018 +0200
6209 FIX utils.py: Fix display of state markers after URLs
Properly display URLs in service description if they are
followed by a state marker, as in
"... url: http://localhost/heute/check_mk/deploy_agent.py<b class..."
Change-Id: If0b5efeb3ab07e43d771451d70719821a1ae7e9e
---
.werks/6209 | 11 +++++++++++
cmk/gui/utils.py | 3 ++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/.werks/6209 b/.werks/6209
new file mode 100644
index 0000000..b96e558
--- /dev/null
+++ b/.werks/6209
@@ -0,0 +1,11 @@
+Title: utils.py: Fix display of state markers after URLs
+Level: 1
+Component: multisite
+Compatible: compat
+Edition: cre
+Version: 1.6.0i1
+Date: 1531725353
+Class: fix
+
+Properly display URLs in service description if they are
+followed by a state marker.
diff --git a/cmk/gui/utils.py b/cmk/gui/utils.py
index 5442121..c5c0674 100644
--- a/cmk/gui/utils.py
+++ b/cmk/gui/utils.py
@@ -188,9 +188,10 @@ def format_plugin_output(output, row=None, shall_escape=True):
output = output[:a] + "running on " + h + output[e+1:]
if shall_escape:
+ http_url = r"(http[s]?://[A-Za-z0-9\-._~:/?#\[\]@!$&'()*+,;=%]+)"
# (?:<A HREF="), (?: target="_blank">)? and endswith(" </A>") is a special
# handling for the HTML code produced by check_http when "clickable URL" option is active.
- output = re.sub("(?:<A HREF=")?(http[s]?://[^\"'>\\s,]+)(?: target="_blank">)?",
+ output = re.sub("(?:<A HREF=")?" + http_url + "(?: target="_blank">)?",
lambda p: '<a href="%s"><img class=pluginurl align=absmiddle title="%s" src="images/pluginurl.png"></a>' %
(p.group(1).replace('"', ''), p.group(1).replace('"', '')), output)
Module: check_mk
Branch: master
Commit: 2f030efddbb83771b52d706eebb3c817bac2df47
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=2f030efddbb837…
Author: Moritz Kiemer <mo(a)mathias-kettner.de>
Date: Fri Jul 6 11:27:27 2018 +0200
check_api(_utils).py: be more consistent
All three globals _hostname, _check_type and _service_description
are initialised with None. If requested before set properly,
a RuntimeError is raised.
testlib is adjusted accordingly.
Change-Id: I6b522c4a2ac22182138fe5bc8e99187225c07014
---
cmk_base/check_api_utils.py | 21 ++++++++++++++-------
cmk_base/config.py | 2 +-
tests/testlib/__init__.py | 45 +++++++++++++++++++++++++++++++++++----------
3 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/cmk_base/check_api_utils.py b/cmk_base/check_api_utils.py
index fbd3fde..e7b09e2 100644
--- a/cmk_base/check_api_utils.py
+++ b/cmk_base/check_api_utils.py
@@ -55,7 +55,9 @@ HOST_ONLY = "host_only" # Check is only executed for real SNMP host
# Is set before check/discovery function execution
-_hostname = "unknown" # Host currently being checked
+_hostname = None # Host currently being checked
+_check_type = None
+_service_description = None
def set_hostname(hostname):
@@ -63,16 +65,18 @@ def set_hostname(hostname):
_hostname = hostname
+def reset_hostname():
+ global _hostname
+ _hostname = None
+
+
def host_name():
"""Returns the name of the host currently being checked or discovered."""
+ if _hostname is None:
+ raise RuntimeError("host name has not been set")
return _hostname
-# Is set before check execution
-_check_type = None
-_service_description = None
-
-
def set_service(check_type, service_description):
global _check_type, _service_description
_check_type = check_type
@@ -81,10 +85,13 @@ def set_service(check_type, service_description):
def check_type():
"""Returns the name of the check type currently being checked."""
+ if _check_type is None:
+ raise RuntimeError("check type has not been set")
return _check_type
-# TODO: Is this really needed? Could not find a call site.
def service_description():
"""Returns the name of the service currently being checked."""
+ if _service_description is None:
+ raise RuntimeError("service description has not been set")
return _service_description
diff --git a/cmk_base/config.py b/cmk_base/config.py
index e14688f..c356118 100644
--- a/cmk_base/config.py
+++ b/cmk_base/config.py
@@ -2807,4 +2807,4 @@ def filter_by_management_board(hostname, found_check_plugin_names,
return final_collection
-cmk_base.cleanup.register_cleanup(lambda: check_api_utils.set_hostname("unknown"))
+cmk_base.cleanup.register_cleanup(check_api_utils.reset_hostname)
diff --git a/tests/testlib/__init__.py b/tests/testlib/__init__.py
index 1294525..dbb4262 100644
--- a/tests/testlib/__init__.py
+++ b/tests/testlib/__init__.py
@@ -16,6 +16,7 @@ import sys
import shutil
import lockfile
import ast
+import abc
from urlparse import urlparse
from bs4 import BeautifulSoup
@@ -1793,14 +1794,34 @@ class MissingCheckInfoError(KeyError):
pass
-class Check(object):
+class BaseCheck(object):
+ """Abstract base class for Check and ActiveCheck"""
+ __metaclass__ = abc.ABCMeta
def __init__(self, name):
- import cmk_base.config as config
+ import cmk_base.check_api_utils
+ self.set_hostname = cmk_base.check_api_utils.set_hostname
+ self.set_service = cmk_base.check_api_utils.set_service
self.name = name
- if name not in config.check_info:
- raise MissingCheckInfoError(name)
- self.info = config.check_info[name]
- self.context = config._check_contexts[name]
+
+ def set_check_api_utils_globals(self, item=None, set_service=False):
+ description = None
+ if set_service:
+ description = self.info["service_description"]
+ if item is not None:
+ assert "%s" in description
+ description = description % item
+ self.set_service(self.name, description)
+ self.set_hostname('non-existent-testhost')
+
+
+class Check(BaseCheck):
+ def __init__(self, name):
+ import cmk_base.config as config
+ super(Check, self).__init__(name)
+ if self.name not in config.check_info:
+ raise MissingCheckInfoError(self.name)
+ self.info = config.check_info[self.name]
+ self.context = config._check_contexts[self.name]
def default_parameters(self):
import cmk_base.config as config
@@ -1812,6 +1833,7 @@ class Check(object):
if not parse_func:
raise MissingCheckInfoError("Check '%s' " % self.name +
"has no parse function defined")
+ self.set_check_api_utils_globals()
return parse_func(info)
def run_discovery(self, info):
@@ -1819,6 +1841,7 @@ class Check(object):
if not disco_func:
raise MissingCheckInfoError("Check '%s' " % self.name +
"has no discovery function defined")
+ self.set_check_api_utils_globals()
# TODO: use standard sanitizing code
return disco_func(info)
@@ -1827,6 +1850,7 @@ class Check(object):
if not check_func:
raise MissingCheckInfoError("Check '%s' " % self.name +
"has no check function defined")
+ self.set_check_api_utils_globals(item, set_service=True)
# TODO: use standard sanitizing code
return check_func(item, params, info)
@@ -1853,14 +1877,15 @@ class Check(object):
# return self.info["check_function"](item, params, info)
-class ActiveCheck(object):
+class ActiveCheck(BaseCheck):
def __init__(self, name):
import cmk_base.config as config
- self.name = name
- assert name.startswith('check_'), 'Specify the full name of the active check, e.g. check_http'
- self.info = config.active_check_info[name[len('check_'):]]
+ super(ActiveCheck, self).__init__(name)
+ assert self.name.startswith('check_'), 'Specify the full name of the active check, e.g. check_http'
+ self.info = config.active_check_info[self.name[len('check_'):]]
def run_argument_function(self, params):
+ self.set_check_api_utils_globals()
return self.info['argument_function'](params)
def run_service_description(self, params):