Module: check_mk
Branch: master
Commit: bd453399eea0576a6c6ebb11302915a03d6afb83
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=bd453399eea057…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Fri May 25 10:08:22 2012 +0200
WATO: keep track of foreign changes when activating
---
ChangeLog | 3 +
web/htdocs/images/icon_foreign_changes.png | Bin 0 -> 3259 bytes
web/htdocs/pages.css | 2 +-
web/htdocs/wato.css | 40 ++++++++++--------
web/htdocs/wato.py | 64 +++++++++++++++++++++++++---
5 files changed, 83 insertions(+), 26 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 55fba84..5c180ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -18,6 +18,9 @@
is valid on the replication slaves
* FIX: implement locking in order to prevent data corruption on
concurrent changes
+ * Keep track of changes made by other users before activating changes,
+ let user confirm this, new permission can be used to prevent a user
+ from activating foreign changes.
Multisite:
* New display type 'boxes-omit-root' for BI views
diff --git a/web/htdocs/images/icon_foreign_changes.png
b/web/htdocs/images/icon_foreign_changes.png
new file mode 100644
index 0000000..b11a7b6
Binary files /dev/null and b/web/htdocs/images/icon_foreign_changes.png differ
diff --git a/web/htdocs/pages.css b/web/htdocs/pages.css
index b9559b3..5abaa0e 100644
--- a/web/htdocs/pages.css
+++ b/web/htdocs/pages.css
@@ -467,7 +467,7 @@ table.form img.toggleheader {
height: 20px;
cursor: auto;
padding-right: 5px;
- vertical-align:middle;
+ vertical-align: middle;
}
table.form img.toggleheader.hover {
cursor: pointer;
diff --git a/web/htdocs/wato.css b/web/htdocs/wato.css
index 8ddadd4..e2a9a21 100644
--- a/web/htdocs/wato.css
+++ b/web/htdocs/wato.css
@@ -134,33 +134,37 @@ Boston, MA 02110-1301 USA.
font-weight: bold;
}
-.wato table.auditlog {
- background-image: url("images/form_background.png");
- background-repeat: repeat;
- border-collapse: collapse;
- margin-top: 3px;
- margin-bottom: 1em;
- width: 100%;
+.wato table.auditlog td.nobreak {
+ white-space: nowrap;
}
-.wato table.pending {
- background-color: #fff;
+.wato table.auditlog img {
+ width: 14px;
+ height: 14px;
+ margin: 0 5px 0 0;
+ padding: 0;
+ border-style; none;
+ float: left;
}
-.wato table.auditlog td {
- border: 1px solid #fff;
- padding: 2px 6px;
+.wato table.foreignchanges {
+ border-spacing: 3px;
+ margin-left: 20px;
+ margin-top: 5px;
+ margin-bottom: 5px;
}
-
-.wato table.auditlog td.nobreak {
- white-space: nowrap;
+.wato table.foreignchanges td {
+ padding: 2px 8px;
+ background-color: #ff0;
+ margin: 2px;
}
-.wato .pending td {
- border: 1px solid #444;
- padding: 2px 6px;
+.wato img.foreignchanges {
+ float: left;
+ margin-right: 10px;
}
+
.wato td.dns {
color: #666;
}
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 3d0d2fc..68d395b 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -3259,6 +3259,32 @@ def mode_changelog(phase):
[ '<a href="%s">%s</a>' %
(make_link([("mode", "edithost"), ("host", hn)]), hn)
for hn in defective_hosts.keys() ]))
+ # If there are changes by other users, we need a confirmation
+ transaction_already_checked = False
+ changes = foreign_changes()
+ if changes:
+ table = "<table class=foreignchanges>"
+ for user_id, count in changes.items():
+ table += '<tr><td>%s: </td><td>%d
%s</td></tr>' % \
+ (config.alias_of_user(user_id), count, _("changes"))
+ table += '</table>'
+ c = wato_confirm(_("Confirm activating foreign changes"),
+ '<img class=foreignchanges
src="images/icon_foreign_changes.png">' +
+ _("There are some changes made by you collegues that you will "
+ "activate if you proceed:") + table +
+ _("Do you really want to proceed?"))
+ if c == False:
+ return ""
+ elif not c:
+ return None
+ transaction_already_checked = True
+
+ if changes and not config.may("wato.activateforeign"):
+ raise MKAuthException(
+ _("Sorry, you are not allowed to activate "
+ "changes of other users."))
+
+
# Give hooks chance to do some pre-activation things (and maybe stop
# the activation)
try:
@@ -3274,7 +3300,7 @@ def mode_changelog(phase):
config.need_permission("wato.activate")
site_id = html.var("_site")
action = html.var("_siteaction")
- if html.check_transaction():
+ if transaction_already_checked or html.check_transaction():
try:
# If the site has no pending changes but just needs restart,
# the button text is just "Restart". We do a sync anyway.
This
@@ -3301,7 +3327,7 @@ def mode_changelog(phase):
raise
raise MKUserError(None, _("Remote command on site %s failed:
<pre>%s</pre>") % (site_id, e))
- elif html.check_transaction():
+ elif transaction_already_checked or html.check_transaction():
config.need_permission("wato.activate")
create_snapshot()
if is_distributed():
@@ -3502,7 +3528,16 @@ def mode_changelog(phase):
if len(pending) == 0:
html.write("<div class=info>" + _("There are no pending
changes.") + "</div>")
else:
- render_audit_log(pending, "pending")
+ render_audit_log(pending, "pending", hilite_others=True)
+
+# Determine if other users have made pending changes
+def foreign_changes():
+ changes = {}
+ for t, linkinfo, user, action, text in parse_audit_log("pending"):
+ if user != config.user_id:
+ changes.setdefault(user, 0)
+ changes[user] += 1
+ return changes
def log_entry(linkinfo, action, message, logfilename):
@@ -3737,7 +3772,7 @@ def display_paged((start_time, end_time, previous_log_time,
next_log_time)):
html.write('</div>')
-def render_audit_log(log, what, with_filename = False):
+def render_audit_log(log, what, with_filename = False, hilite_others=False):
htmlcode = ''
if what == 'audit':
log, times = paged_log(log)
@@ -3765,12 +3800,18 @@ def render_audit_log(log, what, with_filename = False):
even = "even"
for t, linkinfo, user, action, text in log:
even = even == "even" and "odd" or "even"
- htmlcode += '<tr class="%s0">' % even
+ hilite = hilite_others and config.user_id != user
+ htmlcode += '<tr class="data %s%d">' % (even, hilite and
2 or 0)
htmlcode += '<td class=nobreak>%s</td>' %
render_linkinfo(linkinfo)
htmlcode += '<td class=nobreak>%s</td>' % fmt_date(float(t))
htmlcode += '<td class=nobreak>%s</td>' % fmt_time(float(t))
- htmlcode += '<td>%s</td><td
width="100%%">%s</td></tr>\n' % \
- (user, text)
+ htmlcode += '<td class=nobreak>'
+ if hilite:
+ htmlcode += '<img class=icon
src="images/icon_foreign_changes.png" title="%s">' \
+ % _("This change has been made by another user")
+ htmlcode += user + '</td>'
+
+ htmlcode += '</td><td
width="100%%">%s</td></tr>\n' % text
htmlcode += "</table>"
if what == 'audit':
@@ -11288,6 +11329,15 @@ def load_plugins():
"current configuration (and thus rewriting the "
"monitoring configuration and restart the monitoring daemon.)"),
[ "admin", "user", ])
+
+ config.declare_permission("wato.activateforeign",
+ _("Activate Foreign Changes"),
+ _("When several users work in parallel with WATO then "
+ "several pending changes of different users might pile up "
+ "before changes are activate. Only with this permission "
+ "a user will be allowed to activate the current configuration "
+ "if this situation appears."),
+ [ "admin", ])
config.declare_permission("wato.auditlog",
_("Audit log"),