SW-Inventory GUI with special characters in inventorized data
Message-ID: <55080a46.AAOvyoygZIczzl/Q%lm(a)mathias-kettner.de>
User-Agent: Heirloom mailx 12.5 6/20/10
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Module: check_mk
Branch: master
Commit: 0e9bb6a6346f8d13ce0d26ba08869463c6e12a17
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=0e9bb6a6346f8d…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Tue Mar 17 12:04:32 2015 +0100
#2147 FIX Fixed exception in HW-/SW-Inventory GUI with special characters in inventorized data
The information fetched from e.g. windows systems were not properly encoded. This could
lead into exceptions when viewing the data in the GUI.
To get these encoding errors fixed, you need to update to this version and then wait
for all your inventory data being updated. After it has been updated, the errors in the
GUI should be gone.
---
.werks/2147 | 15 +++++++++++++++
ChangeLog | 1 +
inventory/win_bios | 1 +
inventory/win_cpuinfo | 1 +
inventory/win_disks | 1 +
inventory/win_exefiles | 1 +
inventory/win_os | 1 +
inventory/win_reg_uninstall | 1 +
inventory/win_system | 1 +
inventory/win_video | 1 +
inventory/win_wmi_software | 1 +
modules/check_mk_base.py | 14 +++++++++++++-
12 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/.werks/2147 b/.werks/2147
new file mode 100644
index 0000000..ec6a636
--- /dev/null
+++ b/.werks/2147
@@ -0,0 +1,15 @@
+Title: Fixed exception in HW-/SW-Inventory GUI with special characters in inventorized data
+Level: 1
+Component: inv
+Class: fix
+Compatible: compat
+State: unknown
+Version: 1.2.7i1
+Date: 1426590143
+
+The information fetched from e.g. windows systems were not properly encoded. This could
+lead into exceptions when viewing the data in the GUI.
+
+To get these encoding errors fixed, you need to update to this version and then wait
+for all your inventory data being updated. After it has been updated, the errors in the
+GUI should be gone.
diff --git a/ChangeLog b/ChangeLog
index 45f04fc..dd93893 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -403,6 +403,7 @@
* 1851 FIX: win_exefiles: inventory check can now handle time stamps in us english locale
* 1943 FIX: inventory plugin win_os: no longer detects incorrect i386 architecture...
* 1995 FIX: dmidecode: Fix parsing when memory devices are listed before controller
+ * 2147 FIX: Fixed exception in HW-/SW-Inventory GUI with special characters in inventorized data...
1.2.6b1:
diff --git a/inventory/win_bios b/inventory/win_bios
index ac199a7..4a79180 100644
--- a/inventory/win_bios
+++ b/inventory/win_bios
@@ -75,5 +75,6 @@ def inv_win_bios(info):
inv_info['win_bios'] = {
"inv_function" : inv_win_bios,
+ "unicode" : True,
}
diff --git a/inventory/win_cpuinfo b/inventory/win_cpuinfo
index 7a614cf..d37cb21 100644
--- a/inventory/win_cpuinfo
+++ b/inventory/win_cpuinfo
@@ -124,5 +124,6 @@ def inv_win_cpuinfo(info):
inv_info['win_cpuinfo'] = {
"inv_function" : inv_win_cpuinfo,
+ "unicode" : True,
}
diff --git a/inventory/win_disks b/inventory/win_disks
index 7514f00..1feba35 100644
--- a/inventory/win_disks
+++ b/inventory/win_disks
@@ -88,4 +88,5 @@ def inv_win_disks(info):
inv_info['win_disks'] = {
"inv_function" : inv_win_disks,
+ "unicode" : True,
}
diff --git a/inventory/win_exefiles b/inventory/win_exefiles
index b5d1862..6c3401b 100644
--- a/inventory/win_exefiles
+++ b/inventory/win_exefiles
@@ -65,4 +65,5 @@ def inv_win_exefiles(info):
inv_info['win_exefiles'] = {
"inv_function" : inv_win_exefiles,
+ "unicode" : True,
}
diff --git a/inventory/win_os b/inventory/win_os
index 9fc5f2c..3d51076 100644
--- a/inventory/win_os
+++ b/inventory/win_os
@@ -47,4 +47,5 @@ def inv_win_os(info):
inv_info['win_os'] = {
"inv_function" : inv_win_os,
+ "unicode" : True,
}
diff --git a/inventory/win_reg_uninstall b/inventory/win_reg_uninstall
index ed21209..1cd4525 100644
--- a/inventory/win_reg_uninstall
+++ b/inventory/win_reg_uninstall
@@ -53,4 +53,5 @@ def inv_win_reg_uninstall(info):
inv_info['win_reg_uninstall'] = {
"inv_function" : inv_win_reg_uninstall,
+ "unicode" : True,
}
diff --git a/inventory/win_system b/inventory/win_system
index 5c232d1..2016694 100644
--- a/inventory/win_system
+++ b/inventory/win_system
@@ -51,4 +51,5 @@ def inv_win_system(info):
inv_info['win_system'] = {
"inv_function" : inv_win_system,
+ "unicode" : True,
}
diff --git a/inventory/win_video b/inventory/win_video
index 4eebf19..127b3de 100644
--- a/inventory/win_video
+++ b/inventory/win_video
@@ -53,4 +53,5 @@ def inv_win_video(info):
inv_info['win_video'] = {
"inv_function" : inv_win_video,
+ "unicode" : True,
}
diff --git a/inventory/win_wmi_software b/inventory/win_wmi_software
index 66382b5..bbec16a 100644
--- a/inventory/win_wmi_software
+++ b/inventory/win_wmi_software
@@ -55,4 +55,5 @@ def inv_win_wmi_software(info):
inv_info['win_wmi_software'] = {
"inv_function" : inv_win_wmi_software,
+ "unicode" : True,
}
diff --git a/modules/check_mk_base.py b/modules/check_mk_base.py
index c48a12e..9251418 100644
--- a/modules/check_mk_base.py
+++ b/modules/check_mk_base.py
@@ -825,6 +825,7 @@ def parse_info(lines, hostname):
section_options = {}
separator = None
encoding = None
+ to_unicode = False
for line in lines:
line = line.rstrip("\r")
stripped_line = line.strip()
@@ -872,6 +873,13 @@ def parse_info(lines, hostname):
# The section data might have a different encoding
encoding = section_options.get("encoding")
+ # Make the contents of the section unicode strings or UTF-8
+ # encoded bytestrings (like it was done always in the past)
+ try:
+ to_unicode = inv_info.get(section_name, {}).get('unicode', False)
+ except NameError:
+ pass # e.g. in precompiled mode we have no inv_info. That's ok.
+
elif stripped_line != '':
if "nostrip" not in section_options:
line = stripped_line
@@ -879,9 +887,13 @@ def parse_info(lines, hostname):
if encoding:
try:
decoded_line = line.decode(encoding)
- line = decoded_line.encode('utf-8')
+ if not to_unicode:
+ line = decoded_line.encode('utf-8')
except:
pass
+ elif to_unicode:
+ line = line.decode('utf-8')
+
section.append(line.split(separator))
return info, piggybacked, persist
Module: check_mk
Branch: master
Commit: cebcaf83b72bc7fd9483900113d7d560b00f0eb0
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=cebcaf83b72bc7…
Author: Goetz Golla <gg(a)mathias-kettner.de>
Date: Tue Mar 17 11:53:58 2015 +0100
#2104 aix_if: new agent section and check
This aix check_mk_agent has a new section aix_if extracting more information about network interfaces
than the previous lnx_if section. A new interface check for AIX named aix_if has also been created
given more useful information.
As long as you do not replace the check_mk_agent on your AIX systems, nothing will change.
When you replace the agent with the new one, you will have to redo the service discovery.
Interfaces will reappear with the same service description, but with more information about the NIC.
---
.werks/2104 | 16 +++++
ChangeLog | 2 +
agents/check_mk_agent.aix | 16 ++---
checkman/aix_if | 171 +++++++++++++++++++++++++++++++++++++++++++++
checks/aix_if | 135 +++++++++++++++++++++++++++++++++++
5 files changed, 329 insertions(+), 11 deletions(-)
Diff: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commitdiff;h=cebcaf83b7…
Module: check_mk
Branch: master
Commit: 34016d242c55cc15d3d41c18875de42e4741be71
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=34016d242c55cc…
Author: Goetz Golla <gg(a)mathias-kettner.de>
Date: Tue Mar 17 11:31:39 2015 +0100
Updated bug entries #2295
---
.bugs/2295 | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/.bugs/2295 b/.bugs/2295
new file mode 100644
index 0000000..740fefe
--- /dev/null
+++ b/.bugs/2295
@@ -0,0 +1,40 @@
+Title: mk_inventory.ps1 workaround für BOM führt bei manchen Kunden zu Problemen
+Component: inv
+State: open
+Date: 2015-03-17 11:25:20
+Targetversion: 1.2.6
+Class: bug
+
+die zweite Zeile in mk_inventory.ps1
+verursacht bei uns das Problem:
+
+ mk_inventory.ps1
+
+ [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
+
+ write-output "" # workaround
+ to prevent the byte order mark to be at the beginning of the first section
+
+ $name = (Get-Item env:\Computername).Value
+
+ ....
+
+ Das Script wir bei jedem Agentenaufruf
+ gecalled, steigt dann aber vor dem Inventory aus, da ein Timestamp existiert.
+
+ Da die leere Zeile aber vor dem Ausstieg
+ geschrieben wird, führt dies zu folgenden Bild im Agentenoutput:
+
+ [[[Veeam Backup]]]
+ [[[Windows PowerShell]]]
+ <<<logwatch>>>
+
+ <<<local>>>
+ <<<mrpe>>>
+
+ Damit kommt dann der logwatch.ec check nicht mehr zurecht.
+
+ Log Forwarding UNKNOWN - invalid output from agent, invalid check
+
+ > parameters or error in implementation of check logwatch.ec. Please
+ > enable "Log exceptions in check plugins" for further information.
Module: check_mk
Branch: master
Commit: c05364ab77d301fea49d237ffbc7b48554e8387e
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=c05364ab77d301…
Author: Goetz Golla <gg(a)mathias-kettner.de>
Date: Tue Mar 17 11:18:01 2015 +0100
ibm_imm_fan: code rewrite, no more perfdata, hardcoded levels
---
checkman/ibm_imm_fan | 13 +++++--------
checks/ibm_imm_fan | 46 ++++++++++++++++++++--------------------------
2 files changed, 25 insertions(+), 34 deletions(-)
diff --git a/checkman/ibm_imm_fan b/checkman/ibm_imm_fan
index 653eec4..c7ce6c3 100644
--- a/checkman/ibm_imm_fan
+++ b/checkman/ibm_imm_fan
@@ -4,18 +4,15 @@ catalog: hw/server/ibm
license: GPL
distribution: check_mk
description:
- This check monitors the rpms of fans via a IBM Integrated Management Module
- (IMM). It uses snmp and the IBM IMM MIB to gather and interpret the fan data.
+ This check monitors the percentage of maximum RPM of fans via the IBM
+ Integrated Management Module (IMM). It uses snmp and the IBM IMM MIB to
+ gather the fan data.
- The check uses the lower warning and critical levels extracted from the
- device (OIDs {fanCritLimitLow}, {fanNonCritLimitLow}) to calculate the state
- of the service.
+ The check uses hardcoded lower warning and critical levels of (28%,25%)
+ to calculate the state of the service.
inventory:
The service discovery will find one service per fan
item:
The name of the fan as extracted from the OID {fanDescr}
-
-perfdata:
- The RPM of the fan
diff --git a/checks/ibm_imm_fan b/checks/ibm_imm_fan
index ebe47ba..898567b 100644
--- a/checks/ibm_imm_fan
+++ b/checks/ibm_imm_fan
@@ -24,53 +24,47 @@
# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
# Boston, MA 02110-1301 USA.
+
def inventory_ibm_imm_fan(info):
- for line in info:
- yield line[0], None
+ for descr, speed in info:
+ if speed.lower() != 'offline':
+ yield descr, {}
def check_ibm_imm_fan(item, _no_params, info):
- for line in info:
- if line[0] == item:
- # values are rpm in percent to max rpm
- rpm = int(line[1].split(" ")[0])
- dev_crit_lower, dev_warn_lower = map(lambda rpm: int(rpm)/10.0, line[2:-1])
- status = line[-1]
- infotext = "%d%% of max rpm" % rpm
- if status:
- infotext =+ ", Status: %s" % status
- perfdata = [ ("rpm", str(rpm)+"%", str(dev_warn_lower)+":", \
- str(dev_crit_lower)+":") ]
- levelstext = " (warn/crit lower levels: %d%%/%d%%)" % (dev_warn_lower, dev_crit_lower)
- if rpm <= dev_crit_lower:
+ for descr, speed in info:
+ if descr == item:
+
+ if speed.lower() == "offline":
+ return 2, "is offline"
+
+ # speed can be "34 %", or "34%", or "34 % of maximum"
+ rpm_perc = int(speed.replace("%", " ").split(" ")[0])
+ infotext = "%d%% of max rpm" % rpm_perc
+
+ warn, crit = (28, 25) # preliminary estimates of levels
+ levelstext = " (warn/crit at %d%%/%d%%)" % (warn,crit)
+
+ if rpm_perc <= crit:
state = 2
infotext += levelstext
- elif rpm<= dev_warn_lower:
+ elif rpm_perc <= warn:
state = 1
infotext += levelstext
else:
state = 0
- return state, infotext, perfdata
+ return state, infotext
check_info["ibm_imm_fan"] = {
'check_function' : check_ibm_imm_fan,
'inventory_function' : inventory_ibm_imm_fan,
'service_description' : 'Fan %s',
- 'has_perdata' : True,
'snmp_scan_function' :
lambda oid: oid('.1.3.6.1.2.1.1.1.0').lower().endswith(" mips") or \
oid('.1.3.6.1.2.1.1.1.0').lower().endswith(" sh4a"),
'snmp_info' : ('.1.3.6.1.4.1.2.3.51.3.1.3.2.1', [ # fanTable.fanEntry
- #1, # fanIndex
2, # fanDescr
3, # fanSpeed
- #4, # fanNonRecovLimitHigh
- #5, # fanCritLimitHigh
- #6, # fanNonCritLimitHigh
- #7, # fanNonRecovLimitLow
- 8, # fanCritLimitLow
- 9, # fanNonCritLimitLow
- 10, # fanHealthStatus
]),
}
Module: check_mk
Branch: master
Commit: 15136a6f0ff8f53339af60c9ed91d1095f75da61
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=15136a6f0ff8f5…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Tue Mar 17 11:15:20 2015 +0100
#2146 FIX In distributed environments user notification rules trigger a profile synchronisation now
In previous versions the custom user notification rules were not synchronized to
remote sites in the moment the user changed his rules. An admin had to perform
a synchronisation via WATO to replicate these changes to the rules to the remote
sites for taking effect there.
Now, when a user changes his individual notification rules, a replication of
the updated user profile is triggered.
---
.werks/2146 | 16 ++++++++++++
ChangeLog | 1 +
web/htdocs/wato.py | 74 ++++++++++++++++++++++++++++++++++++++++++----------
3 files changed, 77 insertions(+), 14 deletions(-)
diff --git a/.werks/2146 b/.werks/2146
new file mode 100644
index 0000000..16b4917
--- /dev/null
+++ b/.werks/2146
@@ -0,0 +1,16 @@
+Title: In distributed environments user notification rules trigger a profile synchronisation now
+Level: 1
+Component: wato
+Class: fix
+Compatible: compat
+State: unknown
+Version: 1.2.7i1
+Date: 1426587167
+
+In previous versions the custom user notification rules were not synchronized to
+remote sites in the moment the user changed his rules. An admin had to perform
+a synchronisation via WATO to replicate these changes to the rules to the remote
+sites for taking effect there.
+
+Now, when a user changes his individual notification rules, a replication of
+the updated user profile is triggered.
diff --git a/ChangeLog b/ChangeLog
index 3d78848..f1fbe7c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -357,6 +357,7 @@
* 2084 FIX: Disabled notification for a user is now shown on profile page even when not permitted to edit...
* 2045 FIX: Avoid fetching SNMP data when showing service list in WATO - unless Full Scan is pressed
* 2047 FIX: Allow overriding existing WATO rules by own files in local/ hierarchy...
+ * 2146 FIX: In distributed environments user notification rules trigger a profile synchronisation now...
Notifications:
* 1662 notification plugin spectrum: finalized script. now able to handle host notications
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index c6365df..dc927bc 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -9087,6 +9087,8 @@ def render_bulks(only_ripe):
# Similar like mode_notifications, but just for the user specific notification table
def mode_user_notifications(phase, profilemode):
+ global notification_rule_start_async_repl
+
if profilemode:
userid = config.user_id
title = _("Your personal notification rules")
@@ -9120,10 +9122,18 @@ def mode_user_notifications(phase, profilemode):
_("Do you really want to delete the notification rule <b>%d</b> <i>%s</i>?" %
(nr, rule.get("description",""))))
if c:
- log_pending(SYNC, None, "notification-delete-user-rule", _("Deleted notification rule %d of user %s") %
- (nr, userid))
del rules[nr]
userdb.save_users(users)
+
+ log_what = "notification-delete-user-rule"
+ log_text = _("Deleted notification rule %d of user %s") % (nr, userid)
+
+ notification_rule_start_async_repl = False
+ if profilemode and is_distributed():
+ notification_rule_start_async_repl = True
+ log_audit(None, log_what, log_text)
+ else:
+ log_pending(SYNC, None, log_what, log_text)
elif c == False:
return ""
else:
@@ -9137,15 +9147,31 @@ def mode_user_notifications(phase, profilemode):
del rules[from_pos] # make to_pos now match!
rules[to_pos:to_pos] = [rule]
userdb.save_users(users)
- log_pending(SYNC, None, "notification-move-user-rule", _("Changed position of notification rule %d of user %s") %
- (from_pos, userid))
+
+ log_what = "notification-move-user-rule"
+ log_text = _("Changed position of notification rule %d of user %s") % (from_pos, userid)
+
+ notification_rule_start_async_repl = False
+ if profilemode and is_distributed():
+ notification_rule_start_async_repl = True
+ log_audit(None, log_what, log_text)
+ else:
+ log_pending(SYNC, None, log_what, log_text)
return
+ if notification_rule_start_async_repl:
+ user_profile_async_replication_dialog()
+ notification_rule_start_async_repl = False
+ html.write('<h3>%s</h3>' % _('Notification Rules'))
+
rules = user.get("notification_rules", [])
render_notification_rules(rules, userid, profilemode = profilemode)
+notification_rule_start_async_repl = False
def mode_notification_rule(phase, profilemode):
+ global notification_rule_start_async_repl
+
edit_nr = int(html.var("edit", "-1"))
clone_nr = int(html.var("clone", "-1"))
if profilemode:
@@ -9215,9 +9241,20 @@ def mode_notification_rule(phase, profilemode):
save_notification_rules(rules)
if new:
- log_pending(SYNC, None, "new-notification-rule", _("Created new notification rule") + suffix)
+ log_what = "new-notification-rule"
+ log_text = _("Created new notification rule") + suffix
+ else:
+ log_what = "edit-notification-rule"
+ log_text = _("Changed notification rule %d") % edit_nr + suffix
+
+ notification_rule_start_async_repl = False
+ if profilemode and is_distributed():
+ notification_rule_start_async_repl = True
+ log_audit(None, log_what, log_text)
+ return # don't redirect to other page
else:
- log_pending(SYNC, None, "edit-notification-rule", _("Changed notification rule %d") % edit_nr + suffix)
+ log_pending(SYNC, None, log_what, log_text)
+
if profilemode:
return "user_notifications_p"
elif userid:
@@ -9225,6 +9262,10 @@ def mode_notification_rule(phase, profilemode):
else:
return "notifications"
+ if notification_rule_start_async_repl:
+ user_profile_async_replication_dialog()
+ notification_rule_start_async_repl = False
+ return
html.begin_form("rule", method = "POST")
vs.render_input("rule", rule)
@@ -15683,8 +15724,8 @@ def select_language(user):
'create you own translation, you find <a href="%(url)s">documentation online</a>.') %
{ "url" : "http://mathias-kettner.de/checkmk_multisite_i18n.html"} )
-def user_profile_async_replication_dialog():
- html.header(_('Replicate new Authentication Information'),
+def user_profile_async_replication_page():
+ html.header(_('Replicate new User Profile'),
javascripts = ['wato'],
stylesheets = ['check_mk', 'pages', 'wato', 'status'])
@@ -15692,14 +15733,20 @@ def user_profile_async_replication_dialog():
html.context_button(_('User Profile'), 'user_profile.py', 'back')
html.end_context_buttons()
+ user_profile_async_replication_dialog()
+
+ html.footer()
+
+
+def user_profile_async_replication_dialog():
sites = [(name, config.site(name)) for name in config.sitenames() ]
sort_sites(sites)
repstatus = load_replication_status()
- html.message(_('To make a login possible with your new credentials on all remote sites, the '
- 'new login credentials need to be replicated to the remote sites. This is done '
- 'on this page now. Each site is being represented by a single image which is first '
- 'shown gray and then fills to green during synchronisation.'))
+ html.message(_('For make your changes available on all remote sites, your user profile needs '
+ 'to be replicated to the remote sites. This is done on this page now. Each site '
+ 'is being represented by a single image which is first shown gray and then fills '
+ 'to green during synchronisation.'))
html.write('<h3>%s</h3>' % _('Replication States'))
html.write('<div id="profile_repl">')
@@ -15741,7 +15788,6 @@ def user_profile_async_replication_dialog():
html.javascript('var g_num_replsites = %d;\n' % num_replsites)
html.write('</div>')
- html.footer()
def page_user_profile(change_pw=False):
@@ -15853,7 +15899,7 @@ def page_user_profile(change_pw=False):
# When in distributed setup, display the replication dialog instead of the normal
# profile edit dialog after changing the password.
if start_async_replication:
- user_profile_async_replication_dialog()
+ user_profile_async_replication_page()
return
if change_pw: