Added Compass CLI and health check modules
1. Added comments, removed typos. 2. Updated github urls to stackforge 3. Added setting.py Amend: Run pep8 and fix styling issues. Change-Id: Ice0ba0964207827f683c27734f78b43b6a522392
This commit is contained in:
parent
d2fec0205f
commit
ccefdc1b6f
6
bin/compass
Executable file
6
bin/compass
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import compass.actions.cli as cli
|
||||
|
||||
sys.exit(cli.main())
|
146
compass/actions/cli.py
Normal file
146
compass/actions/cli.py
Normal file
@ -0,0 +1,146 @@
|
||||
"""Compass Command Line Interface"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
from subprocess import Popen
|
||||
|
||||
from compass.actions.health_check import check
|
||||
from compass.utils.util import pretty_print
|
||||
|
||||
ACTION_MAP = {"check": "apache celery dhcp dns hds misc os_installer "
|
||||
"package_installer squid tftp".split(" "),
|
||||
"refresh": "db sync".split(" "),
|
||||
}
|
||||
|
||||
|
||||
class BootCLI:
|
||||
|
||||
def __init__(self):
|
||||
return
|
||||
|
||||
def run(self, args):
|
||||
"""
|
||||
cli takes the commands and calls respective modules
|
||||
"""
|
||||
action = self.get_action(args)
|
||||
if action is None:
|
||||
self.print_help()
|
||||
else:
|
||||
module = self.get_module(action, args)
|
||||
if module == "invalid":
|
||||
self.print_help(action)
|
||||
else:
|
||||
method = "self.run_" + action + "(module)"
|
||||
eval(method)
|
||||
|
||||
def get_action(self, args):
|
||||
"""
|
||||
This method returns an action type.
|
||||
For 'compass check dhcp' command, it will return 'check'.
|
||||
"""
|
||||
if len(args) == 1:
|
||||
return None
|
||||
elif args[1] in ACTION_MAP.keys():
|
||||
return args[1]
|
||||
return None
|
||||
|
||||
def get_module(self, action, args):
|
||||
"""
|
||||
This method returns a module.
|
||||
For 'compass check dhcp' command, it will return 'dhcp'.
|
||||
"""
|
||||
if len(args) <= 2:
|
||||
return None
|
||||
elif args[2] in ACTION_MAP[action]:
|
||||
return args[2]
|
||||
return "invalid"
|
||||
|
||||
def run_check(self, module=None):
|
||||
"""
|
||||
param module default set to None.
|
||||
This provides a flexible sanity check,
|
||||
if parameter module is none. Compass checks all modules.
|
||||
If module specified, Compass will only check such module.
|
||||
|
||||
"""
|
||||
if module is None:
|
||||
pretty_print("Starting: Compass Health Check",
|
||||
"==============================")
|
||||
c = check.BootCheck()
|
||||
res = c.run()
|
||||
self.output_check_result(res)
|
||||
|
||||
else:
|
||||
pretty_print("Checking Module: %s" % module,
|
||||
"============================")
|
||||
c = check.BootCheck()
|
||||
method = "c.check_" + module + "()"
|
||||
res = eval(method)
|
||||
print "\n".join(msg for msg in res[1])
|
||||
|
||||
def output_check_result(self, result):
|
||||
if result == {}:
|
||||
return
|
||||
pretty_print("\n",
|
||||
"===============================",
|
||||
"* Compass Health Check Report *",
|
||||
"===============================")
|
||||
successful = True
|
||||
num = 1
|
||||
for key in result.keys():
|
||||
if result[key][0] == 0:
|
||||
successful = False
|
||||
print "%s" % "\n".join(item for item in result[key][1])
|
||||
|
||||
print "===================="
|
||||
if successful is True:
|
||||
print "Compass Check completes. No problems found, all systems go"
|
||||
else:
|
||||
print "Compass has ERRORS shown above. Please fix them before " \
|
||||
"deploying!"
|
||||
|
||||
def run_refresh(self, action=None):
|
||||
## TODO: replace refresh.sh with refresh.py
|
||||
if action is None:
|
||||
pretty_print("Refreshing Compass...",
|
||||
"=================")
|
||||
Popen(['/opt/compass/bin/refresh.sh'], shell=True)
|
||||
elif action == "db":
|
||||
pretty_print("Refreshing Compass Database...",
|
||||
"===================")
|
||||
Popen(['/opt/compass/bin/manage_db.py createdb'], shell=True)
|
||||
else:
|
||||
pretty_print("Syncing with Installers...",
|
||||
"================")
|
||||
Popen(['/opt/compass/bin/manage_db.py sync_from_installers'],
|
||||
shell=True)
|
||||
|
||||
def print_help(self, module_help=""):
|
||||
if module_help == "":
|
||||
pretty_print("usage\n=====",
|
||||
"compass <refresh|check>",
|
||||
"type 'compass {action} --help' for detailed "
|
||||
"command list")
|
||||
|
||||
elif module_help == "refresh":
|
||||
pretty_print("usage\n=====",
|
||||
"compass refresh [%s]" %
|
||||
"|".join(action for action in ACTION_MAP['refresh']))
|
||||
|
||||
else:
|
||||
pretty_print("usage\n=====",
|
||||
"compass check [%s]" %
|
||||
"|".join(action for action in ACTION_MAP['check']))
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Compass cli entry point
|
||||
"""
|
||||
cli = BootCLI()
|
||||
output = cli.run(sys.argv)
|
||||
return sys.exit(output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
22
compass/actions/health_check/base.py
Normal file
22
compass/actions/health_check/base.py
Normal file
@ -0,0 +1,22 @@
|
||||
"""Base class for Compass Health Check"""
|
||||
|
||||
import compass.utils.setting_wrapper as setting
|
||||
import utils as health_check_utils
|
||||
|
||||
from compass.utils.util import pretty_print
|
||||
|
||||
|
||||
class BaseCheck:
|
||||
|
||||
def __init__(self):
|
||||
self.config = setting
|
||||
self.code = 1
|
||||
self.messages = []
|
||||
self.dist, self.version, self.release = health_check_utils.get_dist()
|
||||
|
||||
def _set_status(self, code, message):
|
||||
self.code = code
|
||||
self.messages.append(message)
|
||||
|
||||
def get_status(self):
|
||||
return (self.code, self.messages)
|
@ -0,0 +1,71 @@
|
||||
"""Main Entry Point of Compass Health Check"""
|
||||
|
||||
import check_apache as apache
|
||||
import check_celery as celery
|
||||
import check_dhcp as dhcp
|
||||
import check_dns as dns
|
||||
import check_hds as hds
|
||||
import check_os_installer as os_installer
|
||||
import check_package_installer as package_installer
|
||||
import check_squid as squid
|
||||
import check_tftp as tftp
|
||||
import check_misc as misc
|
||||
import base
|
||||
|
||||
|
||||
class BootCheck(base.BaseCheck):
|
||||
|
||||
def run(self):
|
||||
status = {}
|
||||
status['apache'] = self.check_apache()
|
||||
status['celery'] = self.check_celery()
|
||||
status['dhcp'] = self.check_dhcp()
|
||||
status['dns'] = self.check_dns()
|
||||
status['hds'] = self.check_hds()
|
||||
status['os_installer'] = self.check_os_installer()
|
||||
status['package_installer'] = self.check_package_installer()
|
||||
status['squid'] = self.check_squid()
|
||||
status['tftp'] = self.check_tftp()
|
||||
status['other'] = self.check_misc()
|
||||
|
||||
return status
|
||||
|
||||
def check_apache(self):
|
||||
checker = apache.ApacheCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_celery(self):
|
||||
checker = celery.CeleryCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_dhcp(self):
|
||||
checker = dhcp.DhcpCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_dns(self):
|
||||
checker = dns.DnsCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_hds(self):
|
||||
checker = hds.HdsCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_os_installer(self):
|
||||
checker = os_installer.OsInstallerCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_package_installer(self):
|
||||
checker = package_installer.PackageInstallerCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_squid(self):
|
||||
checker = squid.SquidCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_tftp(self):
|
||||
checker = tftp.TftpCheck()
|
||||
return checker.run()
|
||||
|
||||
def check_misc(self):
|
||||
checker = misc.MiscCheck()
|
||||
return checker.run()
|
@ -0,0 +1,84 @@
|
||||
"""Health Check module for Apache service"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import commands
|
||||
import urllib2
|
||||
|
||||
from socket import *
|
||||
|
||||
import utils as health_check_utils
|
||||
import base
|
||||
import logging
|
||||
|
||||
|
||||
class ApacheCheck(base.BaseCheck):
|
||||
|
||||
NAME = "Apache Check"
|
||||
|
||||
def run(self):
|
||||
if self.dist in ("centos", "redhat", "fedora", "scientific linux"):
|
||||
apache_service = 'httpd'
|
||||
else:
|
||||
apache_service = 'apache2'
|
||||
self.check_apache_conf(apache_service)
|
||||
print "[Done]"
|
||||
self.check_apache_running(apache_service)
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: Apache health check has completed. "
|
||||
"No problems found, all systems go." % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_apache_conf(self, apache_service):
|
||||
"""
|
||||
Validates if Apache settings.
|
||||
|
||||
:param apache_service : service type of apache, os dependent.
|
||||
e.g. httpd or apache2
|
||||
:type apache_service : string
|
||||
|
||||
"""
|
||||
print "Checking Apache Config......",
|
||||
conf_err_msg = health_check_utils.check_path(
|
||||
self.NAME,
|
||||
"/etc/%s/conf.d/ods-server.conf" % apache_service)
|
||||
if not conf_err_msg == "":
|
||||
self._set_status(0, conf_err_msg)
|
||||
|
||||
wsgi_err_msg = health_check_utils.check_path(
|
||||
self.NAME,
|
||||
'/var/www/compass/compass.wsgi')
|
||||
if not wsgi_err_msg == "":
|
||||
self._set_status(0, wsgi_err_msg)
|
||||
|
||||
return True
|
||||
|
||||
def check_apache_running(self, apache_service):
|
||||
"""Checks if Apache service is running on port 80"""
|
||||
|
||||
print "Checking Apache service......",
|
||||
serv_err_msg = health_check_utils.check_service_running(self.NAME,
|
||||
apache_service)
|
||||
if not serv_err_msg == "":
|
||||
self._set_status(0, serv_err_msg)
|
||||
if 'http' != getservbyport(80):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Apache is not listening on port 80."
|
||||
% self.NAME)
|
||||
try:
|
||||
html = urllib2.urlopen('http://localhost')
|
||||
content = html.geturl()
|
||||
if "http://localhost/ods/ods.html" != content:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Compass web is not redirected by Apache.")
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Apache is not running on Port 80."
|
||||
% self.NAME)
|
||||
|
||||
return True
|
@ -0,0 +1,107 @@
|
||||
"""Health Check module for Celery"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import commands
|
||||
|
||||
import base
|
||||
import utils as health_check_utils
|
||||
from celery.task.control import inspect
|
||||
|
||||
|
||||
class CeleryCheck(base.BaseCheck):
|
||||
|
||||
NAME = "Celery Check"
|
||||
|
||||
def run(self):
|
||||
self.check_compass_celery_setting()
|
||||
print "[Done]"
|
||||
self.check_celery_backend()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append("[%s]Info: Celery health check "
|
||||
"has completed. No problems found, "
|
||||
"all systems go." % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_compass_celery_setting(self):
|
||||
"""Validates Celery settings"""
|
||||
|
||||
print "Checking Celery setting......",
|
||||
SETTING_MAP = {'logfile': 'CELERY_LOGFILE',
|
||||
'configdir': 'CELERYCONFIG_DIR',
|
||||
'configfile': 'CELERYCONFIG_FILE',
|
||||
}
|
||||
|
||||
res = health_check_utils.validate_setting('Celery',
|
||||
self.config,
|
||||
'CELERY_LOGFILE')
|
||||
if res is True:
|
||||
logfile = self.config.CELERY_LOGFILE
|
||||
else:
|
||||
logfile = ""
|
||||
self._set_status(0, res)
|
||||
|
||||
res = health_check_utils.validate_setting('Celery',
|
||||
self.config,
|
||||
'CELERYCONFIG_DIR')
|
||||
if res is True:
|
||||
configdir = self.config.CELERYCONFIG_DIR
|
||||
else:
|
||||
configdir = ""
|
||||
self._set_status(0, res)
|
||||
|
||||
res = health_check_utils.validate_setting('Celery',
|
||||
self.config,
|
||||
'CELERYCONFIG_FILE')
|
||||
if res is True:
|
||||
configfile = self.config.CELERYCONFIG_FILE
|
||||
else:
|
||||
configfile = ""
|
||||
self._set_status(0, res)
|
||||
|
||||
unset = []
|
||||
for item in ['logfile', 'configdir', 'configfile']:
|
||||
if eval(item) == "":
|
||||
unset.append(SETTING_MAP[item])
|
||||
if len(unset) != 0:
|
||||
self._set_status(0,
|
||||
"[%s]Error: Unset celery settings: %s"
|
||||
" in /etc/compass/setting"
|
||||
% (self.NAME, ', '.join(item for item in unset)))
|
||||
return True
|
||||
|
||||
def check_celery_backend(self):
|
||||
"""Checks if Celery backend is running and configured properly"""
|
||||
|
||||
print "Checking Celery Backend......",
|
||||
if not 'celeryd' in commands.getoutput('ps -ef'):
|
||||
self._set_status(0, "[%s]Error: celery is not running" % self.NAME)
|
||||
return True
|
||||
|
||||
if not os.path.exists('/etc/compass/celeryconfig'):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: No celery config file found for Compass"
|
||||
% self.NAME)
|
||||
return True
|
||||
|
||||
try:
|
||||
insp = inspect()
|
||||
celery_stats = inspect.stats(insp)
|
||||
if not celery_stats:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: No running Celery workers were found."
|
||||
% self.NAME)
|
||||
except IOError as e:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Failed to connect to the backend: %s"
|
||||
% (self.NAME, str(e)))
|
||||
from errno import errorcode
|
||||
if len(e.args) > 0 and errorcode.get(e.args[0]) == 'ECONNREFUSED':
|
||||
self.messages.append(
|
||||
"[%s]Error: RabbitMQ server isn't running"
|
||||
% self.NAME)
|
||||
return True
|
@ -0,0 +1,137 @@
|
||||
"""Health Check module for DHCP service"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import commands
|
||||
import xmlrpclib
|
||||
import sys
|
||||
|
||||
from socket import *
|
||||
|
||||
import base
|
||||
|
||||
|
||||
class DhcpCheck(base.BaseCheck):
|
||||
|
||||
NAME = "DHCP Check"
|
||||
|
||||
def run(self):
|
||||
installer = self.config.OS_INSTALLER
|
||||
method_name = "self.check_" + installer + "_dhcp()"
|
||||
return eval(method_name)
|
||||
|
||||
def check_cobbler_dhcp(self):
|
||||
"""Checks if Cobbler has taken over DHCP service"""
|
||||
|
||||
try:
|
||||
self.remote = xmlrpclib.Server(
|
||||
self.config.COBBLER_INSTALLER_URL,
|
||||
allow_none=True)
|
||||
self.token = self.remote.login(
|
||||
*self.config.COBBLER_INSTALLER_TOKEN)
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Cannot login to Cobbler with "
|
||||
"the tokens provided in the config file" % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
cobbler_settings = self.remote.get_settings()
|
||||
if cobbler_settings['manage_dhcp'] == 0:
|
||||
self.messages.append(
|
||||
"[DHCP]Info: DHCP service is not managed by Compass")
|
||||
return (self.code, self.messages)
|
||||
self.check_cobbler_dhcp_template()
|
||||
print "[Done]"
|
||||
self.check_dhcp_service()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: DHCP health check has completed. "
|
||||
"No problems found, all systems go." % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_cobbler_dhcp_template(self):
|
||||
"""Validates Cobbler's DHCP template file"""
|
||||
|
||||
print "Checking DHCP template......",
|
||||
if os.path.exists("/etc/cobbler/dhcp.template"):
|
||||
VAR_MAP = {"match_next_server": False,
|
||||
"match_subnet": False,
|
||||
"match_filename": False,
|
||||
"match_range": False,
|
||||
}
|
||||
|
||||
ip_regex = re.compile('^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$')
|
||||
|
||||
f = open("/etc/cobbler/dhcp.template")
|
||||
for line in f.readlines():
|
||||
if line.find("next_server") != -1:
|
||||
elmlist = line.split(" ")
|
||||
for elm in elmlist:
|
||||
if ";" in elm:
|
||||
elm = elm[:-2]
|
||||
if "$next_server" in elm or ip_regex.match(elm):
|
||||
VAR_MAP["match_next_server"] = True
|
||||
|
||||
elif line.find("subnet") != -1 and line.find("{") != -1:
|
||||
elmlist = line.split(" ")
|
||||
for elm in elmlist:
|
||||
if ip_regex.match(elm):
|
||||
if elm[-1] == "0" and "255" not in elm:
|
||||
VAR_MAP["match_subnet"] = True
|
||||
elif elm[-1] != "0":
|
||||
self.messages.append(
|
||||
"[%s]Error: Subnet should be set "
|
||||
"in the form of 192.168.0.0 in"
|
||||
"/etc/cobbler/dhcp.template"
|
||||
% self.NAME)
|
||||
elif line.find("filename") != -1:
|
||||
VAR_MAP["match_filename"] = True
|
||||
elif line.find("range dynamic-bootp") != -1:
|
||||
elmlist = line.split(" ")
|
||||
ip_count = 0
|
||||
for elm in elmlist:
|
||||
if ";" in elm and "\n" in elm:
|
||||
elm = elm[:-2]
|
||||
if ip_regex.match(elm):
|
||||
ip_count += 1
|
||||
if ip_count != 2:
|
||||
self.messages.append(
|
||||
"[%s]Error: DHCP range should be set "
|
||||
"between two IP addresses in "
|
||||
"/etc/cobbler/dhcp.template" % self.NAME)
|
||||
else:
|
||||
VAR_MAP["match_range"] = True
|
||||
|
||||
f.close()
|
||||
failed = []
|
||||
for var in VAR_MAP.keys():
|
||||
if VAR_MAP[var] is False:
|
||||
failed.append(var)
|
||||
if len(failed) != 0:
|
||||
self._set_status(0,
|
||||
"[%s]Info: DHCP template file "
|
||||
"failed components: %s"
|
||||
% (self.NAME, ' '.join(f for f in failed)))
|
||||
else:
|
||||
self._set_status(0,
|
||||
"[%s]Error: DHCP template file doesn't exist, "
|
||||
"health check failed." % self.NAME)
|
||||
return True
|
||||
|
||||
def check_dhcp_service(self):
|
||||
"""Checks if DHCP is running on port 67"""
|
||||
|
||||
print "Checking DHCP service......",
|
||||
if not 'dhcp' in commands.getoutput('ps -ef'):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: dhcp service does not seem to be running"
|
||||
% self.NAME)
|
||||
if getservbyport(67) != 'bootps':
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: bootps is not listening on port 67"
|
||||
% self.NAME)
|
||||
return True
|
@ -0,0 +1,120 @@
|
||||
"""Health Check module for DNS service"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import xmlrpclib
|
||||
import commands
|
||||
|
||||
from socket import *
|
||||
|
||||
import base
|
||||
|
||||
|
||||
class DnsCheck(base.BaseCheck):
|
||||
|
||||
NAME = "DNS Check"
|
||||
|
||||
def run(self):
|
||||
installer = self.config.OS_INSTALLER
|
||||
method_name = "self.check_" + installer + "_dns()"
|
||||
return eval(method_name)
|
||||
|
||||
def check_cobbler_dns(self):
|
||||
"""Checks if Cobbler has taken over DNS service"""
|
||||
|
||||
try:
|
||||
self.remote = xmlrpclib.Server(
|
||||
self.config.COBBLER_INSTALLER_URL,
|
||||
allow_none=True)
|
||||
self.token = self.remote.login(
|
||||
*self.config.COBBLER_INSTALLER_TOKEN)
|
||||
except:
|
||||
self._set_status(0,
|
||||
"[%s]Error: Cannot login to Cobbler "
|
||||
"with the tokens provided in the config file"
|
||||
% self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
cobbler_settings = self.remote.get_settings()
|
||||
if cobbler_settings['manage_dns'] == 0:
|
||||
self.messages.append('[DNS]Info: DNS is not managed by Compass')
|
||||
return (self.code, self.messages)
|
||||
self.check_cobbler_dns_template()
|
||||
print "[Done]"
|
||||
self.check_dns_service()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: DNS health check has complated. "
|
||||
"No problems found, all systems go." % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_cobbler_dns_template(self):
|
||||
"""Validates Cobbler's DNS template file"""
|
||||
|
||||
print "Checking DNS template......",
|
||||
if os.path.exists("/etc/cobbler/named.template"):
|
||||
VAR_MAP = {"match_port": False,
|
||||
"match_allow_query": False,
|
||||
}
|
||||
f = open("/etc/cobbler/named.template")
|
||||
host_ip = gethostbyname(gethostname())
|
||||
missing_query = []
|
||||
for line in f.readlines():
|
||||
if "listen-on port 53" in line and host_ip in line:
|
||||
VAR_MAP["match_port"] = True
|
||||
if "allow-query" in line:
|
||||
for subnet in ["127.0.0.0/8",
|
||||
"10.0.0.0/8",
|
||||
"192.168.0.0/16",
|
||||
"172.16.0.0/12"]:
|
||||
if not subnet in line:
|
||||
missing_query.append(subnet)
|
||||
f.close()
|
||||
|
||||
if VAR_MAP["match_port"] is False:
|
||||
self.messages.append(
|
||||
"[%s]Error: named service port and/or IP is "
|
||||
"misconfigured in /etc/cobbler/named.template"
|
||||
% self.NAME)
|
||||
if len(missing_query) != 0:
|
||||
self.messages.append(
|
||||
"[%s]Error: Missing allow_query values in "
|
||||
"/etc/cobbler/named.template:%s"
|
||||
% (self.Name,
|
||||
', '.join(subnet for subnet in missing_query)))
|
||||
else:
|
||||
VAR_MAP["match_allow_query"] = True
|
||||
|
||||
failed = []
|
||||
for var in VAR_MAP.keys():
|
||||
if VAR_MAP[var] is False:
|
||||
failed.append(var)
|
||||
if len(failed) != 0:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Info: DNS template failed components: %s"
|
||||
% (self.NAME, ' '.join(f for f in failed)))
|
||||
else:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: named template file doesn't exist, "
|
||||
"health check failed." % self.NAME)
|
||||
return True
|
||||
|
||||
def check_dns_service(self):
|
||||
"""Checks if DNS is running on port 53"""
|
||||
|
||||
print "Checking DNS service......",
|
||||
if not 'named' in commands.getoutput('ps -ef'):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: named service does not seem to be running"
|
||||
% self.NAME)
|
||||
|
||||
if getservbyport(53) != 'domain':
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: domain service is not listening on port 53"
|
||||
% self.NAME)
|
||||
return None
|
@ -0,0 +1,74 @@
|
||||
"""Health Check module for Hardware Discovery"""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
import base
|
||||
import utils as health_check_utils
|
||||
|
||||
|
||||
class HdsCheck(base.BaseCheck):
|
||||
|
||||
NAME = "HDS Check"
|
||||
|
||||
def run(self):
|
||||
if self.dist in ("centos", "redhat", "fedora", "scientific linux"):
|
||||
pkg_type = "yum"
|
||||
else:
|
||||
pkg_type = "apt"
|
||||
try:
|
||||
pkg_module = __import__(pkg_type)
|
||||
except:
|
||||
self.messages.append("[HDS]Error: No module named %s, "
|
||||
"please install it first." % pkg_module)
|
||||
method_name = 'self.check_' + pkg_type + '_snmp(pkg_module)'
|
||||
eval(method_name)
|
||||
print "[Done]"
|
||||
self.check_snmp_mibs()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append("[HDS]Info: hds health check has complated. "
|
||||
"No problems found, all systems go.")
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_yum_snmp(self, pkg_module):
|
||||
"""
|
||||
Check if SNMP yum dependencies are installed
|
||||
|
||||
:param pkg_module : python yum library
|
||||
:type pkg_module : python module
|
||||
|
||||
"""
|
||||
print "Checking SNMP Packages......",
|
||||
yum_base = pkg_module.YumBase()
|
||||
uninstalled = []
|
||||
for package in ['net-snmp-utils', 'net-snmp', 'net-snmp-python']:
|
||||
if not yum_base.rpmdb.searchNevra(name=package):
|
||||
self.messages.append("[HDS]Error: %s package is required "
|
||||
"for HDS" % package)
|
||||
uninstalled.append(package)
|
||||
if len(uninstalled) != 0:
|
||||
self._set_status(0, "[%s]Info: Uninstalled packages: %s"
|
||||
% (self.NAME,
|
||||
', '.join(item for item in uninstalled)))
|
||||
return True
|
||||
|
||||
def check_apt_snmp(self, pkg_module):
|
||||
## TODO: add ubuntu package check here
|
||||
return None
|
||||
|
||||
def check_snmp_mibs(self):
|
||||
"""Checks if SNMP MIB files are properly placed"""
|
||||
|
||||
print "Checking SNMP MIBs......",
|
||||
conf_err_msg = health_check_utils.check_path(self.NAME,
|
||||
'/etc/snmp/snmp.conf')
|
||||
if not conf_err_msg == "":
|
||||
self._set_status(0, conf_err_msg)
|
||||
|
||||
mibs_err_msg = health_check_utils.check_path(
|
||||
self.NAME,
|
||||
'/usr/local/share/snmp/mibs')
|
||||
if not mibs_err_msg == "":
|
||||
self._set_status(0, mibs_err_msg)
|
||||
return True
|
@ -0,0 +1,206 @@
|
||||
"""Miscellaneous Health Check for Compass"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import commands
|
||||
import base
|
||||
import utils as health_check_utils
|
||||
|
||||
|
||||
class MiscCheck(base.BaseCheck):
|
||||
|
||||
NAME = "Miscellaneous Check"
|
||||
|
||||
MISC_MAPPING = {
|
||||
"yum": "rsyslog ntp iproute openssh-clients python git wget "
|
||||
"python-setuptools python-netaddr python-flask "
|
||||
"python-flask-sqlalchemy python-amqplib amqp "
|
||||
"python-paramiko python-mock mod_wsgi httpd squid "
|
||||
"dhcp bind rsync yum-utils xinetd tftp-server gcc "
|
||||
"net-snmp-utils net-snmp python-daemon".split(" "),
|
||||
|
||||
"pip": "flask-script flask-restful celery six discover "
|
||||
"unittest2 chef".replace("-", "_").split(" "),
|
||||
|
||||
"disable": "iptables ip6tables".split(" "),
|
||||
|
||||
"enable": "httpd squid xinetd dhcpd named sshd rsyslog cobblerd "
|
||||
"ntpd compassd".split(" "),
|
||||
}
|
||||
|
||||
def run(self):
|
||||
self.check_linux_dependencies()
|
||||
print "[Done]"
|
||||
self.check_pip_dependencies()
|
||||
print "[Done]"
|
||||
self.check_ntp()
|
||||
print "[Done]"
|
||||
self.check_rsyslogd()
|
||||
print "[Done]"
|
||||
self.check_chkconfig()
|
||||
print "[Done]"
|
||||
self.check_selinux()
|
||||
print "[Done]"
|
||||
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: Miscellaneous check has completed "
|
||||
"No problems found, all systems go." % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_linux_dependencies(self):
|
||||
"""Checks if dependencies are installed"""
|
||||
|
||||
print "Checking Linux dependencies....",
|
||||
if self.dist in ("centos", "redhat", "fedora", "scientific linux"):
|
||||
pkg_type = "yum"
|
||||
else:
|
||||
pkg_type = "apt"
|
||||
try:
|
||||
pkg_module = __import__(pkg_type)
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: No module named %s, "
|
||||
"please install it first." % (self.NAME, pkg_module))
|
||||
method_name = 'self.check_' + pkg_type + '_dependencies(pkg_module)'
|
||||
eval(method_name)
|
||||
|
||||
def check_yum_dependencies(self, pkg_module):
|
||||
"""
|
||||
Checks if yum dependencies are installed.
|
||||
|
||||
:param pkg_module : python yum library
|
||||
:type pkg_module : python module
|
||||
|
||||
"""
|
||||
print "Checking Yum dependencies......",
|
||||
yum_base = pkg_module.YumBase()
|
||||
uninstalled = []
|
||||
for package in self.MISC_MAPPING["yum"]:
|
||||
if not yum_base.rpmdb.searchNevra(name=package):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: %s package is required"
|
||||
% (self.NAME, package))
|
||||
uninstalled.append(package)
|
||||
|
||||
if len(uninstalled) != 0:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Info: Uninstalled yum packages: %s"
|
||||
% (self.NAME, ', '.join(item for item in uninstalled)))
|
||||
|
||||
return True
|
||||
|
||||
def check_pip_dependencies(self):
|
||||
"""Checks if required pip packages are installed"""
|
||||
|
||||
print "Checking pip dependencies......",
|
||||
uninstalled = []
|
||||
for module in self.MISC_MAPPING['pip']:
|
||||
try:
|
||||
__import__(module)
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: pip package %s is requred"
|
||||
% (self.NAME, module))
|
||||
uninstalled.append(module)
|
||||
|
||||
if len(uninstalled) != 0:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Info: Uninstalled pip packages: %s"
|
||||
% (self.NAME, ', '.join(item for item in uninstalled)))
|
||||
|
||||
return True
|
||||
|
||||
def check_ntp(self):
|
||||
"""Validates ntp configuration and service"""
|
||||
|
||||
print "Checking NTP......",
|
||||
conf_err_msg = health_check_utils.check_path(self.NAME,
|
||||
'/etc/ntp.conf')
|
||||
if not conf_err_msg == "":
|
||||
self._set_status(0, conf_err_msg)
|
||||
|
||||
serv_err_msg = health_check_utils.check_service_running(self.NAME,
|
||||
'ntpd')
|
||||
if not serv_err_msg == "":
|
||||
self._set_status(0, serv_err_msg)
|
||||
|
||||
return True
|
||||
|
||||
def check_rsyslogd(self):
|
||||
"""Validates rsyslogd configuration and service"""
|
||||
|
||||
print "Checking rsyslog......",
|
||||
conf_err_msg = health_check_utils.check_path(self.NAME,
|
||||
'/etc/rsyslog.conf')
|
||||
if not conf_err_msg == "":
|
||||
self._set_status(0, conf_err_msg)
|
||||
|
||||
dir_err_msg = health_check_utils.check_path(self.NAME,
|
||||
'/etc/rsyslog.d/')
|
||||
if not dir_err_msg == "":
|
||||
self._set_status(0, dir_err_msg)
|
||||
|
||||
serv_err_msg = health_check_utils.check_service_running(self.NAME,
|
||||
'rsyslogd')
|
||||
if not serv_err_msg == "":
|
||||
self._set_status(0, serv_err_msg)
|
||||
|
||||
return True
|
||||
|
||||
def check_chkconfig(self):
|
||||
"""Check if required services are enabled on the start up"""
|
||||
|
||||
print "Checking chkconfig......",
|
||||
serv_to_disable = []
|
||||
for serv in self.MISC_MAPPING["disable"]:
|
||||
if health_check_utils.check_chkconfig(serv) is True:
|
||||
self._set_status(
|
||||
0,
|
||||
"[Miscellaenous Check]Error: %s is not disabled"
|
||||
% serv)
|
||||
serv_to_disable.append(serv)
|
||||
if len(serv_to_disable) != 0:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Info: You need to disable these services "
|
||||
"on system start-up: %s"
|
||||
% (self.NAME,
|
||||
", ".join(item for item in serv_to_disable)))
|
||||
|
||||
serv_to_enable = []
|
||||
for serv in self.MISC_MAPPING["enable"]:
|
||||
if health_check_utils.check_chkconfig(serv) is False:
|
||||
self._set_status(
|
||||
0, "[%s]Error: %s is disabled" % (self.NAME, serv))
|
||||
serv_to_enable.append(serv)
|
||||
if len(serv_to_enable) != 0:
|
||||
self._set_status(0, "[%s]Info: You need to enable these "
|
||||
"services on system start-up: %s"
|
||||
% (self.NAME,
|
||||
", ".join(item for item in serv_to_enable)))
|
||||
|
||||
return True
|
||||
|
||||
def check_selinux(self):
|
||||
"""Check if SELinux is disabled"""
|
||||
|
||||
print "Checking Selinux......",
|
||||
f = open("/etc/selinux/config")
|
||||
disabled = False
|
||||
for line in f.readlines():
|
||||
if "SELINUX=disabled" in line:
|
||||
disabled = True
|
||||
break
|
||||
if disabled is False:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Selinux is not disabled, "
|
||||
"please disable it in /etc/selinux/config." % self.NAME)
|
||||
|
||||
return True
|
@ -0,0 +1,113 @@
|
||||
"""Compass Health Check module for OS Installer"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import xmlrpclib
|
||||
|
||||
import base
|
||||
|
||||
|
||||
class OsInstallerCheck(base.BaseCheck):
|
||||
|
||||
NAME = "OS Installer Check"
|
||||
|
||||
def run(self):
|
||||
installer = self.config.OS_INSTALLER
|
||||
method_name = 'self.' + installer + '_check()'
|
||||
return eval(method_name)
|
||||
|
||||
def cobbler_check(self):
|
||||
"""Runs cobbler check from xmlrpc client"""
|
||||
|
||||
try:
|
||||
self.remote = xmlrpclib.Server(
|
||||
self.config.COBBLER_INSTALLER_URL,
|
||||
allow_none=True)
|
||||
self.token = self.remote.login(
|
||||
*self.config.COBBLER_INSTALLER_TOKEN)
|
||||
except:
|
||||
self.code = 0
|
||||
self.messages.append(
|
||||
"[OS Installer]Error: Cannot login to Cobbler with "
|
||||
"the tokens provided in the config file")
|
||||
self.messages.append(
|
||||
"[OS Installer]Error: Failed to connect to Cobbler "
|
||||
"API, please check if /etc/cobbler/setting "
|
||||
"is properly configured")
|
||||
return (self.code, self.messages)
|
||||
|
||||
check_result = self.remote.check(self.token)
|
||||
if len(check_result) != 0:
|
||||
self.code = 0
|
||||
for error_msg in check_result:
|
||||
self.messages.append("[OS Installer]Error: " + error_msg)
|
||||
|
||||
if len(self.remote.get_distros()) == 0:
|
||||
self._set_status(0,
|
||||
"[%s]Error: No Cobbler distros found" % self.NAME)
|
||||
|
||||
if len(self.remote.get_profiles()) == 0:
|
||||
self._set_status(0,
|
||||
"[%s]Error: No Cobbler profiles found"
|
||||
% self.NAME)
|
||||
|
||||
found_ppa = False
|
||||
if len(self.remote.get_repos()) != 0:
|
||||
for repo in self.remote.get_repos():
|
||||
if 'ppa_repo' in repo['mirror']:
|
||||
found_ppa = True
|
||||
break
|
||||
if found_ppa is False:
|
||||
self._set_status(0,
|
||||
"[%s]Error: No repository ppa_repo found"
|
||||
% self.NAME)
|
||||
|
||||
PATH_MAP = {'match_kickstart': ('/var/lib/cobbler/kickstarts/',
|
||||
['default.ks', ]
|
||||
),
|
||||
'match_snippets': ('/var/lib/cobbler/snippets/',
|
||||
[
|
||||
'chef',
|
||||
'chef-validator.pem',
|
||||
'client.rb',
|
||||
'first-boot.json',
|
||||
'kickstart_done',
|
||||
'kickstart_start',
|
||||
'network_config',
|
||||
'ntp.conf',
|
||||
'partition_disks',
|
||||
'partition_select',
|
||||
'post_anamon',
|
||||
'post_install_network_config',
|
||||
'pre_anamon',
|
||||
'pre_install_network_config',
|
||||
'rsyslogchef',
|
||||
'rsyslogconf',
|
||||
'yum.conf',
|
||||
]
|
||||
),
|
||||
'match_ks_mirror': ('/var/www/cobbler/',
|
||||
['ks_mirror']
|
||||
),
|
||||
'match_repo_mirror': ('/var/www/cobbler/',
|
||||
['repo_mirror/ppa_repo']
|
||||
),
|
||||
'match_iso': ('/var/lib/cobbler/', ['iso']),
|
||||
}
|
||||
not_exists = []
|
||||
for key in PATH_MAP.keys():
|
||||
for path in PATH_MAP[key][1]:
|
||||
if not os.path.exists(PATH_MAP[key][0] + path):
|
||||
not_exists.append(PATH_MAP[key][0] + path)
|
||||
if len(not_exists) != 0:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: These locations do not exist: %s"
|
||||
% (self.NAME, ', '.join(item for item in not_exists)))
|
||||
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[OS Installer]Info: OS Installer health check "
|
||||
"has completed. No problems found, all systems go.")
|
||||
|
||||
return (self.code, self.messages)
|
@ -0,0 +1,120 @@
|
||||
"""Health Check module for Package Installer"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import requests
|
||||
|
||||
import base
|
||||
import utils as health_check_utils
|
||||
import setting as health_check_setting
|
||||
|
||||
|
||||
class PackageInstallerCheck(base.BaseCheck):
|
||||
|
||||
NAME = "Package Installer Check"
|
||||
|
||||
def run(self):
|
||||
installer = self.config.PACKAGE_INSTALLER
|
||||
method_name = "self." + installer + "_check()"
|
||||
return eval(method_name)
|
||||
|
||||
def chef_check(self):
|
||||
"""Checks chef setting, cookbooks, databags and roles"""
|
||||
|
||||
CHEFDATA_MAP = {'CookBook': health_check_setting.COOKBOOKS,
|
||||
'DataBag': health_check_setting.DATABAGS,
|
||||
'Role': health_check_setting.ROLES,
|
||||
}
|
||||
|
||||
total_missing = []
|
||||
for data_type in CHEFDATA_MAP.keys():
|
||||
total_missing.append(self.check_chef_data(data_type,
|
||||
CHEFDATA_MAP[data_type]))
|
||||
print "[Done]"
|
||||
|
||||
missing = False
|
||||
for item in total_missing:
|
||||
if item[1] != []:
|
||||
missing = True
|
||||
break
|
||||
|
||||
if missing is True:
|
||||
messages = []
|
||||
for item in total_missing:
|
||||
messages.append("[%s]:%s"
|
||||
% (item[0],
|
||||
', '.join(missed for missed in item[1])))
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Missing modules on chef server: %s. "
|
||||
% (self.NAME, ' ;'.join(message for message in messages)))
|
||||
|
||||
self.check_chef_config_dir()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: Package installer health check "
|
||||
"has completed. No problems found, all systems go."
|
||||
% self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_chef_data(self, data_type, github_url):
|
||||
"""
|
||||
Checks if chef cookbooks/roles/databags are correct.
|
||||
|
||||
:param data_type : chef data type
|
||||
should be one of ['CookBook','DataBag','Role']
|
||||
:type data_type : string
|
||||
:param github_url : Latest chef data on stackforge/compass-adapters
|
||||
:type github_url : string
|
||||
|
||||
"""
|
||||
print "Checking Chef %s......" % (data_type.lower().strip() + 's'),
|
||||
try:
|
||||
import chef
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: pychef is not installed." % self.NAME)
|
||||
|
||||
return self.get_status()
|
||||
|
||||
self.api_ = chef.autoconfigure()
|
||||
|
||||
github = set([item['name']
|
||||
for item in
|
||||
requests.get(github_url).json()])
|
||||
if data_type == 'CookBook':
|
||||
local = set(os.listdir('/var/chef/cookbooks'))
|
||||
elif data_type == 'Role':
|
||||
local = set([name
|
||||
for
|
||||
name, item
|
||||
in
|
||||
chef.Role.list(api=self.api_).iteritems()])
|
||||
github = set([item['name'].replace(".rb", "")
|
||||
for item in
|
||||
requests.get(github_url).json()])
|
||||
else:
|
||||
local = set([item
|
||||
for item in
|
||||
eval('chef.' + data_type + '.list(api = self.api_)')])
|
||||
diff = github - local
|
||||
|
||||
if len(diff) <= 0:
|
||||
return (data_type, [])
|
||||
else:
|
||||
return (data_type, list(diff))
|
||||
|
||||
def check_chef_config_dir(self):
|
||||
"""Validates chef configuration directories"""
|
||||
|
||||
print "Checking Chef configurations......",
|
||||
message = health_check_utils.check_path(self.NAME, '/etc/chef-server/')
|
||||
if not message == "":
|
||||
self._set_status(0, message)
|
||||
|
||||
message = health_check_utils.check_path(self.NAME, '/opt/chef-server/')
|
||||
if not message == "":
|
||||
self._set_status(0, message)
|
||||
return None
|
@ -0,0 +1,106 @@
|
||||
"""Health Check module for Squid service"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import commands
|
||||
import pwd
|
||||
|
||||
from socket import *
|
||||
|
||||
import base
|
||||
import utils as health_check_utils
|
||||
|
||||
|
||||
class SquidCheck(base.BaseCheck):
|
||||
|
||||
NAME = "Squid Check"
|
||||
|
||||
def run(self):
|
||||
self.check_squid_files()
|
||||
print "[Done]"
|
||||
self.check_squid_service()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: Squid health check has completed. "
|
||||
"No problems found, all systems go." % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_squid_files(self):
|
||||
"""Validates squid config, cache directory and ownership"""
|
||||
|
||||
print "Checking Squid Files......",
|
||||
VAR_MAP = {'match_squid_conf': False,
|
||||
'match_squid_cache': False,
|
||||
'match_squid_ownership': False,
|
||||
}
|
||||
|
||||
conf_err_msg = health_check_utils.check_path(
|
||||
self.NAME,
|
||||
"/etc/squid/squid.conf")
|
||||
if not conf_err_msg == "":
|
||||
self._set_status(0, conf_err_msg)
|
||||
elif int(oct(os.stat('/etc/squid/squid.conf').st_mode)) < 644:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: squid.conf has incorrect "
|
||||
"file permissions" % self.NAME)
|
||||
else:
|
||||
VAR_MAP['match_squid_conf'] = True
|
||||
|
||||
squid_path_err_msg = health_check_utils.check_path(
|
||||
self.NAME,
|
||||
'/var/squid/')
|
||||
if not squid_path_err_msg == "":
|
||||
self.set_stauts(0, squid_path_err_msg)
|
||||
elif health_check_utils.check_path(self.NAME,
|
||||
'/var/squid/cache') != "":
|
||||
self._set_status(
|
||||
0,
|
||||
health_check_utils.check_path(
|
||||
self.NAME,
|
||||
'/var/squid/cache'))
|
||||
else:
|
||||
VAR_MAP['match_squid_cache'] = True
|
||||
uid = os.stat('/var/squid/').st_uid
|
||||
gid = os.stat('/var/squid/').st_gid
|
||||
if uid != gid or pwd.getpwuid(23).pw_name != 'squid':
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: /var/squid directory ownership "
|
||||
"misconfigured" % self.NAME)
|
||||
else:
|
||||
VAR_MAP['match_squid_ownership'] = True
|
||||
|
||||
failed = []
|
||||
for key in VAR_MAP.keys():
|
||||
if VAR_MAP[key] is False:
|
||||
failed.append(key)
|
||||
if len(failed) != 0:
|
||||
self.messages.append(
|
||||
"[%s]Info: Failed components for squid config: %s"
|
||||
% (self.NAME, ', '.join(item for item in failed)))
|
||||
return True
|
||||
|
||||
def check_squid_service(self):
|
||||
"""Checks if squid is running on port 3128"""
|
||||
|
||||
print "Checking Squid service......",
|
||||
if not 'squid' in commands.getoutput('ps -ef'):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: squid service does not seem running"
|
||||
% self.NAME)
|
||||
|
||||
try:
|
||||
if 'squid' != getservbyport(3128):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: squid is not listening on 3128"
|
||||
% self.NAME)
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: No service is listening on 3128, "
|
||||
"squid failed" % self.NAME)
|
||||
return True
|
@ -0,0 +1,88 @@
|
||||
"""Health Check module for TFTP service"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import xmlrpclib
|
||||
import commands
|
||||
from socket import *
|
||||
|
||||
import base
|
||||
import utils as health_check_utils
|
||||
|
||||
|
||||
class TftpCheck(base.BaseCheck):
|
||||
|
||||
NAME = "TFTP Check"
|
||||
|
||||
def run(self):
|
||||
installer = self.config.OS_INSTALLER
|
||||
method_name = "self.check_" + installer + "_tftp()"
|
||||
return eval(method_name)
|
||||
|
||||
def check_cobbler_tftp(self):
|
||||
"""
|
||||
Checks if Cobbler manages TFTP service
|
||||
|
||||
:note: we assume TFTP service is running at the
|
||||
same machine where this health check runs at
|
||||
"""
|
||||
|
||||
try:
|
||||
self.remote = xmlrpclib.Server(
|
||||
self.config.COBBLER_INSTALLER_URL,
|
||||
allow_none=True)
|
||||
self.token = self.remote.login(
|
||||
*self.config.COBBLER_INSTALLER_TOKEN)
|
||||
except:
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: Cannot login to Cobbler with the tokens "
|
||||
" provided in the config file" % self.NAME)
|
||||
return (self.code, self.messages)
|
||||
|
||||
cobbler_settings = self.remote.get_settings()
|
||||
if cobbler_settings['manage_tftp'] == 0:
|
||||
self.messages.append(
|
||||
'[TFTP]Info: tftp service is not managed by Compass')
|
||||
return (self.code, self.messages)
|
||||
self.check_tftp_dir()
|
||||
print "[Done]"
|
||||
self.check_tftp_service()
|
||||
print "[Done]"
|
||||
if self.code == 1:
|
||||
self.messages.append(
|
||||
"[%s]Info: tftp service health check has completed. "
|
||||
"No problems found, all systems go." % self.NAME)
|
||||
|
||||
return (self.code, self.messages)
|
||||
|
||||
def check_tftp_dir(self):
|
||||
"""Validates TFTP directories and configurations"""
|
||||
|
||||
print "Checking TFTP directories......",
|
||||
if not os.path.exists('/var/lib/tftpboot/'):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: No tftp-boot libraries found, "
|
||||
"please check if tftp server is properly "
|
||||
"installed/managed" % self.NAME)
|
||||
|
||||
return True
|
||||
|
||||
def check_tftp_service(self):
|
||||
"""Checks if TFTP is running on port 69"""
|
||||
|
||||
print "Checking TFTP services......",
|
||||
serv_err_msg = health_check_utils.check_service_running(self.NAME,
|
||||
'xinetd')
|
||||
if not serv_err_msg == "":
|
||||
self._set_status(0, serv_err_msg)
|
||||
|
||||
if 'tftp' != getservbyport(69):
|
||||
self._set_status(
|
||||
0,
|
||||
"[%s]Error: tftp doesn't seem to be listening "
|
||||
"on Port 60." % self.NAME)
|
||||
|
||||
return True
|
6
compass/actions/health_check/setting.py
Normal file
6
compass/actions/health_check/setting.py
Normal file
@ -0,0 +1,6 @@
|
||||
"""Health Check Settings"""
|
||||
|
||||
# Chef data on github
|
||||
COOKBOOKS="https://api.github.com/repos/stackforge/compass-adapters/contents/chef/cookbooks"
|
||||
ROLES="https://api.github.com/repos/stackforge/compass-adapters/contents/chef/roles"
|
||||
DATABAGS="https://api.github.com/repos/stackforge/compass-adapters/contents/chef/databags"
|
81
compass/actions/health_check/utils.py
Normal file
81
compass/actions/health_check/utils.py
Normal file
@ -0,0 +1,81 @@
|
||||
"""Compass Health Check heavy-lifting utilities"""
|
||||
|
||||
import os
|
||||
import platform
|
||||
import commands
|
||||
|
||||
|
||||
def validate_setting(module, setting, param):
|
||||
"""
|
||||
Checks if a Compass setting exists in the config file.
|
||||
|
||||
:param module : module name to be checked
|
||||
:type module : string
|
||||
:param setting : compass setting wrapper
|
||||
:type setting : python module
|
||||
:param param : settings defined in compass config file
|
||||
:type param : string
|
||||
|
||||
"""
|
||||
if hasattr(setting, param):
|
||||
return True
|
||||
else:
|
||||
err_msg = "[%s]Error: no %s defined" % (module, param)
|
||||
return err_msg
|
||||
|
||||
|
||||
def get_dist():
|
||||
"""Returns the operating system related information"""
|
||||
|
||||
os, version, release = platform.linux_distribution()
|
||||
return (os.lower().strip(), version, release.lower().strip())
|
||||
|
||||
|
||||
def check_path(module_name, path):
|
||||
"""
|
||||
Checks if a directory or file exisits.
|
||||
|
||||
:param module_name : module name to be checked
|
||||
:type module_name : string
|
||||
:param path : path of the directory of file
|
||||
:type path : string
|
||||
|
||||
"""
|
||||
err_msg = ""
|
||||
if not os.path.exists(path):
|
||||
err_msg = "[%s]Error: %s does not exsit, "
|
||||
"please check your configurations." % (module_name, path)
|
||||
return err_msg
|
||||
|
||||
|
||||
def check_service_running(module_name, service_name):
|
||||
"""
|
||||
Checks if a certain service is running.
|
||||
|
||||
:param module_name : module name to be checked
|
||||
:type module_name : string
|
||||
:param service_name : service name to be checked
|
||||
:type service_name : string
|
||||
|
||||
"""
|
||||
err_msg = ""
|
||||
if not service_name in commands.getoutput('ps -ef'):
|
||||
err_msg = "[%s]Error: %s is not running." \
|
||||
% (module_name, service_name)
|
||||
return err_msg
|
||||
|
||||
|
||||
def check_chkconfig(service_name):
|
||||
"""
|
||||
Checks if a service is enabled at the start up.
|
||||
|
||||
:param service_name : service name to be checked
|
||||
:type service_name : string
|
||||
|
||||
"""
|
||||
on = False
|
||||
for service in os.listdir('/etc/rc3.d/'):
|
||||
if service_name in service and 'S' in service:
|
||||
on = True
|
||||
break
|
||||
return on
|
@ -129,3 +129,10 @@ def flat_lists_with_possibility(lists):
|
||||
max_index = list_possibility.index(max(list_possibility))
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def pretty_print(*contents):
|
||||
if len(contents) == 0:
|
||||
print ""
|
||||
else:
|
||||
print "\n".join(content for content in contents)
|
||||
|
Loading…
Reference in New Issue
Block a user