Skip to content
Snippets Groups Projects
prisma-iaas 9.98 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__), 'credentials.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()