Module: check_mk
Branch: master
Commit: ab01ac097ecdb39ff6324c27115b4853dbfbf682
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=ab01ac097ecdb3…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Thu Jun 5 09:34:30 2014 +0200
mysql_slave: New check for monitoring MySQL slave sync state
---
.werks/815 | 8 ++++
ChangeLog | 1 +
checkman/mysql_slave | 29 +++++++++++
checks/mysql_slave | 88 ++++++++++++++++++++++++++++++++++
web/plugins/wato/check_parameters.py | 24 ++++++++++
5 files changed, 150 insertions(+)
diff --git a/.werks/815 b/.werks/815
new file mode 100644
index 0000000..77bb675
--- /dev/null
+++ b/.werks/815
@@ -0,0 +1,8 @@
+Title: mysql_slave: New check for monitoring MySQL slave sync state
+Level: 1
+Component: checks
+Version: 1.2.5i4
+Date: 1401953646
+Class: feature
+
+
diff --git a/ChangeLog b/ChangeLog
index 747a77c..6d184ec 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,7 @@
* 0812 nginx_status: New check for monitoring status information of the Nginx web server...
* 0986 citrix_licenses: new check for monitoring Citrix licenses
* 0814 Agent versions can now be checked with "at least version X" parameters...
+ * 0815 mysql_slave: New check for monitoring MySQL slave sync state
* 0616 FIX: brocade.fan, brocade.power, brocade.temp: will now only discover services which are not marked as absent
Multisite:
diff --git a/checkman/mysql_slave b/checkman/mysql_slave
new file mode 100644
index 0000000..aa3393c
--- /dev/null
+++ b/checkman/mysql_slave
@@ -0,0 +1,29 @@
+title: MySQL Database: Slave Sync Status
+agents: linux
+catalog: app/mysql
+license: GPL
+distribution: check_mk
+description:
+ This check monitors the synchronsiation state of MySQL slave databases.
+
+ This check needs the agent plugin {mk_mysql} to be installed on the
+ monitored database server. Further details about this plugin and
+ monitoring of MySQL can be found in the Check_MK online documentation
+ in the article "Monitoring MySQL with Check_MK".
+
+inventory:
+ On each host where the agent plugin {mk_mysql} is being installed
+ and the MySQL daemon is running one service is being generated.
+
+[parameters]
+parameters (dict): A dictionary with currentl just one possible key: {"seconds_behind_master"}. This
+ is a pair if two floating point numbers:
+
+ {warn} (float): The maximum number of seconds behind the master that triggers
+ a {WARN} state.
+
+ {crit} (float): The maximum number of seconds behind the master that triggers
+ a {CRIT} state.
+
+ If {seconds_behind_master} is not set, the check always reports {CRITICAL} states
+ when either the slave IO or slave SQL are reported as not running.
diff --git a/checks/mysql_slave b/checks/mysql_slave
new file mode 100644
index 0000000..56868d1
--- /dev/null
+++ b/checks/mysql_slave
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+# -*- encoding: utf-8; py-indent-offset: 4 -*-
+# +------------------------------------------------------------------+
+# | ____ _ _ __ __ _ __ |
+# | / ___| |__ ___ ___| | __ | \/ | |/ / |
+# | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+# | | |___| | | | __/ (__| < | | | | . \ |
+# | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+# | |
+# | Copyright Mathias Kettner 2014 mk(a)mathias-kettner.de |
+# +------------------------------------------------------------------+
+#
+# This file is part of Check_MK.
+# The official homepage is at http://mathias-kettner.de/check_mk.
+#
+# check_mk is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation in version 2. check_mk is distributed
+# in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
+# out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE. See the GNU General Public License for more de-
+# ails. You should have received a copy of the GNU General Public
+# License along with GNU Make; see the file COPYING. If not, write
+# to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+# Boston, MA 02110-1301 USA.
+
+def inventory_mysql_slave(info):
+ if info:
+ return [(None, {})]
+
+def parse_mysql_slave(info):
+ data = {}
+ for l in info:
+ if ':' in l[0]:
+ val = ' '.join(l[1:])
+
+ # Parse some values
+ try:
+ val = int(val)
+ except ValueError:
+ if val == 'Yes':
+ val = True
+ elif val == 'No':
+ val = False
+ elif val == 'None':
+ val = None
+
+ data[l[0][:-1]] = val
+ return data
+
+def check_mysql_slave(_unused, params, info):
+ data = parse_mysql_slave(info)
+
+ state = 0
+ perfdata = []
+ output = []
+
+ if data['Slave_IO_Running']:
+ output.append('Slave-IO: running')
+ else:
+ output.append('Slave-IO: not running(!!)')
+
+ if data['Slave_SQL_Running']:
+ output.append('Slave-SQL: running')
+ else:
+ output.append('Slave-SQL: not running(!!)')
+
+ out = 'Time behind Master: %s' % get_age_human_readable(data['Seconds_Behind_Master'])
+ warn, crit = params.get('seconds_behind_master', (None, None))
+ if crit != None and data['Seconds_Behind_Master'] > crit:
+ state = 2
+ out += '(!!)'
+ elif warn != None and data['Seconds_Behind_Master'] > warn:
+ state = 1
+ out += '(!)'
+ output.append(out)
+ perfdata.append(('seconds_behind_master', data['Seconds_Behind_Master'], warn, crit))
+
+ return state, ', '.join(output), perfdata
+
+check_info['mysql_slave'] = {
+ "check_function" : check_mysql_slave,
+ "inventory_function" : inventory_mysql_slave,
+ "service_description" : "MySQL DB Slave",
+ "has_perfdata" : False,
+ "group" : "mysql_slave",
+}
+
diff --git a/web/plugins/wato/check_parameters.py b/web/plugins/wato/check_parameters.py
index 0b3b1d8..1b85e29 100644
--- a/web/plugins/wato/check_parameters.py
+++ b/web/plugins/wato/check_parameters.py
@@ -3028,6 +3028,30 @@ register_check_parameters(
register_check_parameters(
subgroup_applications,
+ "mysql_slave",
+ _("MySQL Slave"),
+ Dictionary(
+ elements = [
+ ( "seconds_behind_master",
+ Tuple(
+ title = _("Seconds behind master (Slave lag)"),
+ help = _("When the slave is actively processing updates, this field shows the difference "
+ "between the current timestamp on the slave and the original timestamp logged on "
+ "the master for the most event currently being processed on the slave. "
+ "You can configure the amount of time you treat as a problem here."),
+ elements = [
+ Age(title = _("Warning if above")),
+ Age(title = _("Critical if above")),
+ ]
+ )
+ ),
+ ]),
+ None,
+ "dict"
+)
+
+register_check_parameters(
+ subgroup_applications,
"f5_connections",
_("F5 Loadbalancer Connections"),
Dictionary(
Module: check_mk
Branch: master
Commit: 9799cc1c076819cf17bbaf605bd4eec13bff6c1d
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=9799cc1c076819…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Thu Jun 5 08:30:22 2014 +0200
Agent versions can now be checked with "at least version X" parameters
The rule "Check for correct version of Check_MK agent" can now check for minimal
versions instead of specific ones. You can configure minimal build and/or release
versions your agents need to be.
---
.werks/814 | 10 ++++
ChangeLog | 1 +
modules/check_mk.py | 12 +++-
modules/check_mk_base.py | 88 +++++++++++++++++++++++++++-
web/plugins/wato/check_mk_configuration.py | 46 +++++++++++----
5 files changed, 140 insertions(+), 17 deletions(-)
diff --git a/.werks/814 b/.werks/814
new file mode 100644
index 0000000..977fc4a
--- /dev/null
+++ b/.werks/814
@@ -0,0 +1,10 @@
+Title: Agent versions can now be checked with "at least version X" parameters
+Level: 1
+Component: checks
+Version: 1.2.5i4
+Date: 1401949735
+Class: feature
+
+The rule "Check for correct version of Check_MK agent" can now check for minimal
+versions instead of specific ones. You can configure minimal build and/or release
+versions your agents need to be.
diff --git a/ChangeLog b/ChangeLog
index 6bcfcdd..d5909c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
1.2.5i4:
Checks & Agents:
* 0812 nginx_status: New check for monitoring status information of the Nginx web server...
+ * 0814 Agent versions can now be checked with "at least version X" parameters...
Multisite:
* 0934 FIX: Logwatch messages with class unknown ( 'u' ) now displayed as WARN...
diff --git a/modules/check_mk.py b/modules/check_mk.py
index eb34e88..867e8d0 100755
--- a/modules/check_mk.py
+++ b/modules/check_mk.py
@@ -651,12 +651,18 @@ def check_interval_of(hostname, checkname):
def agent_target_version(hostname):
agent_target_versions = host_extra_conf(hostname, check_mk_agent_target_versions)
if len(agent_target_versions) > 0:
- if agent_target_versions[0] == "ignore":
+ spec = agent_target_versions[0]
+ if spec == "ignore":
return None
- elif agent_target_versions[0] == "site":
+ elif spec == "site":
return check_mk_version
+ elif type(spec) == str:
+ # Compatibility to old value specification format (a single version string)
+ return spec
+ elif spec[0] == 'specific':
+ return spec[1]
else:
- return agent_target_versions[0]
+ return spec # return the whole spec in case of an "at least version" config
regex_cache = {}
def regex(r):
diff --git a/modules/check_mk_base.py b/modules/check_mk_base.py
index 511adf0..7fbb1bb 100644
--- a/modules/check_mk_base.py
+++ b/modules/check_mk_base.py
@@ -973,8 +973,23 @@ def do_check(hostname, ipaddress, only_check_types = None):
elif num_errors > 0:
output = "Got no information from host, "
status = exit_spec.get("empty_output", 2)
- elif expected_version and agent_version != expected_version:
- output = "unexpected agent version %s (should be %s), " % (agent_version, expected_version)
+ elif expected_version and agent_version \
+ and not is_expected_agent_version(agent_version, expected_version):
+ # expected version can either be:
+ # a) a single version string
+ # b) a tuple of ("at_least", {'daily_build': '2014.06.01', 'release': '1.2.5i4'}
+ # (the dict keys are optional)
+ if type(expected_version) == tuple and expected_version[0] == 'at_least':
+ expected = 'at least'
+ if 'daily_build' in expected_version[1]:
+ expected += ' build %s' % expected_version[1]['daily_build']
+ if 'release' in expected_version[1]:
+ if 'daily_build' in expected_version[1]:
+ expected += ' or'
+ expected += ' release %s' % expected_version[1]['release']
+ else:
+ expected = expected_version
+ output = "unexpected agent version %s (should be %s), " % (agent_version, expected)
status = exit_spec.get("wrong_version", 1)
elif agent_min_version and agent_version < agent_min_version:
output = "old plugin version %s (should be at least %s), " % (agent_version, agent_min_version)
@@ -1409,6 +1424,75 @@ def username():
def i_am_root():
return os.getuid() == 0
+# Parses versions of Check_MK and converts them into comparable integers.
+# This does not handle daily build numbers, only official release numbers.
+# 1.2.4p1 -> 01020450001
+# 1.2.4 -> 01020450000
+# 1.2.4b1 -> 01020420100
+# 1.2.3i1p1 -> 01020310101
+# 1.2.3i1 -> 01020310100
+def parse_version(v):
+ def extract_number(s):
+ number = ''
+ for i, c in enumerate(s):
+ try:
+ int(c)
+ number += c
+ except ValueError:
+ s = s[i:]
+ return number and int(number) or 0, s
+ return number and int(number) or 0, ''
+
+ major, minor, rest = v.split('.')
+ sub, rest = extract_number(rest)
+
+ if not rest:
+ val = 50000
+ elif rest[0] == 'p':
+ num, rest = extract_number(rest[1:])
+ val = 50000 + num
+ elif rest[0] == 'i':
+ num, rest = extract_number(rest[1:])
+ val = 10000 + num*100
+
+ if rest and rest[0] == 'p':
+ num, rest = extract_number(rest[1:])
+ val += num
+ elif rest[0] == 'b':
+ num, rest = extract_number(rest[1:])
+ val = 20000 + num*100
+
+ return int('%02d%02d%02d%05d' % (int(major), int(minor), sub, val))
+
+def is_expected_agent_version(agent_version, expected_version):
+ try:
+ if type(expected_version) == str and expected_version != agent_version:
+ return False
+
+ elif type(expected_version) == tuple and expected_version[0] == 'at_least':
+ is_daily_build = len(agent_version) == 10 or '-' in agent_version
+
+ spec = expected_version[1]
+ if is_daily_build and 'daily_build' in spec:
+ expected = int(spec['daily_build'].replace('.', ''))
+ if len(agent_version) == 10: # master build
+ agent = int(agent_version.replace('.', ''))
+
+ else: # branch build (e.g. 1.2.4-2014.06.01)
+ agent = int(agent_version.split('-')[1].replace('.', ''))
+
+ if agent < expected:
+ return False
+
+ elif 'release' in spec:
+ if parse_version(agent_version) < parse_version(spec['release']):
+ return False
+
+ return True
+ except Exception, e:
+ raise MKGeneralException("Unable to check agent version (Agent: %s Expected: %s, Error: %s)" %
+ (agent_version, expected_version, e))
+
# Returns the nodes of a cluster, or None if hostname is
# not a cluster
g_nodesof_cache = {}
diff --git a/web/plugins/wato/check_mk_configuration.py b/web/plugins/wato/check_mk_configuration.py
index 6e034b0..dd48836 100644
--- a/web/plugins/wato/check_mk_configuration.py
+++ b/web/plugins/wato/check_mk_configuration.py
@@ -2286,18 +2286,40 @@ register_rule(group,
register_rule(group,
"check_mk_agent_target_versions",
- OptionalDropdownChoice(
- title = _("Check for correct version of Check_MK agent"),
- help = _("If you want to make sure all of your Check_MK agents are running"
- " one specific version, you may set it by this rule. Agents running "
- " some different version return a none ok state then"),
- choices = [
- ("ignore", _("Ignore the version")),
- ("site", _("Same version as the monitoring site")),
- ],
- otherlabel = _("Specific version"),
- explicit = TextAscii(allow_empty = False),
- default_value = "ignore",
+ Transform(
+ CascadingDropdown(
+ title = _("Check for correct version of Check_MK agent"),
+ help = _("If you want to make sure all of your Check_MK agents are running"
+ " one specific version, you may set it by this rule. Agents running "
+ " some different version return a none ok state then"),
+ choices = [
+ ("ignore", _("Ignore the version")),
+ ("site", _("Same version as the monitoring site")),
+ ("specific", _("Specific version"),
+ TextAscii(
+ allow_empty = False,
+ )
+ ),
+ ("at_least", _("At least"),
+ Dictionary(
+ elements = [
+ ('release', TextAscii(
+ title = _('Official Release version'),
+ allow_empty = False,
+ )),
+ ('daily_build', TextAscii(
+ title = _('Daily build'),
+ allow_empty = False,
+ )),
+ ]
+ ),
+ ),
+ ],
+ default_value = "ignore",
+ ),
+ # In the past, this was a OptionalDropdownChoice() which values could be strings:
+ # ignore, site or a custom string representing a version number.
+ forth = lambda x: type(x) == str and x not in [ "ignore", "site" ] and ("specific", x) or x
)
)
Module: check_mk
Branch: master
Commit: 1c8d9035a41a09bbcbab1aaf0a3308db8d833bbe
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=1c8d9035a41a09…
Author: Goetz Golla <gg(a)mathias-kettner.de>
Date: Wed Jun 4 18:28:02 2014 +0200
FIX brocade.fan, brocade.power, brocade.temp: will now only discover services which are not marked as absent
---
.werks/616 | 8 ++++++++
ChangeLog | 1 +
checkman/brocade.fan | 7 +++++--
checkman/brocade.power | 5 +++--
checkman/brocade.temp | 6 ++++--
checks/brocade | 34 +++++++++++++++++++---------------
6 files changed, 40 insertions(+), 21 deletions(-)
diff --git a/.werks/616 b/.werks/616
new file mode 100644
index 0000000..9f4e57e
--- /dev/null
+++ b/.werks/616
@@ -0,0 +1,8 @@
+Title: brocade.fan, brocade.power, brocade.temp: will now only discover services which are not marked as absent
+Level: 1
+Component: checks
+Version: 1.2.5i4
+Date: 1401899225
+Class: fix
+
+
diff --git a/ChangeLog b/ChangeLog
index 38c6775..017021e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
1.2.5i4:
Checks & Agents:
* 0812 nginx_status: New check for monitoring status information of the Nginx web server...
+ * 0616 FIX: brocade.fan, brocade.power, brocade.temp: will now only discover services which are not marked as absent
Multisite:
* 0934 FIX: Logwatch messages with class unknown ( 'u' ) now displayed as WARN...
diff --git a/checkman/brocade.fan b/checkman/brocade.fan
index ff00cd3..fde800a 100644
--- a/checkman/brocade.fan
+++ b/checkman/brocade.fan
@@ -7,13 +7,16 @@ description:
This checks monitors the FAN speeds of a Brocade FC switch.
item:
- The number of the FAN (1, 2, 3 ...) like descripted in the SNMP output.
+ The number of the FAN (1, 2, 3 ...) as described in the SNMP output.
perfdata:
The speed of each fan.
inventory:
- The inventory creates a service for each fan.
+
+ The inventory creates a service for each fan unless it is marked as absent
+ in {swSensorStatus}
+
[parameters]
warn(int): the minimum fan speed for an OK state
diff --git a/checkman/brocade.power b/checkman/brocade.power
index 7ee7a5f..a597899 100644
--- a/checkman/brocade.power
+++ b/checkman/brocade.power
@@ -8,8 +8,9 @@ description:
a Brocade switch.
item:
- The number of the power supply (1, 2, 3 ...) like descripted in the SNMP output.
+ The number of the power supply (1, 2, 3 ...) as described in the SNMP output.
inventory:
- The inventory creates a service for each power supply.
+ The inventory creates a service for each power supply unless it is marked as absent
+ in {swSensorStatus}
diff --git a/checkman/brocade.temp b/checkman/brocade.temp
index 221d3b9..7eaf931 100644
--- a/checkman/brocade.temp
+++ b/checkman/brocade.temp
@@ -7,13 +7,15 @@ description:
This checks monitors the hardware temperatures of a Brocade FC switch.
item:
- The Number of the sensor (1, 2, 3 ...) like descripted in the SNMP output.
+ The number of the sensor (1, 2, 3 ...) as described in the SNMP output.
perfdata:
The current temperature value for each sensor
inventory:
- The inventory creates a service for each sensor.
+ The inventory creates a service for each sensor unless it is marked as absent
+ in {swSensorStatus}
+
[parameters]
warn(int): the temperature at which a WARN state is reached
diff --git a/checks/brocade b/checks/brocade
index f455019..989b511 100644
--- a/checks/brocade
+++ b/checks/brocade
@@ -36,8 +36,8 @@
def brocade_sensor_convert(info, what):
return_list = []
- for state, name in info:
- if name.startswith(what) and (saveint(state) > 0 or what == "Power"):
+ for presence, state, name in info:
+ if name.startswith(what) and presence != "6" and (saveint(state) > 0 or what == "Power"):
sensor_id = name.split('#')[-1]
return_list.append([sensor_id, name, state])
return return_list
@@ -47,16 +47,20 @@ def brocade_scan(oid):
oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.24.1.1588.2.1.1") or \
oid(".1.3.6.1.2.1.1.2.0").startswith(".1.3.6.1.4.1.1588.2.2.1")
-brocade_info = ('.1.3.6.1.4.1.1588.2.1.1.1.1.22.1', [ 4, 5 ])
+brocade_info = ('.1.3.6.1.4.1.1588.2.1.1.1.1.22.1', [
+ 3, # swSensorStatus, 6 = absent
+ 4, # swSensorValue, -2147483648 = unknown
+ 5, # swSensorInfo
+ ])
brocade_fan_default_levels = { "lower": (3000 , 2800 ) }
def inventory_brocade_fan(info):
- info = brocade_sensor_convert(info, "FAN")
- return [ (x[0], 'brocade_fan_default_levels') for x in info ]
+ converted = brocade_sensor_convert(info, "FAN")
+ return [ (x[0], 'brocade_fan_default_levels') for x in converted ]
def check_brocade_fan(item, params, info):
- info = brocade_sensor_convert(info, "FAN")
+ converted = brocade_sensor_convert(info, "FAN")
if type(params) is tuple: # old format
warn, crit = params
else: # new format
@@ -66,7 +70,7 @@ def check_brocade_fan(item, params, info):
else:
upperwarn, uppercrit = ( None, None )
- for snmp_item, name, value in info:
+ for snmp_item, name, value in converted:
if item == snmp_item:
state = 0
label = ""
@@ -98,12 +102,12 @@ check_info["brocade.fan"] = {
}
def inventory_brocade_power(info):
- info = brocade_sensor_convert(info, "Power")
- return [ (x[0], None) for x in info ]
+ converted = brocade_sensor_convert(info, "Power")
+ return [ (x[0], None) for x in converted ]
def check_brocade_power(item, _no_params, info):
- info = brocade_sensor_convert(info, "Power")
- for snmp_item, name, value in info:
+ converted = brocade_sensor_convert(info, "Power")
+ for snmp_item, name, value in converted:
if item == snmp_item:
value = saveint(value)
if value != 1:
@@ -124,13 +128,13 @@ check_info["brocade.power"] = {
brocade_temp_default_levels = ( 30, 40 )
def inventory_brocade_temp(info):
- info = brocade_sensor_convert(info, "SLOT")
- return [ (x[0], 'brocade_temp_default_levels') for x in info ]
+ converted = brocade_sensor_convert(info, "SLOT")
+ return [ (x[0], 'brocade_temp_default_levels') for x in converted ]
def check_brocade_temp(item, params, info):
- info = brocade_sensor_convert(info, "SLOT")
+ converted = brocade_sensor_convert(info, "SLOT")
warn, crit = params
- for snmp_item, name, value in info:
+ for snmp_item, name, value in converted:
if item == snmp_item:
state = 0
label = ""
Module: check_mk
Branch: master
Commit: 2b3b5bfa00f50d57ef517bdd34c87f05a36fce3b
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=2b3b5bfa00f50d…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Wed Jun 4 17:59:14 2014 +0200
New button for updating DNS cache
In the host details page in WATO there is now a new button <i>Update DNS Cache</i>. If you
press this button, then all cached IP addresses of hosts on the same site as the host currently
edited are being updated.
Use this button when you have not specified an explicit address for a host and that host's
IP address has been changed in your DNS (and you are not willing to wait for the next
regular update).
---
.werks/987 | 14 ++++++++++++++
ChangeLog | 1 +
modules/automation.py | 7 +++++++
modules/check_mk.py | 8 +++++++-
web/htdocs/images/icon_update.png | Bin 0 -> 4229 bytes
web/htdocs/wato.py | 20 ++++++++++++++++++++
6 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/.werks/987 b/.werks/987
new file mode 100644
index 0000000..1151540
--- /dev/null
+++ b/.werks/987
@@ -0,0 +1,14 @@
+Title: New button for updating DNS cache
+Level: 2
+Component: wato
+Version: 1.2.5i4
+Date: 1401897453
+Class: feature
+
+In the host details page in WATO there is now a new button <i>Update DNS Cache</i>. If you
+press this button, then all cached IP addresses of hosts on the same site as the host currently
+edited are being updated.
+
+Use this button when you have not specified an explicit address for a host and that host's
+IP address has been changed in your DNS (and you are not willing to wait for the next
+regular update).
diff --git a/ChangeLog b/ChangeLog
index b836162..70642b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -7,6 +7,7 @@
* 0934 FIX: Logwatch messages with class unknown ( 'u' ) now displayed as WARN...
WATO:
+ * 0987 New button for updating DNS cache...
* 0813 FIX: LDAP: Improved slightly missleading logging of LDAP sync actions...
Reporting & Availability:
diff --git a/modules/automation.py b/modules/automation.py
index baa99cc..e0eca6c 100644
--- a/modules/automation.py
+++ b/modules/automation.py
@@ -43,6 +43,9 @@ def do_automation(cmd, args):
result = automation_delete_host(args)
elif cmd == "notification-get-bulks":
result = automation_get_bulks(args)
+ elif cmd == "update-dns-cache":
+ read_config_files(with_autochecks=False)
+ result = automation_update_dns_cache()
else:
read_config_files()
if cmd == "try-inventory":
@@ -1379,3 +1382,7 @@ def execute_check_plugin(commandline):
raise
return 3, "UNKNOWN - Cannot execute command: %s" % e
+
+def automation_update_dns_cache():
+ return do_update_dns_cache()
+
diff --git a/modules/check_mk.py b/modules/check_mk.py
index 796c34b..5380079 100755
--- a/modules/check_mk.py
+++ b/modules/check_mk.py
@@ -1287,6 +1287,8 @@ def do_update_dns_cache():
# Temporarily disable *use* of cache, we want to force an update
global use_dns_cache
use_dns_cache = False
+ updated = 0
+ failed = []
if opt_verbose:
print "Updating DNS cache..."
@@ -1298,14 +1300,18 @@ def do_update_dns_cache():
# with statically configured addresses, etc.
try:
ip = lookup_ipaddress(hostname)
- sys.stdout.write("%s\n" % ip)
+ if opt_verbose:
+ sys.stdout.write("%s\n" % ip)
+ updated += 1
except Exception, e:
+ failed.append(hostname)
if opt_verbose:
sys.stdout.write("lookup failed: %s\n" % e)
if opt_debug:
raise
continue
+ return updated, failed
def agent_port_of(hostname):
ports = host_extra_conf(hostname, agent_ports)
diff --git a/web/htdocs/images/icon_update.png b/web/htdocs/images/icon_update.png
new file mode 100644
index 0000000..248f614
Binary files /dev/null and b/web/htdocs/images/icon_update.png differ
diff --git a/web/htdocs/wato.py b/web/htdocs/wato.py
index 97a8e1c..04ec06d 100644
--- a/web/htdocs/wato.py
+++ b/web/htdocs/wato.py
@@ -2047,8 +2047,22 @@ def mode_edithost(phase, new, cluster):
if not cluster:
html.context_button(_("Diagnostic"),
make_link([("mode", "diag_host"), ("host", hostname)]), "diagnose")
+ html.context_button(_("Update DNS Cache"),
+ html.makeactionuri([("_update_dns_cache", "1")]), "update")
elif phase == "action":
+ if html.var("_update_dns_cache"):
+ if html.check_transaction():
+ config.need_permission("wato.update_dns_cache")
+ num_updated, failed_hosts = check_mk_automation(host[".siteid"], "update-dns-cache", [])
+ infotext = _("Successfully updated IP addresses of %d hosts.") % num_updated
+ if failed_hosts:
+ infotext += "<br><br><b>Hostnames failed to lookup:</b> " + ", ".join(["<tt>%s</tt>" % h for h in failed_hosts])
+ return None, infotext
+ else:
+ return None
+
+
if not new and html.var("delete"): # Delete this host
config.need_permission("wato.manage_hosts")
check_folder_permissions(g_folder, "write")
@@ -17434,6 +17448,12 @@ def load_plugins():
"hosts and thus simulate larger environments."),
[ ])
+ config.declare_permission("wato.update_dns_cache",
+ _("Update DNS Cache"),
+ _("Updating the DNS cache is neccessary in order to reflect IP address "
+ "changes in hosts that are configured without an explicit address."),
+ [ "admin", "user" ])
+
config.declare_permission("wato.services",
_("Manage services"),
_("Do inventory and service configuration on existing hosts."),