Module: check_mk
Branch: master
Commit: e64f82c1e19d15379189671299b12be77af877f5
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=e64f82c1e19d15…
Author: Florian Heigl <fh(a)mathias-kettner.de>
Date: Mon Jul 18 15:49:13 2011 +0200
add bug entry for IPMI agent issue
---
.bugs/311 | 21 ++++++++++++---------
1 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/.bugs/311 b/.bugs/311
index 9c6b387..e7faede 100644
--- a/.bugs/311
+++ b/.bugs/311
@@ -1,11 +1,14 @@
-Title: manual SNMP checks without scan function not visible in WATO
-Component: wato
-Benefit: 1
+Title: IPMI cache initialization race condition
+Component: checks
+Benefit: 6
State: open
-Cost: 3
-Date: 2011-06-29 12:56:31
-Class: bug
+Cost: 4
+Date: 2011-07-18 15:42:34
+Class: nastiness
-When showing the services table of a host in WATO without
-Full Scan, then manually configured SNMP services with
-out a scan function will not be displayed (e.g. snmp_uptime)
+there is a very nasty issue with the IPMI agent code - we
+kills the initial build of the SDR cache there will be no point in re-doing the scan and IPMI will be disabled forever.
+The problem is that many IPMI modules are not able to handle concurrent requests. If building the SDR cache takes longer than 55+ seconds then we gh chance that a new check_mk_agent call happens via inetd. This second call will cause an IPMI issue which will cause the SDR cache scan to fail.
+From that time on, IPMI will be disabled / broken.
+
+Very ugly issue, maybe xinetd can disable multiple runs of the same service (but this would mean staleness issues will stop the agent forever)
Module: check_mk
Branch: master
Commit: a6e61fe1873cd691719f23b2251a62ae9c57ac62
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=a6e61fe1873cd6…
Author: Florian Heigl <fh(a)mathias-kettner.de>
Date: Fri Jul 22 09:50:48 2011 +0200
New bug entry
---
.bugs/313 | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/.bugs/313 b/.bugs/313
new file mode 100644
index 0000000..ebc3af1
--- /dev/null
+++ b/.bugs/313
@@ -0,0 +1,18 @@
+Title: Change agent NTP check to skip reverse resolution of NTP clocks
+Component: checks
+Benefit: 5
+State: open
+Cost: 3
+Date: 2011-07-21 10:54:02
+Class: feature
+
+The ntpq -p call will do one reverse lookup per NTP clock.
+This is slowing down check_mk_agent by a moment for systems
+with few clocks and fast DNS servers, or not slowing down at all when
+just using files as hosts source.
+BUT if there is any rDNS issue (think windows admins doing the DNS) or if theres
+notable latency to the DNS servers (i.e. when using "pool pool.ntp.org") then this
+will slow down the agent run by many seconds.
+
+We should discuss switching to ntpq -n -p to disable hostname lookups.
+(Suggestion from "Sonic" on the mailing list)
Module: check_mk
Branch: master
Commit: 6364f282fefe900202b28a1a8d4b8db1d687d609
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=6364f282fefe90…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Fri Jul 15 15:40:06 2011 +0200
WATO: support original folder when doing imports
---
web/htdocs/wato.py | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 140 insertions(+), 3 deletions(-)
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index faf7891..5c446b0 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -475,14 +475,17 @@ def check_wato_filename(htmlvarname, name, what):
if not re.match("^[-a-z0-9A-Z_]*$", name):
raise MKUserError(htmlvarname, _("Invalid %s name. Only the characters a-z, A-Z, 0-9, _ and - are allowed.") % what)
-def create_wato_filename(title, what):
+def create_wato_filename(title, what, in_folder = None):
+ if in_folder == None:
+ in_folder = g_folder
+
basename = convert_title_to_filename(title)
c = 1
name = basename
while True:
- if what == "folder" and name not in g_folder[".folders"]:
+ if what == "folder" and name not in in_folder[".folders"]:
break
- elif what == "file" and name + ".mk" not in g_folder[".files"]:
+ elif what == "file" and name + ".mk" not in in_folder[".files"]:
break
c += 1
name = "%s-%d" % (basename, c)
@@ -573,6 +576,10 @@ def mode_file(phase):
num_moved = move_hosts_to(selected_hosts, target_file)
return None, _("Successfully moved %d hosts to %s") % (num_moved, target_file)
+ # Move to target folder (from import)
+ elif html.var("_bulk_movetotarget"):
+ return move_to_imported_folders(selected_hosts)
+
elif html.var("_bulk_edit"):
return "bulkedit"
@@ -615,6 +622,7 @@ def mode_file(phase):
search_text = html.var("search")
selected_hosts = get_hostnames_from_checkboxes()
+ at_least_one_imported = False
for hostname in hostnames:
if search_text and (search_text.lower() not in hostname.lower()):
continue
@@ -667,6 +675,13 @@ def mode_file(phase):
html.write("</td>")
html.write("</tr>\n")
+ # Remember if that host has a target folder (i.e. was imported with
+ # a folder information but not yet moved to that folder). If at least
+ # one host has a target folder, then we show an additional bulk action.
+ if effective.get("imported_folder"):
+ at_least_one_imported = True
+
+
# bulk actions
html.write('<tr class="data %s0"><td class=select>' % odd)
html.jsbutton('_markall', 'X', 'javascript:wato_check_all(\'wato_select\');')
@@ -677,6 +692,8 @@ def mode_file(phase):
html.button("_bulk_cleanup", _("Cleanup"))
html.button("_bulk_inventory", _("Inventory"))
host_move_combo(None)
+ if at_least_one_imported:
+ html.button("_bulk_movetotarget", _("Move to Target Folders"))
html.write("</td></tr>\n")
html.write("</table>\n")
@@ -980,6 +997,107 @@ def search_hosts_in_file(the_folder, the_file, crit):
return len(found)
+def move_to_imported_folders(hosts):
+ c = wato_confirm(
+ _("Confirm moving hosts"),
+ _('You are going to move the selected hosts to folders '
+ 'representing their original folder location in the system '
+ 'you did the import from. Please make sure that you have '
+ 'done an <b>inventory</b> before moving the hosts.'))
+ if c == False: # not yet confirmed
+ return ""
+ elif not c:
+ return None # browser reload
+
+ # Create groups of hosts with the same target folder
+ targets = {}
+ for hostname in hosts:
+ host = g_hosts[hostname]
+ effective = effective_attributes(host, g_file)
+ imported_folder = effective.get('imported_folder')
+ if imported_folder == None:
+ continue
+ targets.setdefault(imported_folder, []).append(hostname)
+
+ # Remove target folder information, now that the hosts are
+ # at their target position.
+ del host['imported_folder']
+
+ # Now handle each target folder
+ num_moved = 0
+ for imported_folder, hosts in targets.items():
+ # Next problem: The folder path in imported_folder refers
+ # to the Alias of the folders, not to the internal file
+ # name. And we need to create folders not yet existing.
+ target_file = create_target_file_from_aliaspath(imported_folder)
+ num_moved += move_hosts_to(hosts, target_file)
+
+ save_folder_config()
+ html.reload_sidebar() # refresh WATO snapin
+ return None, _("Successfully moved %d hosts to their original folder destinations.") % num_moved
+
+
+def create_target_file_from_aliaspath(aliaspath):
+ # The alias path is a '/' separated path of folder titles.
+ # An empty path is interpreted as root path. The actual file
+ # name is the host list with the name "Hosts".
+ if aliaspath == "":
+ folder = g_root_folder
+ else:
+ parts = aliaspath.split("/")
+ folder = g_root_folder
+ while len(parts) > 0:
+ # Look in current folder for subfolder with the target name
+ for name, f in folder.get(".folders", {}).items():
+ if f["title"] == parts[0]:
+ folder = f
+ parts = parts[1:]
+ break
+ else: # not found. Create this folder
+ name = create_wato_filename(parts[0], "folder", folder)
+ new_folder = {
+ ".name" : name,
+ ".path" : folder[".path"] + (name,),
+ "title" : parts[0],
+ "roles" : folder["roles"],
+ "attributes" : {},
+ ".folders" : {},
+ ".files" : {},
+ }
+ folder[".folders"][name] = new_folder
+ folder = new_folder
+ parts = parts[1:]
+
+ # Now folder points to the folder the host needs to be created
+ # in. In that folder we put the host into the host list "hosts.mk".
+ if "hosts" not in folder[".files"]:
+ new_file = {
+ ".name" : "hosts.mk",
+ ".path" : folder[".path"] + ("hosts.mk",),
+ "title" : _("Hosts"),
+ "roles" : folder["roles"],
+ "attributes" : {},
+ "num_hosts" : 0,
+ }
+ folder[".files"]["hosts.mk"] = new_file
+ g_files[new_file[".path"]] = new_file
+
+ the_file = folder[".files"]["hosts.mk"]
+ return "/" + "/".join(the_file[".path"])
+
+
+
+
+
+
+
+
+
+
+
+
+
+
# +----------------------------------------------------------------------+
# | ____ _ _ ___ _ |
# | | __ ) _ _| | | __ |_ _|_ ____ _____ _ __ | |_ ___ _ __ _ _ |
@@ -2365,6 +2483,25 @@ class TextAttribute(Attribute):
value = ""
return crit.lower() in value.lower()
+# A simple text attribute that is not editable by the user.
+# It can be used to store context information from other
+# systems (e.g. during an import of a host database from
+# another system).
+class FixedTextAttribute(TextAttribute):
+ def __init__(self, name, title, help = None):
+ TextAttribute.__init__(self, name, title, help, None)
+ self._mandatory = False
+
+ def render_input(self, value):
+ if value != None:
+ html.hidden_field("attr_" + self.name(), value)
+ html.write(value)
+
+ def from_html_vars(self):
+ return html.var("attr_" + self.name())
+
+
+
class IPAddressAttribute(TextAttribute):
def __init__(self, name, title, help = None, mandatory = False, dnslookup = False):