#!/usr/bin/env python import calendar import ConfigParser import httplib import json import math import optparse import os import sys import time from filelock import FileLock class api_response(): __status = None __data = None __msg = None def __init__(self, status, data, msg): self.setStatus(status) self.setData(data) self.setMsg(msg) def setStatus(self, status): self.__status = status def getStatus(self): return self.__status def setData(self, data): self.__data = data def getData(self): return self.__data def setMsg(self, msg): self.__msg = msg def getMsg(self): return self.__msg class api_request(): @staticmethod def httpGet(url, host, port, header): conn = httplib.HTTPConnection(host, port) conn.request("GET", url, headers = header) res = conn.getresponse() response = api_response(res.status, res.read(), res.msg) return response @staticmethod def httpsGet(url, host, port, header): conn = httplib.HTTPSConnection(host, port) conn.request("GET", url, headers = header) res = conn.getresponse() response = api_response(res.status, res.read(), res.msg) return response @staticmethod def httpPost(url, host, port, params, headers): conn = httplib.HTTPConnection(host, port) conn.request("POST", url, params, headers) res = conn.getresponse() response = api_response(res.status, res.read(), res.msg) return response @staticmethod def httpsPost(url, host, port, params, headers): conn = httplib.HTTPSConnection(host, port) conn.request("POST", url, params, headers) res = conn.getresponse() response = api_response(res.status, res.read(), res.msg) return response def add_service_to_host(struct, host, service, state): find = 0 if 'hosts' not in struct.keys(): struct['hosts'] = [] for h in iter(struct['hosts']): if h['host'] == host: h['services'][service] = state find = 1 else: continue if find == 0: struct['hosts'].append({'host' : host, 'services' : {service : state}}) def add_service(struct, service, state): struct[service] = state class Prisma: __username = '' __tenant = '' __token = '' __password = '' __protocol = 'http' __server = '' __port = None __tenantID = None def __init__(self, protocol, server, port, username, tenant, password): self.setUsername(username) self.setTenant(tenant) self.setPassword(password) self.setProtocol(protocol) self.setServer(server) self.setPort(port) self.getToken() def setUsername(self, username): self.__username = username def getUsername(self): return self.__username def setPassword(self, password): self.__password = password def getPassword(self): return self.__password def setTenant(self, tenant): self.__tenant = tenant def getTenant(self): return self.__tenant def setTenantID(self, tenantID): self.__tenantID = tenantID def getTenantID(self): return self.__tenantID def setProtocol(self, protocol): self.__protocol = protocol def getProtocol(self): return self.__protocol def setServer(self, server): self.__server = server def setPort(self, port): self.__port = port def getPort(self): return self.__port def getServer(self): return self.__server def setToken(self, token): self.__token = token def getToken(self): token_file_path = os.path.join(os.path.dirname(__file__), 'token_backup') parser_token = ConfigParser.SafeConfigParser() with FileLock(token_file_path): parser_token.readfp(open(token_file_path)) if (not parser_token.get('token', 'expires')) or (int(float(parser_token.get('token', 'expires')) - time.time()) <= 0): auth = '{"auth": {"tenantName": "%s", "passwordCredentials": {"username": "%s", "password": "%s"}}}' % (self.getTenant(), self.getUsername(), self.getPassword()) header = {"Content-Type": "application/json", "Accept": "application/json"} if self.getProtocol() == 'http': res = api_request.httpPost('/v2.0/tokens', self.getServer(), self.getPort(), auth, header) else: res = api_request.httpsPost('/v2.0/tokens', self.getServer(), self.getPort(), auth, header) res_json = json.loads(res.getData()) timestamp = calendar.timegm(time.strptime(res_json['access']['token']['expires'],"%Y-%m-%dT%H:%M:%SZ")) parser_token.set('token', 'id', res_json['access']['token']['id']) parser_token.set('token', 'expires', str(timestamp)) parser_token.set('tenant', 'id', res_json['access']['token']['tenant']['id']) with FileLock(token_file_path): with open(token_file_path, 'w') as configfile: parser_token.write(configfile) self.setToken(parser_token.get('token', 'id')) self.setTenantID(parser_token.get('tenant','id')) return self.__token def getAuth(self): return {"X-Auth-Token": self.getToken()} def nova_service_list(self): service = None res = api_request.httpGet("/v2/%s/os-services" % (self.getTenantID()), self.getServer(), 8774, self.getAuth()) if res.getStatus() == 200: service = json.loads(res.getData()) return service def neutron_agent_list(self): agent = None res = api_request.httpGet('/v2.0/agents.json', self.getServer(), 9696, self.getAuth()) if res.getStatus() == 200: agent = json.loads(res.getData()) return agent def glance_images(self): images = None res = api_request.httpGet('/v1.1/images', self.getServer(), '9292', self.getAuth()) if res.getStatus() == 200: images = json.loads(res.getData()) return images def cinder_blocks_list(self): blocks = None res = api_request.httpGet('/v2/%s/os-services' % (self.getTenantID()), self.getServer(), '8776', self.getAuth()) if res.getStatus() == 200: blocks = json.loads(res.getData()) return blocks def swift_blocks_list(self): blocks = None res = api_request.httpsGet('/v1/AUTH_%s?format=json' % (self.getTenantID()), self.getServer(), '8080', self.getAuth()) if res.getStatus() == 200: blocks = json.loads(res.getData()) return blocks def encode(): struct = {} config_file_path = os.path.join(os.path.dirname(__file__), 'proxy.conf') parser_config = ConfigParser.SafeConfigParser() parser_config.readfp(open(config_file_path)) prisma = Prisma( parser_config.get('keystone', 'protocol'), parser_config.get('keystone', 'server'), parser_config.get('keystone', 'port'), parser_config.get('keystone', 'username'), parser_config.get('keystone', 'tenant'), parser_config.get('keystone', 'password') ) #keystone keystone = prisma.getTenantID() # print keystone if keystone != None: add_service(struct, 'keystone', 1) else: add_service(struct, 'keystone', 0) #nova nova = prisma.nova_service_list() compute = 0 if nova != None: add_service(struct, 'nova', 1) for i in iter(nova['services']): if i['status'] == 'enabled': add_service_to_host(struct, i['host'], i['binary'],0 if i['state'] == 'down' else 1) else: add_service(struct, 'nova', 0) #neutron neutron = prisma.neutron_agent_list() if neutron != None: add_service(struct, 'neutron', 1) for i in iter(neutron['agents']): add_service_to_host(struct, i['host'], i['binary'],0 if i['alive'] == 'false' else 1) else: add_service(struct, 'neutron', 0) #glance # glance = prisma.glance_images() # if glance != None: # add_service(struct, 'glance', 1) # else: # add_service(struct, 'glance', 0) #cinder cinder = prisma.cinder_blocks_list() if cinder != None: add_service(struct, 'cinder', 1) else: add_service(struct, 'cinder', 0) #swift # swift = prisma.swift_blocks_list() # if swift != None: # add_service(struct, 'swift', 1) # else: # add_service(struct, 'swift', 0) # print struct return struct def check( test_json): try: keystone = test_json["keystone"] except: print "keystone" return #nova controller_dic = {'nova-cert': 0, 'nova-consoleauth': 0, 'nova-scheduler': 0, 'nova-conductor': 0} nova = test_json["nova"] for host in iter(test_json["hosts"]): for i in iter(host["services"]): try: controller_dic[i]|=host["services"][i] except: continue for i in iter(controller_dic): nova &= controller_dic[i] #neutron network_dic = {'neutron-metadata-agent': 0, 'neutron-dhcp-agent': 0, 'neutron-linuxbridge-agent': 0} neutron = test_json["neutron"] for host in iter(test_json["hosts"]): for i in iter(host["services"]): try: network_dic[i]|=host["services"][i] except: continue for i in iter(network_dic): neutron &= network_dic[i] #cinder cinder = test_json["cinder"] #glance # glance = test_json["glance"] #compute computerun = 0 computecount = 0 compute = 1 for host in iter(test_json["hosts"]): test = 0 try: if 'nova-compute' in host["services"].keys(): computecount += 1 if host["services"]["nova-compute"] & host["services"]["neutron-linuxbridge-agent"]: computerun += 1 if host["services"]["nova-compute"] == 1 and host["services"]["neutron-linuxbridge-agent"] == 0: compute = 0 except: continue status = {} if cinder == 1: add_service(status, 'storage', 'OK') else add_service(status, 'storage', 'KO') if neutron == 1: add_service(status, 'network', 'OK') else add_service(status, 'network', 'KO') if compute == 1: add_service(status, 'available_nodes', computerun) add_service(status, 'total_nodes', computecount) else: add_service(status, 'available_nodes', 0) add_service(status, 'total_nodes', computecount) return json.dumps(status, sort_keys=False, indent=4) # return status # return keystone & compute & nova & neutron & cinder & glance def main(): struct = encode() status = check(struct) print status if __name__ == "__main__": main()