Module: check_mk
Branch: master
Commit: 8a63e5d1a273fdc8755f2abf4d07018f65c78d75
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=8a63e5d1a273fd…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Fri Nov 25 16:47:27 2016 +0100
4073 FIX Cleaned up cluster host handling in HW/SW inventory
Previously the manual inventory calls on the command line were
not possible on the command line, but when adding a "Check_MK inventory"
service to a cluster host, the inventory was tried and did work in case
the cluster has a host address configured.
These differences have now been cleaned up and changed a bit.
You can perform the inventory now on command line and add a "Check_MK
inventory"
service to the hosts, but the regular inventory with all the plugins is not
performed against cluster hosts. Instead the clusters only get the following
inventory nodes added:
<ul>
<li>Software > Applications > Check_MK > Cluster > Cluster host:
Yes</li>
<li>Software > Applications > Check_MK > Cluster > Nodes: List of
nodes</li>
</ul>
The first node is also added to all other hosts but set to <i>No</i>. You
can then use a filter to include or exclude the hosts of your choice from
your inventory list views.
---
.werks/4073 | 28 ++++++++++++++++++++++
ChangeLog | 1 +
modules/check_mk.py | 2 +-
modules/inventory.py | 50 ++++++++++++++++++++++++++++------------
web/plugins/views/inventory.py | 24 +++++++++++++++----
web/plugins/visuals/inventory.py | 28 ++++++++++++++++++++++
6 files changed, 113 insertions(+), 20 deletions(-)
diff --git a/.werks/4073 b/.werks/4073
new file mode 100644
index 0000000..576a4f1
--- /dev/null
+++ b/.werks/4073
@@ -0,0 +1,28 @@
+Title: Cleaned up cluster host handling in HW/SW inventory
+Level: 1
+Component: inv
+Compatible: compat
+Version: 1.4.0i3
+Date: 1480088542
+Class: fix
+
+Previously the manual inventory calls on the command line were
+not possible on the command line, but when adding a "Check_MK inventory"
+service to a cluster host, the inventory was tried and did work in case
+the cluster has a host address configured.
+
+These differences have now been cleaned up and changed a bit.
+
+You can perform the inventory now on command line and add a "Check_MK
inventory"
+service to the hosts, but the regular inventory with all the plugins is not
+performed against cluster hosts. Instead the clusters only get the following
+inventory nodes added:
+
+<ul>
+<li>Software > Applications > Check_MK > Cluster > Cluster host:
Yes</li>
+<li>Software > Applications > Check_MK > Cluster > Nodes: List of
nodes</li>
+</ul>
+
+The first node is also added to all other hosts but set to <i>No</i>. You
+can then use a filter to include or exclude the hosts of your choice from
+your inventory list views.
diff --git a/ChangeLog b/ChangeLog
index b93da3e..9373d7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -69,6 +69,7 @@
* 4067 FIX: Fixed broken inventory history view in current master...
* 3917 FIX: Fixed broken dicttable rendering
* 3918 FIX: Inventory history: Fixed possible exception when renedering history
tables...
+ * 4073 FIX: Cleaned up cluster host handling in HW/SW inventory...
1.4.0i2:
diff --git a/modules/check_mk.py b/modules/check_mk.py
index d2bc850..2f689cf 100755
--- a/modules/check_mk.py
+++ b/modules/check_mk.py
@@ -4697,7 +4697,7 @@ try:
elif o in [ '-i', '--inventory' ]:
load_module("inventory")
if args:
- hostnames = parse_hostname_list(args, with_clusters = False)
+ hostnames = parse_hostname_list(args, with_clusters=True)
else:
hostnames = None
do_inv(hostnames)
diff --git a/modules/inventory.py b/modules/inventory.py
index 62aa5bb..46854ab 100644
--- a/modules/inventory.py
+++ b/modules/inventory.py
@@ -172,7 +172,7 @@ def do_inv(hostnames):
# No hosts specified: do all hosts and force caching
if hostnames == None:
- hostnames = all_active_realhosts()
+ hostnames = all_active_hosts()
set_use_cachefile()
errors = []
@@ -246,15 +246,44 @@ def count_nodes(tree):
else:
return 1
+
def do_inv_for(hostname):
+ global g_inv_tree
+ g_inv_tree = {}
+
+ node = inv_tree("software.applications.check_mk.cluster.")
+
+ if is_cluster(hostname):
+ node["is_cluster"] = True
+ do_inv_for_cluster(hostname)
+ else:
+ node["is_cluster"] = False
+ do_inv_for_realhost(hostname)
+
+ # Remove empty paths
+ inv_cleanup_tree(g_inv_tree)
+ old_timestamp = save_inv_tree(hostname)
+
+ console.verbose("..%s%s%d%s entries" % (tty.bold, tty.yellow,
count_nodes(g_inv_tree), tty.normal))
+
+ run_inv_export_hooks(hostname, g_inv_tree)
+ return g_inv_tree, old_timestamp
+
+
+def do_inv_for_cluster(hostname):
+ inv_node = inv_tree_list("software.applications.check_mk.cluster.nodes:")
+ for node_name in nodes_of(hostname):
+ inv_node.append({
+ "name" : node_name,
+ })
+
+
+def do_inv_for_realhost(hostname):
try:
ipaddress = lookup_ip_address(hostname)
except:
raise MKGeneralException("Cannot resolve hostname '%s'." %
hostname)
- global g_inv_tree
- g_inv_tree = {}
-
# If this is an SNMP host then determine the SNMP sections
# that this device supports.
if is_snmp_host(hostname):
@@ -294,15 +323,6 @@ def do_inv_for(hostname):
extend_tree_with_check_mk_inventory_info(hostname)
- # Remove empty paths
- inv_cleanup_tree(g_inv_tree)
- old_timestamp = save_inv_tree(hostname)
-
- console.verbose("..%s%s%d%s entries" % (tty.bold, tty.yellow,
count_nodes(g_inv_tree), tty.normal))
-
- run_inv_export_hooks(hostname, g_inv_tree)
- return g_inv_tree, old_timestamp
-
def extend_tree_with_check_mk_inventory_info(hostname):
persisted_file = cmk.paths.omd_root + "/var/check_mk/persisted/%s" %
hostname
@@ -318,11 +338,11 @@ def extend_tree_with_check_mk_inventory_info(hostname):
except Exception, e:
raise MKGeneralException(_("Cannot parse persisted file of %s: %s") %
(hostname, e))
- add_check_mk_inventory_info_to_tree(persisted_data)
+ add_check_mk_inventory_info_to_tree(hostname, persisted_data)
console.verbose(tty.green + tty.bold + "check_mk_sections" + " "
+ tty.normal)
-def add_check_mk_inventory_info_to_tree(persisted_data):
+def add_check_mk_inventory_info_to_tree(hostname, persisted_data):
node = inv_tree_list("software.applications.check_mk.inventory.sections:")
section_ages = []
for section, sectiondata in persisted_data:
diff --git a/web/plugins/views/inventory.py b/web/plugins/views/inventory.py
index e953bed..2925906 100644
--- a/web/plugins/views/inventory.py
+++ b/web/plugins/views/inventory.py
@@ -30,8 +30,6 @@ import cmk.defines as defines
def paint_host_inventory(row, invpath):
invdata = inventory.get(row.get("host_inventory"), invpath)
- if not invdata:
- return "", "" # _("No inventory data available")
hint = inv_display_hint(invpath)
if "paint_function" in hint:
@@ -89,6 +87,9 @@ def declare_inv_column(invpath, datatype, title, short = None):
# Declare filter. Sync this with declare_invtable_columns()
if datatype == "str":
visuals.declare_filter(800, visuals.FilterInvText(name, invpath, title))
+ # TODO:
+ #elif datatype == "bool":
+ # visuals.declare_filter(800, visuals.FilterInvBool(name, invpath, title))
else:
filter_info = inv_filter_info.get(datatype, {})
visuals.declare_filter(800, visuals.FilterInvFloat(name, invpath, title,
@@ -392,7 +393,7 @@ multisite_painters["inventory_tree"] = {
def inv_paint_hz(hz):
if hz == None:
- return "", _("unknown")
+ return "", ""
if hz < 10:
return "number", "%.2f" % hz
@@ -409,7 +410,7 @@ def inv_paint_hz(hz):
def inv_paint_bytes(b):
if b == None:
- return "", _("unknown")
+ return "", ""
elif b == 0:
return "number", "0"
@@ -547,6 +548,13 @@ def inv_paint_age(age):
else:
return "", ""
+
+def inv_paint_bool(value):
+ if value == None:
+ return "", ""
+ return "", (_("Yes") if value else _("No"))
+
+
def inv_paint_timestamp_as_age(timestamp):
age = time.time() - timestamp
return inv_paint_age(age)
@@ -717,6 +725,12 @@ inventory_displayhints.update({
".software.applications." : { "title" :
_("Applications"), },
".software.applications.check_mk." : {
"title" : _("Check_MK"), },
+ ".software.applications.check_mk.cluster.is_cluster" : {
"title" : _("Cluster host"),
+ "short" :
_("Cluster"),
+ "paint" :
"bool",
+ },
+ ".software.applications.check_mk.cluster.nodes:" : {
"title" : _("Nodes"),
+ "render" :
render_inv_dicttable, },
".software.applications.check_mk.inventory." : {
"title" : _("Hardware/Software Inventory"), },
".software.applications.check_mk.inventory.oldest_section" : {
"title" : _("Oldest agent section"), "paint" :
"timestamp_as_age" },
".software.applications.check_mk.inventory.sections:" : {
"title" : _("Agent sections"),
@@ -951,6 +965,8 @@ def declare_invtable_columns(infoname, invpath, topic):
if not filter_class:
if paint_name == "str":
filter_class = visuals.FilterInvtableText
+ elif paint_name == "bool":
+ filter_class = visuals.FilterInvtableBool
else:
filter_class = visuals.FilterInvtableIDRange
diff --git a/web/plugins/visuals/inventory.py b/web/plugins/visuals/inventory.py
index c449028..af54a35 100644
--- a/web/plugins/visuals/inventory.py
+++ b/web/plugins/visuals/inventory.py
@@ -312,6 +312,7 @@ class FilterInvtableVersion(Filter):
return new_rows
+
class FilterInvText(Filter):
def __init__(self, name, invpath, title):
self._invpath = invpath
@@ -400,6 +401,33 @@ class FilterInvFloat(Filter):
newrows.append(row)
return newrows
+
+class FilterInvBool(FilterTristate):
+ def __init__(self, name, invpath, title):
+ self._invpath = invpath
+ FilterTristate.__init__(self, name, title, "host", name)
+
+ def need_inventory(self):
+ return True
+
+ def filter(self, infoname):
+ return "" # No Livestatus filtering right now
+
+ def filter_table(self, rows):
+ tri = self.tristate_value()
+ if tri == -1:
+ return rows
+ else:
+ wanted_value = tri == 1
+
+ newrows = []
+ for row in rows:
+ invdata = inventory.get(row["host_inventory"], self._invpath)
+ if wanted_value == invdata:
+ newrows.append(row)
+ return newrows
+
+
class FilterHasInventory(FilterTristate):
def __init__(self):
FilterTristate.__init__(self, "has_inv", _("Has Inventory
Data"), "host", "host_inventory")