From bee9f1ffe9e1586beda00e96d9e3da6171b3ab89 Mon Sep 17 00:00:00 2001 From: Ramesh Nachimuthu Date: Tue, 22 Apr 2014 16:45:57 +0530 Subject: autoconf: use host name for host config Discover the host name configured for the gluster node and use the same as host_name in nagios host configuration. Change-Id: Ib9eb8b3f3a1a03d1be28fa2faba44c2fc81fa0cf Signed-off-by: Ramesh Nachimuthu --- config/gluster-host.cfg.template | 4 +- plugins/config_generator.py | 19 ++++----- plugins/discovery.py | 83 +++++++++++++++++--------------------- plugins/submit_external_command.py | 10 ++--- tests/Makefile.am | 1 + tests/test_config_generator.py | 19 +++++---- tests/test_discovery.py | 82 +++++++++++++++++++++++++++++++++++++ 7 files changed, 150 insertions(+), 68 deletions(-) create mode 100644 tests/test_discovery.py diff --git a/config/gluster-host.cfg.template b/config/gluster-host.cfg.template index bd1b2af..0b5173d 100644 --- a/config/gluster-host.cfg.template +++ b/config/gluster-host.cfg.template @@ -17,10 +17,10 @@ use {{host['use']}} host_name {{host['host_name']}} alias {{host['alias']}} address {{host['address']}} -{% if host['check_command'] != "" -%} +{% if host['check_command'] is defined -%} check_command {{host['check_command']}} {% endif -%} -{% if host['hostgroups'] != "" -%} +{% if host['hostgroups'] is defined -%} hostgroups {{host['hostgroups']}} {% endif -%} } diff --git a/plugins/config_generator.py b/plugins/config_generator.py index bf18cf1..2bfffdf 100644 --- a/plugins/config_generator.py +++ b/plugins/config_generator.py @@ -48,12 +48,12 @@ class GlusterNagiosConfManager: host['alias'] = alias host['use'] = template host['address'] = address - if checkCommand is not None: + if checkCommand: host['check_command'] = checkCommand - if hostGroups is not None: + if hostGroups: host['hostgroups'] = hostGroups - if services is not None: + if services: host['host_services'] = services return host @@ -143,7 +143,8 @@ class GlusterNagiosConfManager: brickService = {} brickService['use'] = 'gluster-brick-passive-service' brickService['host_name'] = hostName - serviceDesc = "Brick Status - %s:%s" % (hostName, brick['brickpath']) + serviceDesc = "Brick Status - %s:%s" % (hostName, + brick['brickpath']) brickService['service_description'] = serviceDesc brickService['_BRICK_DIR'] = brick['brickpath'] brickService['_VOL_NAME'] = brick['volumeName'] @@ -154,10 +155,10 @@ class GlusterNagiosConfManager: brickServices = [] for brick in host['bricks']: brickService = self.__createBrickUtilizationService( - brick, host['hostip']) + brick, host['hostname']) brickServices.append(brickService) brickService = self.__createBrickStatusService( - brick, host['hostip']) + brick, host['hostname']) brickServices.append(brickService) return brickServices @@ -173,13 +174,13 @@ class GlusterNagiosConfManager: cluster['name'], cluster['hosts'][-1]['hostip'])) clusterHostConfig = self.createHost( cluster['name'], cluster['name'], "gluster-cluster", - cluster['name'], "", "", clusterServices) + cluster['name'], None, None, clusterServices) hostsConfigs.append(clusterHostConfig) for host in cluster['hosts']: brickServices = self.createBrickServices(host) hostGroups = "gluster_hosts,%s" % (cluster['name']) hostConfig = self.createHost( - host['hostip'], host['hostip'], "gluster-host", + host['hostname'], host['hostname'], "gluster-host", host['hostip'], hostGroups, "", brickServices) hostsConfigs.append(hostConfig) self.generateConfigFiles(hostsConfigs) @@ -205,7 +206,7 @@ class GlusterNagiosConfManager: os.mkdir(confDir) def __writeHostConfig(self, clusterConfigDir, hostConfig): - if clusterConfigDir is None: + if not clusterConfigDir: raise Exception("Cluster configuration directory can't None") configFilePath = clusterConfigDir + "/" + hostConfig['name'] + ".cfg" with open(configFilePath, 'w') as configFile: diff --git a/plugins/discovery.py b/plugins/discovery.py index 2cde3d0..3818a84 100755 --- a/plugins/discovery.py +++ b/plugins/discovery.py @@ -17,72 +17,49 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # import argparse -import commands import json import datetime import sys -from config_generator import GlusterNagiosConfManager from glusternagios import utils - +from config_generator import GlusterNagiosConfManager from constants import DEFAULT_AUTO_CONFIG_DIR from constants import HOST_TEMPLATE_DIR from constants import HOST_TEMPLATE_NAME from constants import NRPE_PATH -from constants import NAGIOS_COMMAND_FILE_PATH +import submit_external_command serviceCmdPath = utils.CommandPath("service", "/sbin/service", ) +nrpeCmdPath = utils.CommandPath("nrpe", NRPE_PATH, ) -def excecNRPECommand(command): - """ - This function executes NRPE command and return the result - """ - status = commands.getoutput(command) - return status - - -def discoverhostdetails(host, args): - hostparamsdict = {} - command = NRPE_PATH + " -H " + host + " -c discoverhostparams" - hostparams = excecNRPECommand(command) +def excecNRPECommand(host, command): + output = {} + (returncode, outputStr, err) = utils.execCmd([nrpeCmdPath.cmd, + "-H", host, "-c", command]) #convert to dictionary try: - hostparamsdict = json.loads(hostparams) - except Exception, e: - e.args += (hostparams,) - raise - return hostparamsdict - - -def discoverlogicalcomponents(host): - componentlist = [] - command = NRPE_PATH + " -H " + host + " -c discoverlogicalcomponents" - components = excecNRPECommand(command) - try: - componentlist = json.loads(components) - except Exception, e: - e.args += (components,) - #print e.args + output = json.loads(outputStr[0]) + except Exception as e: + e.args += (outputStr[0]) raise - return componentlist + return output -def discovercluster(args): +def discoverCluster(hostip, cluster): clusterdata = {} #Discover the logical components - componentlist = discoverlogicalcomponents(args.hostip) + componentlist = excecNRPECommand(hostip, "discoverlogicalcomponents") #Discover the peers - command = NRPE_PATH + " -H " + args.hostip + " -c discoverpeers" - hosts = excecNRPECommand(command) - hostlist = json.loads(hosts) - + hostlist = excecNRPECommand(hostip, "discoverpeers") #Add the ip address of the root node to the peer list #to generate the configuration - hostlist.append({"hostip": args.hostip}) + hostlist.append({"hostip": hostip}) for host in hostlist: - #host.update(discoverhostdetails(host['hostip'], args)) + #Get host names + hostDetails = excecNRPECommand(host['hostip'], "discoverhostparams") + host.update(hostDetails) #Get the list of bricks for this host and add to dictionary host['bricks'] = [] for volume in componentlist['volumes']: @@ -92,10 +69,27 @@ def discovercluster(args): host['bricks'].append(brick) clusterdata['hosts'] = hostlist clusterdata['volumes'] = componentlist['volumes'] - clusterdata['name'] = args.cluster + clusterdata['name'] = cluster + if not isHostsNamesUnique(clusterdata): + setHostNameWithIP(clusterdata) return clusterdata +def setHostNameWithIP(clusterdata): + for host in clusterdata['hosts']: + host['hostname'] = host['hostip'] + + +def isHostsNamesUnique(clusterdata): + hostnames = {} + for host in clusterdata['hosts']: + if hostnames.get(host['hostname']) is None: + hostnames[host['hostname']] = host['hostip'] + else: + return False + return True + + def parse_input(): parser = argparse.ArgumentParser(description="Gluster Auto Discover Tool") parser.add_argument('-c', '--cluster', action='store', dest='cluster', @@ -122,8 +116,7 @@ def getConfigManager(args): def _restartNagios(): now = datetime.datetime.now() cmdStr = "[%s] RESTART_PROGRAM\n" % (now) - with open(NAGIOS_COMMAND_FILE_PATH, "w") as f: - f.write(cmdStr) + submit_external_command.submitExternalCommand(cmdStr) def _isNagiosRunning(): @@ -136,7 +129,7 @@ def _isNagiosRunning(): if __name__ == '__main__': args = parse_input() - clusterdata = discovercluster(args) + clusterdata = discoverCluster(args.hostip, args.cluster) configManager = getConfigManager(args) clusterConfing = configManager.generateNagiosConfigFromGlusterCluster( clusterdata) diff --git a/plugins/submit_external_command.py b/plugins/submit_external_command.py index 876c6b5..3cbd51c 100755 --- a/plugins/submit_external_command.py +++ b/plugins/submit_external_command.py @@ -41,15 +41,15 @@ def parse_input(): return args -def _submitExternalCommand(command, hostname, service, dateTime): - cmdStr = "[%s] %s;%s;%s;%s\n" % (dateTime, command, - hostname, service, dateTime) +def submitExternalCommand(cmdStr): with open(NAGIOS_COMMAND_FILE_PATH, "w") as f: f.write(cmdStr) if __name__ == '__main__': args = parse_input() - _submitExternalCommand(args.command, args.hostName, - args.service, args.dateTime) + cmdStr = "[%s] %s;%s;%s;%s\n" % (args.dateTime, args.command, + args.hostName, args.service, + args.dateTime) + submitExternalCommand(cmdStr) sys.exit(utils.PluginStatusCode.OK) diff --git a/tests/Makefile.am b/tests/Makefile.am index 9e860b7..be571d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -23,6 +23,7 @@ test_modules = \ test_check_remote_host.py \ test_notify_ovirt_engine_handler.py \ test_config_generator.py \ + test_discovery.py $(NULL) dist_nagiosserveraddonstests_DATA = \ diff --git a/tests/test_config_generator.py b/tests/test_config_generator.py index 891bcbc..6fe62d3 100644 --- a/tests/test_config_generator.py +++ b/tests/test_config_generator.py @@ -41,8 +41,8 @@ class TestGlusterNagiosConfManager(TestCaseBase): clusterData['hosts'][index]) def __verifyHostConfig(self, hostConfig, hostData): - self.assertEqual(hostConfig['host_name'], hostData['hostip']) - self.assertEqual(hostConfig['alias'], hostData['hostip']) + self.assertEqual(hostConfig['host_name'], hostData['hostname']) + self.assertEqual(hostConfig['alias'], hostData['hostname']) self.assertEqual(hostConfig['address'], hostData['hostip']) self.assertEqual(hostConfig['use'], 'gluster-host') @@ -50,23 +50,28 @@ class TestGlusterNagiosConfManager(TestCaseBase): self.assertEqual(config['host_name'], clusterData['name']) self.assertEqual(config['alias'], clusterData['name']) self.assertEqual(config['address'], clusterData['name']) - self.assertEqual(config['check_command'], "") + self.assertEqual(config.get('check_command'), None) self.assertEqual(config['use'], 'gluster-cluster') - def createBricks(self, count, volume): + def createBricks(self, count, volume, hostip): bricks = [] for number in range(count): brickDir = "/mnt/Brick-%s" % (number + 1) bricks.append({'brickpath': brickDir, - 'volumeName': volume}) + 'volumeName': volume, + 'hostip': hostip}) return bricks def __createDummyCluster(self): cluster = {'name': 'Test-Cluster', 'hosts': [], 'volumes': []} cluster['hosts'].append({'hostip': '10.70.43.1', - 'bricks': self.createBricks(1, "Volume1")}) + 'hostname': 'host-1', + 'bricks': self.createBricks(1, "Volume1", + '10.70.43.1')}) cluster['hosts'].append({'hostip': '10.70.43.2', - 'bricks': self.createBricks(2, "Volume1")}) + 'hostname': 'host-2', + 'bricks': self.createBricks(2, "Volume1", + '10.70.43.2')}) cluster['volumes'].append({'name': 'Volume1', "type": "T"}) return cluster diff --git a/tests/test_discovery.py b/tests/test_discovery.py new file mode 100644 index 0000000..0443cde --- /dev/null +++ b/tests/test_discovery.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +# 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 +# + +import mock +from plugins import discovery +from testrunner import PluginsTestCase as TestCaseBase + + +class TestDiscovery(TestCaseBase): + def _mockExcecNRPECommand(self, host, command): + if command == "discoverlogicalcomponents": + return self._getLogicalComponents() + elif command == "discoverpeers": + return self._getPeers() + elif command == "discoverhostparams": + return self._getHostParams(host) + + def _getLogicalComponents(self): + result = {} + result['volumes'] = [] + result['volumes'].append({"bricks": [{"brickpath": "/bricks/v1-1", + "hostUuid": "0000-1111", + "hostip": "172.16.53.1"}], + "type": "DISTRIBUTE", "name": "V1"}) + result['volumes'].append({"bricks": [{"brickpath": "/bricks/v2-1", + "hostUuid": "0000-1112", + "hostip": "172.16.53.2"}], + "type": "DISTRIBUTE", "name": "V2"}) + return result + + def _getPeers(self): + result = [] + result.append({"hostip": "172.16.53.2"}) + return result + + def _getHostParams(self, hostip): + if hostip == "172.16.53.1": + return {"hostname": "node-1"} + elif hostip == "172.16.53.2": + return {"hostname": "node-2"} + + def _verifyClusterData(self, clusterdata, clusterName, host): + + self.assertEqual(clusterdata['hosts'][0]['hostip'], + self._getPeers()[0]['hostip']) + self.assertEqual(clusterdata['hosts'][1]['hostip'], host) + for host in clusterdata['hosts']: + hostDetails = self._getHostParams(host['hostip']) + self.assertEqual(host['hostname'], hostDetails['hostname']) + self.assertEqual(len(host['bricks']), 1) + volumes = self._getLogicalComponents()['volumes'] + self.assertEqual(len(clusterdata['volumes']), len(volumes)) + + for i in range(len(volumes)): + self._verifyVolume(volumes[i], clusterdata['volumes'][i]) + + def _verifyVolume(self, expected, actual): + self.assertEqual(expected['name'], actual['name']) + self.assertEqual(expected['type'], actual['type']) + + # Method to test the discoverCluster() method + def testDiscoverCluster(self): + discovery.excecNRPECommand = self._mockExcecNRPECommand + clusterName = "test-cluster" + host = "172.16.53.1" + clusterdata = discovery.discoverCluster(host, clusterName) + self._verifyClusterData(clusterdata, clusterName, host) -- cgit