Skip to content
Snippets Groups Projects
prisma-iaas 10.8 KiB
Newer Older
#!/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()