Module: check_mk
Branch: master
Commit: 4f76b5a13b3ba568ae93e28792f7625f4945b76b
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=4f76b5a13b3ba5…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Thu Jul 12 09:10:23 2018 +0200
Abstracted plugin registry
Change-Id: I132a1daab1484cfc5e67b85122d2f89d1a9d571b
---
cmk/gui/plugin_registry.py | 89 +++++++++++++++++++++++++++++++++++++
cmk/gui/plugins/sidebar/__init__.py | 26 +++++++++++
cmk/gui/sidebar.py | 59 +++++++++---------------
3 files changed, 136 insertions(+), 38 deletions(-)
diff --git a/cmk/gui/plugin_registry.py b/cmk/gui/plugin_registry.py
new file mode 100644
index 0000000..068abc7
--- /dev/null
+++ b/cmk/gui/plugin_registry.py
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+# -*- encoding: utf-8; py-indent-offset: 4 -*-
+# +------------------------------------------------------------------+
+# | ____ _ _ __ __ _ __ |
+# | / ___| |__ ___ ___| | __ | \/ | |/ / |
+# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+# | | |___| | | | __/ (__| < | | | | . \ |
+# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+# | |
+# | Copyright Mathias Kettner 2014 mk(a)mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation in version 2. check_mk is distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
+# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public License for more de-
+# tails. You should have received a copy of the GNU General Public
+# License along with GNU Make; see the file COPYING. If not, write
+# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
+import abc
+
+class Registry(object):
+ """The management object for all available plugins of a component.
+
+ The snapins are loaded by importing cmk.gui.plugins.[component]. These plugins
+ contain subclasses of the cmk.gui.plugins.PluginBase (e.g. SidebarSnpain) class.
+ Registry.load_plugins() will register all snapins with this management
+ object and make them available for use.
+ """
+ __metaclass__ = abc.ABCMeta
+
+ def __init__(self):
+ super(Registry, self).__init__()
+ self._entries = {}
+
+
+ # TODO: Make staticmethod (But abc.abstractstaticmethod not available. How to make this possible?)
+ @abc.abstractmethod
+ def plugin_base_class(self):
+ raise NotImplementedError()
+
+
+ def load_plugins(self):
+ self._entries.clear()
+
+ def _all_subclasses_of(base_class):
+ l = []
+ for plugin_class in base_class.__subclasses__(): # pylint: disable=no-member
+ l += _all_subclasses_of(plugin_class)
+ l.append(plugin_class)
+ return l
+
+ for plugin_class in _all_subclasses_of(self.plugin_base_class()):
+ if plugin_class.__subclasses__(): # pylint: disable=no-member
+ continue # Only use leaf classes
+
+ self.register(plugin_class)
+
+
+ @abc.abstractmethod
+ def register(self, plugin_class):
+ raise NotImplementedError()
+
+
+ def __contains__(self, text):
+ return text in self._entries
+
+
+ def __delitem__(self, key):
+ del self._entries[key]
+
+
+ def items(self):
+ return self._entries.items()
+
+
+ def keys(self):
+ return self._entries.keys()
+
+
+ def get(self, key, deflt=None):
+ return self._entries.get(key, deflt)
diff --git a/cmk/gui/plugins/sidebar/__init__.py b/cmk/gui/plugins/sidebar/__init__.py
index 081c702..7054431 100644
--- a/cmk/gui/plugins/sidebar/__init__.py
+++ b/cmk/gui/plugins/sidebar/__init__.py
@@ -1,3 +1,29 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8; py-indent-offset: 4 -*-
+# +------------------------------------------------------------------+
+# | ____ _ _ __ __ _ __ |
+# | / ___| |__ ___ ___| | __ | \/ | |/ / |
+# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+# | | |___| | | | __/ (__| < | | | | . \ |
+# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+# | |
+# | Copyright Mathias Kettner 2014 mk(a)mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation in version 2. check_mk is distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
+# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public License for more de-
+# tails. You should have received a copy of the GNU General Public
+# License along with GNU Make; see the file COPYING. If not, write
+# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
import os
import glob
diff --git a/cmk/gui/sidebar.py b/cmk/gui/sidebar.py
index 1db6a2f..d35e11a 100644
--- a/cmk/gui/sidebar.py
+++ b/cmk/gui/sidebar.py
@@ -49,6 +49,7 @@ import cmk.gui.notify as notify
import cmk.gui.werks as werks
import cmk.gui.sites as sites
import cmk.gui.modules as modules
+import cmk.gui.plugin_registry
import cmk.gui.plugins.sidebar
import cmk.gui.plugins.sidebar.quicksearch
from cmk.gui.exceptions import MKGeneralException, MKUserError, MKException
@@ -123,7 +124,7 @@ def load_plugins(force):
# TODO: Deprecate this one day.
def transform_old_dict_based_snapins():
for snapin_id, snapin in sidebar_snapins.items():
- snapin_registry.register_snapin(GenericSnapin(snapin_id, snapin))
+ snapin_registry.register(GenericSnapin(snapin_id, snapin))
# TODO: Deprecate this one day.
@@ -565,37 +566,31 @@ def ajax_switch_site():
#.
-# .--Snapin API----------------------------------------------------------.
-# | ____ _ _ ____ ___ |
-# | / ___| _ __ __ _ _ __ (_)_ __ / \ | _ \_ _| |
-# | \___ \| '_ \ / _` | '_ \| | '_ \ / _ \ | |_) | | |
-# | ___) | | | | (_| | |_) | | | | | / ___ \| __/| | |
-# | |____/|_| |_|\__,_| .__/|_|_| |_| /_/ \_\_| |___| |
-# | |_| |
-# +----------------------------------------------------------------------+
-# | The new snapin API allows encapsulating the whole functionality of a |
-# | snapin in a single object. This includes page handlers and so on. |
-# | All new snapins need to be realized as child of SidebarSnapin() and |
-# | use the register_snapin() function to register with the sidebar. |
+# .--Plugins-------------------------------------------------------------.
+# | ____ _ _ |
+# | | _ \| |_ _ __ _(_)_ __ ___ |
+# | | |_) | | | | |/ _` | | '_ \/ __| |
+# | | __/| | |_| | (_| | | | | \__ \ |
+# | |_| |_|\__,_|\__, |_|_| |_|___/ |
+# | |___/ |
# '----------------------------------------------------------------------'
-# Load all plugins. The snapins will then register on their own by subclassing SidebarSnapin
-import cmk.gui.plugins.sidebar
-
-class SnapinRegistry(object):
- def __init__(self):
- super(SnapinRegistry, self).__init__()
- self._snapins = {}
+class SnapinRegistry(cmk.gui.plugin_registry.Registry):
+ """The management object for all available plugins.
- def load_snapins(self):
- for snapin_class in cmk.gui.plugins.sidebar.SidebarSnapin.__subclasses__(): # pylint: disable=no-member
- self.register_snapin(snapin_class())
+ The snapins are loaded by importing cmk.gui.plugins.sidebar. These plugins
+ contain subclasses of the cmk.gui.plugins.SidebarSnapin class.
+ SnapinRegistry.load_plugins() will register all snapins with this management
+ object and make them available for use.
+ """
+ def plugin_base_class(self):
+ return cmk.gui.plugins.sidebar.SidebarSnapin
- def register_snapin(self, snapin):
+ def register(self, snapin):
snapin_id = snapin.type_name()
- self._snapins[snapin_id] = snapin
+ self._entries[snapin_id] = snapin
config.declare_permission("sidesnap.%s" % snapin_id,
snapin.title(),
@@ -605,20 +600,8 @@ class SnapinRegistry(object):
modules.register_handlers(snapin.page_handlers())
- def __contains__(self, text):
- return text in self._snapins
-
-
- def items(self):
- return self._snapins.items()
-
-
- def get(self, key, deflt=None):
- return self._snapins.get(key, deflt)
-
-
snapin_registry = SnapinRegistry()
-snapin_registry.load_snapins()
+snapin_registry.load_plugins()
class GenericSnapin(cmk.gui.plugins.sidebar.SidebarSnapin):
Module: check_mk
Branch: master
Commit: b16e33bf8f6c027211ed7393990df39e558c3296
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=b16e33bf8f6c02…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Thu Jul 12 09:10:23 2018 +0200
Moved helper function to fetch groups from livestatus to more generic place
Change-Id: I85f6bb7a90adea0e471f4f6b4b69d5f00e289574
---
cmk/gui/availability.py | 2 +-
cmk/gui/plugins/sidebar/shipped.py | 6 +-----
cmk/gui/sites.py | 10 ++++++++++
web/plugins/visuals/filters.py | 12 +++---------
4 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/cmk/gui/availability.py b/cmk/gui/availability.py
index c08ceef..da661d5 100644
--- a/cmk/gui/availability.py
+++ b/cmk/gui/availability.py
@@ -1050,7 +1050,7 @@ def compute_availability_groups(what, av_data, avoptions):
# 2. Compute names for the groups and sort according to these names
if grouping != "host":
- group_titles = dict(visuals.all_groups(grouping[:-7]))
+ group_titles = dict(sites.all_groups(grouping[:-7]))
titled_groups = []
for group_id in all_group_ids:
diff --git a/cmk/gui/plugins/sidebar/shipped.py b/cmk/gui/plugins/sidebar/shipped.py
index bbc391b..01c360f 100644
--- a/cmk/gui/plugins/sidebar/shipped.py
+++ b/cmk/gui/plugins/sidebar/shipped.py
@@ -207,12 +207,8 @@ sidebar_snapins["dashboards"] = {
# '----------------------------------------------------------------------'
def render_groups(what):
- data = sites.live().query("GET %sgroups\nColumns: name alias\n" % what)
- name_to_alias = dict(data)
- groups = [(name_to_alias[name].lower(), name_to_alias[name], name) for name in name_to_alias.keys()]
- groups.sort() # sort by Alias in lowercase
html.open_ul()
- for alias_lower, alias, name in groups:
+ for name, alias in sites.all_groups(what):
url = "view.py?view_name=%sgroup&%sgroup=%s" % (what, what, html.urlencode(name))
bulletlink(alias or name, url)
html.close_ul()
diff --git a/cmk/gui/sites.py b/cmk/gui/sites.py
index 008c8cd..e588414 100644
--- a/cmk/gui/sites.py
+++ b/cmk/gui/sites.py
@@ -102,6 +102,16 @@ def cores_by_site():
return cores
+
+def all_groups(what):
+ # type: (str) -> List[Tuple[str, str]]
+ """Returns a list of host/service/contact groups (pairs of name/alias)
+
+ Groups are collected via livestatus from all sites. In case no alias is defined
+ the name is used as second element. The list is sorted by lower case alias in the first place."""
+ groups = live().query("GET %sgroups\nCache: reload\nColumns: name alias\n" % what)
+ return sorted([ (name, alias or name) for name, alias in groups ], key=lambda e: e[1].lower())
+
#.
# .--Internal------------------------------------------------------------.
# | ___ _ _ |
diff --git a/web/plugins/visuals/filters.py b/web/plugins/visuals/filters.py
index 9d44ec1..44ef7a8 100644
--- a/web/plugins/visuals/filters.py
+++ b/web/plugins/visuals/filters.py
@@ -256,12 +256,6 @@ class FilterAddressFamilies(Filter):
declare_filter(103, FilterAddressFamilies())
-# Helper that retrieves the list of host/service/contactgroups via Livestatus
-# use alias by default but fallback to name if no alias defined
-def all_groups(what):
- groups = dict(sites.live().query("GET %sgroups\nCache: reload\nColumns: name alias\n" % what))
- return [ (name, groups[name] or name) for name in groups.keys() ]
-
class FilterMultigroup(Filter):
def __init__(self, what, title, negateable=False):
self.htmlvar = what + "groups"
@@ -281,7 +275,7 @@ class FilterMultigroup(Filter):
def valuespec(self):
return DualListChoice(
- choices = all_groups(self.what),
+ choices = sites.all_groups(self.what),
rows=3 if self.negateable else 4,
enlarge_active=True
)
@@ -340,7 +334,7 @@ class FilterGroupCombo(Filter):
return True
def display(self):
- choices = all_groups(self.what.split("_")[-1])
+ choices = sites.all_groups(self.what.split("_")[-1])
if not self.enforce:
choices = [("", "")] + choices
html.dropdown(self.htmlvars[0], choices, sorted=True)
@@ -418,7 +412,7 @@ class FilterGroupSelection(Filter):
self.what = infoname
def display(self):
- choices = all_groups(self.what[:-5]) # chop off "group", leaves host or service
+ choices = sites.all_groups(self.what[:-5]) # chop off "group", leaves host or service
html.dropdown(self.htmlvars[0], choices, sorted=True)
def current_value(self):