Module: check_mk
Branch: master
Commit: 46281280bd326126fb13eb7021153f9436cac7e6
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=46281280bd3261…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Thu Nov 18 09:42:26 2010 +0100
Audit log and pending changes
---
web/htdocs/.f12 | 2 +-
web/htdocs/check_mk.css | 27 +++++++++++++++++++
web/htdocs/lib.py | 8 ++++-
web/htdocs/webconf.py | 66 ++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 96 insertions(+), 7 deletions(-)
diff --git a/web/htdocs/.f12 b/web/htdocs/.f12
index 1df668e..d0db3c2 100644
--- a/web/htdocs/.f12
+++ b/web/htdocs/.f12
@@ -1,5 +1,5 @@
#!/bin/bash
set -e
-sudo cp -v *.py /omd/versions/default/share/check_mk/web/htdocs
+sudo cp -v *.css *.py /omd/versions/default/share/check_mk/web/htdocs
sudo cp -v ../plugins/pages/*.py /omd/versions/default/share/check_mk/web/plugins/pages/
sudo omd restart webconf apache
diff --git a/web/htdocs/check_mk.css b/web/htdocs/check_mk.css
index 9daf326..35f4070 100644
--- a/web/htdocs/check_mk.css
+++ b/web/htdocs/check_mk.css
@@ -1154,6 +1154,13 @@ div.really, div.success, div.error, div.message, div.warning {
border-style: solid;
}
+div.really h1, div.success h1, div.error h1, div.message h1, div.warning h1 {
+ font-size: 12pt;
+ font-weight: bold;
+ margin-bottom: 5px;
+color: black;
+}
+
div.really {
background-color: #f88;
border-color: #800;
@@ -1673,3 +1680,23 @@ table.add_snapin i {
color: white;
}
+/*
+ __ __ _ __
+ \ \ / /__| |__ ___ ___ _ __ / _|
+ \ \ /\ / / _ \ '_ \ / __/ _ \| '_ \| |_
+ \ V V / __/ |_) | (_| (_) | | | | _|
+ \_/\_/ \___|_.__/ \___\___/|_| |_|_|
+
+*/
+table.webconfpending {
+ background-color: #fff;
+ border-collapse: collapse;
+ margin-top: 3px;
+ margin-bottom: 1em;
+ width: 100%;
+}
+
+table.webconfpending td {
+ border: 1px solid #444;
+ padding: 2px 6px;
+}
diff --git a/web/htdocs/lib.py b/web/htdocs/lib.py
index 2818df0..e50e883 100644
--- a/web/htdocs/lib.py
+++ b/web/htdocs/lib.py
@@ -72,8 +72,8 @@ def make_nagios_directory(path):
"<li>Both Nagios and the web server are in the group
<tt>%s</tt>.</ul>Reason: %s" % (
path, defaults.www_group, defaults.www_group, e))
-def write_settings_file(path, content):
- file(path, "w", 0).write(pprint.pformat(content) + "\n")
+def create_user_file(path, mode):
+ f = file(path, mode, 0)
gid = grp.getgrnam(defaults.www_group).gr_gid
# Tackle user problem: If the file is owned by nagios, the web
# user can write it but cannot chown the group. In that case we
@@ -83,3 +83,7 @@ def write_settings_file(path, content):
os.chmod(path, 0660)
except:
pass
+ return f
+
+def write_settings_file(path, content):
+ create_user_file(path, "w").write(pprint.pformat(content) +
"\n")
diff --git a/web/htdocs/webconf.py b/web/htdocs/webconf.py
index 87d4f16..03d078c 100644
--- a/web/htdocs/webconf.py
+++ b/web/htdocs/webconf.py
@@ -5,19 +5,55 @@ import config
#config = importer.import_module("config", path =
["/omd/sites/webconf/share/check_mk/web/htdocs"])
# config = importer.import_module("config")
-import sys, pprint, socket, re, subprocess
+import sys, pprint, socket, re, subprocess, time
from lib import *
import htmllib
# import config
+conf_dir = defaults.var_dir + "/webconf/"
+
config.declare_permission("use_webconf",
"Use Webconfiguration",
"Only with this permission, users are allowed to use Check_MK web configuration
GUI.",
[ "admin", ])
+
+def log_entry(hostname, action, message, filename):
+ make_nagios_directory(conf_dir)
+ log_file = conf_dir + filename
+ create_user_file(log_file, "a").write("%d %s %s %s\n" %
+ (int(time.time()), html.req.user, action, message))
+
+
+def log_audit(hostname, what, message):
+ log_entry(hostname, what, message, "audit.log")
+
+
+def log_pending(hostname, what, message):
+ log_entry(hostname, what, message, "pending.log")
+ log_entry(hostname, what, message, "audit.log")
+
+
+def log_commit_pending():
+ pending = conf_dir + "pending.log"
+ if os.path.exists(pending):
+ os.remove(pending)
+
+def parse_pending():
+ pending = conf_dir + "pending.log"
+ if os.path.exists(pending):
+ entries = []
+ for line in file(pending):
+ line = line.rstrip()
+ entries.append(line.split(None, 3))
+ return entries
+ return []
+
+
def check_mk_automation(command, args, indata=""):
- p = subprocess.Popen(["check_mk", "--automation", command ] +
args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ p = subprocess.Popen(["check_mk", "--automation", command ] +
args,
+ stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
p.stdin.write(repr(indata))
p.stdin.close()
outdata = p.stdout.read()
@@ -123,18 +159,33 @@ def page_index(h):
# Context buttons
html.begin_context_buttons()
html.context_button("Create new host",
"webconf_edithost.py?filename=" + filename)
- html.context_button("Activate Changes!",
html.makeuri([("_action", "activate")]))
html.end_context_buttons()
+ # Activate changes
action = html.var("_action")
- if action == "activate":
+ if action == "activate" and html.transaction_valid():
activate_configuration()
+ pending = parse_pending()
+ if len(pending) > 0:
+ message = "<h1>Changes which are not yet activated:</h1>"
+ message += '<table class="webconfpending">'
+ for t, user, action, text in pending:
+ message +=
'<tr><td>%s</td><td>%s</td><td
width="100%%">%s</td></tr>\n' % (
+ time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime(float(t))),
+ user,
+ text)
+ message += "</table>"
+ message += '<a href="%s" class=button>Activate
Changes!</a>' % \
+ html.makeuri([("_action", "activate"),
("_transid", html.current_transid(html.req.user))])
+ html.show_warning(message)
+
# Deletion of entries
delname = html.var("_delete")
if delname and delname in hosts and html.confirm("Do you really want to delete
the host <tt>%s</tt>?" % delname):
del hosts[delname]
write_configuration_file(filename, hosts)
+ log_pending(delname, "delete-host", "Deleted host %s" %
delname)
check_mk_automation("delete-host", [delname])
@@ -236,6 +287,10 @@ def page_edithost(h):
write_configuration_file(filename, hosts)
# html.set_browser_redirect(1, "webconf.py?filename=%s" %
htmllib.urlencode(filename))
html.message("Saved changes.")
+ if not html.var("host"):
+ log_pending(hostname, "create-host", "Created new host
%s" % hostname)
+ else:
+ log_pending(hostname, "edit-host", "Edited properties
of host %s" % hostname)
except MKUserError, e:
html.write("<div class=error>%s</div>\n" % e.message)
@@ -306,6 +361,8 @@ def activate_configuration():
html.show_error(errors)
else:
html.message("The new configuration has been successfully activated.")
+ log_commit_pending() # flush logfile with pending actions
+ log_audit(None, "activate-config", "Configuration activated,
monitoring server restarted")
def show_services_table(hostname):
# Read current check configuration
@@ -322,6 +379,7 @@ def show_services_table(hostname):
check_mk_automation("set-autochecks", [hostname], active_checks)
html.message("Saved check configuration with %d checks." %
len(active_checks))
+ log_pending(hostname, "set-autochecks", "Saved check configuration
of host %s with %d checks" % (hostname, len(active_checks)))
# re-read current check configuration, because it has changed
table = check_mk_automation("try-inventory", ["tcp",
hostname])