diff options
author | Shubhendu Tripathi <shtripat@redhat.com> | 2014-03-21 13:53:46 +0530 |
---|---|---|
committer | Bala.FA <barumuga@redhat.com> | 2014-04-29 10:21:37 +0530 |
commit | 26b98e7239222704bb7438bcc47793fc6be60f2c (patch) | |
tree | b2f62a1188a44cd5337c711e1d8b5a04b98e3b90 | |
parent | 81cc690fbe74f15e73c30079ea4bff1c37fefa3f (diff) |
nagios-server-addons: Test case for host event handler
Added unit test cases for host event handler with minor
code fixes
Change-Id: Id9516303aaa1e4f14e781a06d4f73158bfcdebf4
Signed-off-by: Shubhendu Tripathi <shtripat@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/21669
Reviewed-by: Darshan Narayana Murthy <dnarayan@redhat.com>
Reviewed-by: Sahina Bose <sabose@redhat.com>
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | plugins/Makefile.am | 3 | ||||
-rwxr-xr-x | plugins/check_remote_host.py.in (renamed from plugins/check_remote_host.py) | 51 | ||||
-rwxr-xr-x | plugins/gluster_host_service_handler.py | 145 | ||||
-rwxr-xr-x | plugins/gluster_host_service_handler.py.in | 140 | ||||
-rw-r--r-- | tests/test_gluster_host_service_handler.py | 89 |
6 files changed, 255 insertions, 177 deletions
diff --git a/configure.ac b/configure.ac index 661dfd9..e9067e1 100644 --- a/configure.ac +++ b/configure.ac @@ -54,6 +54,8 @@ AC_SUBST([glusternagiospluginsdir], ['${nagiospluginsdir}/gluster']) AC_SUBST([glusternagioscommonpylibdir], ['${pyexecdir}/glusternagios']) AC_SUBST([nagiosserveraddonstestsdir], ['${datarootdir}/${PACKAGE_NAME}/tests']) AC_SUBST([nagioslivestatussocketpath], ['/var/spool/nagios/cmd/live']) +AC_SUBST([nagioscommandfilepath], ['/var/spool/nagios/cmd/nagios.cmd']) +AC_SUBST([hostmonitoringserviceslist], ['/etc/nagios/gluster/host-monitoring-services.in']) # Checking for pyflakes AC_PATH_PROG([PYFLAKES], [pyflakes]) @@ -94,7 +96,9 @@ AC_CONFIG_FILES([ Makefile nagios-server-addons.spec config/Makefile + plugins/check_remote_host.py plugins/constants.py + plugins/gluster_host_service_handler.py plugins/Makefile templates/Makefile tests/Makefile diff --git a/plugins/Makefile.am b/plugins/Makefile.am index b7917ec..ef199f0 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -2,10 +2,11 @@ dist_glusternagiosplugins_PYTHON = \ constants.py \ check_cluster_vol_usage.py \ check_remote_host.py \ + check_vol_utilization_server.py \ gluster_host_service_handler.py \ livestatus.py \ notify_ovirt_engine_handler.py \ - check_vol_utilization_server.py \ + server_utils.py \ $(NULL) EXTRA_DIST = \ diff --git a/plugins/check_remote_host.py b/plugins/check_remote_host.py.in index 6f540df..0ef101e 100755 --- a/plugins/check_remote_host.py +++ b/plugins/check_remote_host.py.in @@ -30,25 +30,10 @@ import os import sys import getopt -#import socket import json import livestatus - -STATUS_OK = 0 -STATUS_WARNING = 1 -STATUS_CRITICAL = 2 -STATUS_UNKNOWN = 3 -_commandStatusStrs = {STATUS_OK: 'OK', STATUS_WARNING: 'WARNING', - STATUS_CRITICAL: 'CRITICAL', STATUS_UNKNOWN: 'UNKNOWN'} - - -# Load the host monitoring services list -def loadSrvcList(): - srvc_list = [] - with open("/etc/nagios/gluster/host-monitoring-services.in") as data_file: - srvc_list = json.load(data_file)['serviceList'] - return srvc_list +from glusternagios import utils # Method to execute livestatus @@ -62,7 +47,14 @@ def checkLiveStatus(hostAddr, srvc): if len(table) > 0 and len(table[0]) > 0: return int(table[0][0]) else: - return STATUS_UNKNOWN + return utils.PluginStatusCode.UNKNOWN + + +def _getHostMonitoringSrvcList(): + srvc_list = [] + with open("@hostmonitoringserviceslist@") as data_file: + srvc_list = json.load(data_file)['serviceList'] + return srvc_list # Method to show the usage @@ -78,12 +70,12 @@ if __name__ == "__main__": except getopt.GetoptError as e: print (str(e)) showUsage() - sys.exit(STATUS_CRITICAL) + sys.exit(utils.PluginStatusCode.CRITICAL) hostAddr = '' if len(opts) == 0: showUsage() - sys.exit(STATUS_CRITICAL) + sys.exit(utils.PluginStatusCode.CRITICAL) else: for opt, arg in opts: if opt in ("-h", "--help"): @@ -93,27 +85,24 @@ if __name__ == "__main__": hostAddr = arg else: showUsage() - sys.exit(STATUS_CRITICAL) - - # Load the services list - srvc_list = loadSrvcList() + sys.exit(utils.PluginStatusCode.CRITICAL) # Calculate the consolidated status for the host based on above # status of individual services - finalStatus = STATUS_OK + finalStatus = utils.PluginStatusCode.OK criticalSrvcs = [] - for srvc in srvc_list: + for srvc in _getHostMonitoringSrvcList(): srvc_status = checkLiveStatus(hostAddr, srvc) finalStatus = finalStatus | srvc_status - if srvc_status == STATUS_CRITICAL: + if srvc_status == utils.PluginStatusCode.CRITICAL: criticalSrvcs.append(str(srvc)) # Return the status - if finalStatus == STATUS_CRITICAL: + if finalStatus == utils.PluginStatusCode.CRITICAL: print "Host Status %s - Service(s) %s in CRITICAL state" % \ - (_commandStatusStrs[STATUS_WARNING], criticalSrvcs) - sys.exit(STATUS_WARNING) + (utils.PluginStatus.WARNING, criticalSrvcs) + sys.exit(utils.PluginStatusCode.WARNING) print "Host Status %s - Services in good health" % \ - _commandStatusStrs[STATUS_OK] - sys.exit(STATUS_OK) + utils.PluginStatus.OK + sys.exit(utils.PluginStatusCode.OK) diff --git a/plugins/gluster_host_service_handler.py b/plugins/gluster_host_service_handler.py deleted file mode 100755 index 2a62108..0000000 --- a/plugins/gluster_host_service_handler.py +++ /dev/null @@ -1,145 +0,0 @@ -#!/usr/bin/python -# -# gluster_host_service_handler.py -- Event handler which checks the -# status of defined services and accordingly changes the host status -# -# Copyright (C) 2014 Red Hat Inc -# -# This program 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; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA -# - -import os -import sys -import datetime -import getopt - -import livestatus - -STATUS_OK = "OK" -STATUS_WARNING = "WARNING" -STATUS_CRITICAL = "CRITICAL" -STATUS_UNKNOWN = "UNKNOWN" -SRVC_STATE_TYPE_SOFT = "SOFT" -SRVC_STATE_TYPE_HARD = "HARD" -statusCodes = {STATUS_OK: 0, STATUS_WARNING: 1, STATUS_CRITICAL: 2, - STATUS_UNKNOWN: 3} -NAGIOS_COMMAND_FILE = "/var/spool/nagios/cmd/nagios.cmd" -SRVC_LIST = ['Disk Utilization', 'Cpu Utilization', 'Memory Utilization', - 'Swap Utilization', 'Network Utilization'] - - -# Shows the usage of the script -def showUsage(): - usage = "Usage: %s -s <Service State (OK/WARNING/CRITICAL/UNKNOWN)> " \ - "-t <Service State Type (SOFT/HARD)>" \ - " -a <No of Service attempts> " \ - "-l <Host Address>" \ - " -n <Service Name>\n" % os.path.basename(sys.argv[0]) - sys.stderr.write(usage) - - -# Method to change the host status -def update_host_state(hostAddr, srvcName, statusCode): - now = datetime.datetime.now() - if statusCode == statusCodes[STATUS_WARNING]: - cmdStr = "[%s] PROCESS_HOST_CHECK_RESULT;%s;%s;" \ - "Host Status WARNING - " \ - "Service(s) ['%s'] in CRITICAL state\n" \ - % (now, hostAddr, statusCode, srvcName) - else: - cmdStr = "[%s] PROCESS_HOST_CHECK_RESULT;%s;%s;Host Status OK - " \ - "Services in good health\n" % (now, hostAddr, statusCode) - - f = open(NAGIOS_COMMAND_FILE, "w") - f.write(cmdStr) - f.close() - - -# Method to execute livestatus -def checkLiveStatus(hostAddr, srvc): - cmd = "GET services\nColumns: state\nFilter: " \ - "description = %s\nFilter: host_address = %s" % (srvc, hostAddr) - - table = livestatus.readLiveStatus(cmd) - - if len(table) > 0 and len(table[0]) > 0: - return int(table[0][0]) - else: - return statusCodes[STATUS_UNKNOWN] - - -# Method to change the host state to UP based on other service type status -def check_and_update_host_state_to_up(hostAddr, srvcName): - finalState = 0 - for item in SRVC_LIST: - if item != srvcName: - finalState = finalState | checkLiveStatus(hostAddr, item) - - if finalState == statusCodes[STATUS_OK]: - update_host_state(hostAddr, srvcName, statusCodes[STATUS_OK]) - - -# Main method -if __name__ == "__main__": - try: - opts, args = getopt.getopt(sys.argv[1:], "hs:t:a:l:n:", - ["help", "state=", "type=", - "attempts=", "location=", "name="]) - except getopt.GetoptError as e: - print (str(e)) - showUsage() - sys.exit(STATUS_CRITICAL) - - srvcState = '' - srvcStateType = '' - attempts = '' - hostAddr = '' - srvcName = '' - if len(opts) == 0: - showUsage() - else: - for opt, arg in opts: - if opt in ('-h', '--help'): - showUsage() - sys.exit() - elif opt in ('-s', '--state'): - srvcState = arg - elif opt in ('-t', '--type'): - srvcStateType = arg - elif opt in ('-a', '--attempts'): - attempts = arg - elif opt in ('-l', '--location'): - hostAddr = arg - elif opt in ('-n', '--name'): - srvcName = arg - else: - showUsage() - sys.exit() - - # Swicth over the service state values and do the needful - if srvcState == STATUS_CRITICAL: - if srvcStateType == SRVC_STATE_TYPE_SOFT: - if int(attempts) == 3: - print "Updating the host status to warning " \ - "(3rd SOFT critical state)..." - update_host_state(hostAddr, srvcName, - statusCodes[STATUS_WARNING]) - elif srvcStateType == SRVC_STATE_TYPE_HARD: - print "Updating the host status to warning..." - update_host_state(hostAddr, srvcName, statusCodes[STATUS_WARNING]) - elif srvcState == STATUS_OK: - check_and_update_host_state_to_up(hostAddr, srvcName) - - sys.exit(0) diff --git a/plugins/gluster_host_service_handler.py.in b/plugins/gluster_host_service_handler.py.in new file mode 100755 index 0000000..2d5bff0 --- /dev/null +++ b/plugins/gluster_host_service_handler.py.in @@ -0,0 +1,140 @@ +#!/usr/bin/python +# +# gluster_host_service_handler.py -- Event handler which checks the +# status of defined services and accordingly changes the host status +# +# Copyright (C) 2014 Red Hat Inc +# +# This program 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; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,USA +# + +import os +import sys +import datetime +import argparse + +import livestatus +from glusternagios import utils + +SRVC_STATE_TYPE_SOFT = "SOFT" +SRVC_STATE_TYPE_HARD = "HARD" + + +def _writeNagiosCommand(cmdStr): + with open("@nagioscommandfilepath@", "w") as f: + f.write(cmdStr) + + +# Method to change the host status +def update_host_state(hostAddr, srvcName, statusCode): + now = datetime.datetime.now() + if statusCode == utils.PluginStatusCode.WARNING: + cmdStr = "[%s] PROCESS_HOST_CHECK_RESULT;%s;%s;" \ + "Host Status WARNING - " \ + "Service(s) ['%s'] in CRITICAL state\n" \ + % (now, hostAddr, statusCode, srvcName) + else: + cmdStr = "[%s] PROCESS_HOST_CHECK_RESULT;%s;%s;Host Status OK - " \ + "Services in good health\n" % (now, hostAddr, statusCode) + + _writeNagiosCommand(cmdStr) + + +# Method to execute livestatus +def checkLiveStatus(hostAddr, srvc): + cmd = "GET services\nColumns: state\nFilter: " \ + "description = %s\nFilter: host_address = %s" % (srvc, hostAddr) + + table = livestatus.readLiveStatus(cmd) + + if len(table) > 0 and len(table[0]) > 0: + return int(table[0][0]) + else: + return utils.PluginStatusCode.UNKNOWN + + +def _getHostMonitoringSrvcList(): + srvc_list = [] + with open("@hostmonitoringserviceslist@") as data_file: + srvc_list = json.load(data_file)['serviceList'] + return srvc_list + + +# Method to change the host state to UP based on other service type status +def check_and_update_host_state_to_up(hostAddr, srvcName): + finalState = utils.PluginStatusCode.OK + for item in _getHostMonitoringSrvcList(): + if item != srvcName: + finalState = finalState | checkLiveStatus(hostAddr, item) + + if finalState == utils.PluginStatusCode.OK: + update_host_state(hostAddr, srvcName, utils.PluginStatusCode.OK) + + +# Main method +if __name__ == "__main__": + parser = argparse.ArgumentParser( + usage='%(prog)s -s <State> -t <State Type>' + ' -a <No of attempts> -l <Host Address>' + ' -n <Service Name>') + parser.add_argument( + "-s", + "--state", + action="store", + required=True, + type=str, + help="Current State of the service (CRITICAL/WARNING/OK/UNKNOWN)") + parser.add_argument( + "-t" + "--statetype", + action="store", + required=True, + type=str, + help="State Type of the service (SOFT/HARD)") + parser.add_argument( + "-a", + "--attempts", + action="store", + required=True, + type=int, + help="No of attempts") + parser.add_argument( + "-l", + "--location", + action="store", + required=True, + type=str, + help="Address of the host") + parser.add_argument( + "-n", + "--name", + action="store", + required=True, + type=str, + help="Service Name") + + args = parser.parse_args() + + # Swicth over the service state values and update state + if args.state == utils.PluginStatus.CRITICAL \ + and args.t__statetype == SRVC_STATE_TYPE_HARD: + print "Updating the host status to warning..." + update_host_state(args.location, + args.name, + utils.PluginStatusCode.WARNING) + elif args.state == utils.PluginStatusCode.OK: + check_and_update_host_state_to_up(args.location, args.name) + + sys.exit(utils.PluginStatusCode.OK) diff --git a/tests/test_gluster_host_service_handler.py b/tests/test_gluster_host_service_handler.py new file mode 100644 index 0000000..9c36f19 --- /dev/null +++ b/tests/test_gluster_host_service_handler.py @@ -0,0 +1,89 @@ +# +# Copyright 2014 Red Hat, Inc. +# +# This program 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; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# Refer to the README and COPYING files for full details of the license +# + +import mock + +from plugins import gluster_host_service_handler as handler +from testrunner import PluginsTestCase as TestCaseBase + + +class TestGlusterHostServiceHandler(TestCaseBase): + # Method to test the checkLiveStatus() method + @mock.patch('plugins.gluster_host_service_handler.' + 'livestatus.socket.socket') + def testCheckLiveStatus(self, mock_socket): + reference = mock_socket(mock_socket.AF_UNIX, mock_socket.SOCK_STREAM) + self.assertTrue(mock_socket, "called") + reference.recv.return_value = "0\n" + handler.checkLiveStatus("dummy host", "dummy srvc") + reference.connect.assert_called_with('/var/spool/nagios/cmd/live') + reference.send.assert_called_with("GET services\nColumns: state\n" + "Filter: description = dummy srvc\n" + "Filter: host_address = " + "dummy host\n" + "Separators: 10 124 44 59\n") + self.assertEquals(0, handler.checkLiveStatus("dummy host", + "dummy srvc")) + + @mock.patch('plugins.gluster_host_service_handler._writeNagiosCommand') + @mock.patch('plugins.gluster_host_service_handler.datetime') + def testUpdateHostState(self, mock_datetime, mock_write_nagios_cmd): + mock_datetime.datetime.now.return_value = "now" + + handler.update_host_state("dummy host", "dummy srvc", 0) + mock_write_nagios_cmd.assert_called_with("[now] " + "PROCESS_HOST_CHECK_RESULT;" + "dummy host;0;" + "Host Status OK - " + "Services in good health\n") + + handler.update_host_state("dummy host", "dummy srvc", 1) + mock_write_nagios_cmd.assert_called_with("[now] " + "PROCESS_HOST_CHECK_RESULT;" + "dummy host;1;" + "Host Status WARNING - " + "Service(s) [\'dummy srvc\']" + " in CRITICAL state\n") + + handler.update_host_state("dummy host", "dummy srvc", 1) + mock_write_nagios_cmd.assert_called_with("[now] " + "PROCESS_HOST_CHECK_RESULT;" + "dummy host;1;" + "Host Status WARNING - " + "Service(s) [\'dummy srvc\']" + " in CRITICAL state\n") + + @mock.patch('plugins.gluster_host_service_handler.' \ + '_getHostMonitoringSrvcList') + @mock.patch('plugins.gluster_host_service_handler.checkLiveStatus') + @mock.patch('plugins.gluster_host_service_handler.update_host_state') + def testCheckAndUpdateHostStateToUp(self, + mock_update_host_state, + mock_checkLiveStatus, + mock_srvc_list): + mock_checkLiveStatus.return_value = 0 + mock_srvc_list.return_value = [] + + handler.check_and_update_host_state_to_up("dummy host", "dummy srvc") + + self.assertTrue(mock_checkLiveStatus, "called") + mock_update_host_state.assert_called_with("dummy host", + "dummy srvc", + 0) |