Source code for alignak.http.generic_interface

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (C) 2015-2015: Alignak team, see AUTHORS.txt file for contributors
#
# This file is part of Alignak.
#
# Alignak is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Alignak 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Alignak.  If not, see <http://www.gnu.org/licenses/>.
"""This module provide a generic HTTP interface for all satellites.
Any Alignak satellite have at least those functions exposed over network
See : http://cherrypy.readthedocs.org/en/latest/tutorials.html for Cherrypy basic HTPP apps.
"""
import base64
import cherrypy
import cPickle
import inspect
import logging
import random
import time
import zlib

from alignak.log import logger


[docs]class GenericInterface(object): """Interface for inter satellites communications""" def __init__(self, app): self.app = app self.start_time = int(time.time()) self.running_id = "%d.%d" % ( self.start_time, random.randint(0, 100000000) ) @cherrypy.expose @cherrypy.tools.json_out()
[docs] def index(self): """Wrapper to call api from / :return: function list """ return self.api()
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def ping(self): """Test the connection to the daemon. Returns: pong :return: string 'pong' :rtype: str """ return "pong"
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_start_time(self): """Get the start time of the daemon :return: start time :rtype: int """ return self.start_time
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_running_id(self): """'Get the current running id of the daemon (scheduler)' :return: running_ig :rtype: int """ return self.running_id
@cherrypy.expose
[docs] def put_conf(self, conf): """Send a new configuration to the daemon (internal) :param conf: new conf to send :return: None """ with self.app.conf_lock: self.app.new_conf = conf # Safer to lock this one also
put_conf.method = 'post' @cherrypy.expose @cherrypy.tools.json_out()
[docs] def have_conf(self): """Get the daemon cur_conf state :return: boolean indicating if the daemon has a conf :rtype: bool """ return self.app.cur_conf is not None
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def set_log_level(self, loglevel): """Set the current log level in [NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL, UNKNOWN] :param loglevel: a value in one of the above :type loglevel: str :return: None """ return logger.setLevel(loglevel)
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_log_level(self): """Get the current log level in [NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL, UNKNOWN] :return: current log level :rtype: str """ return {logging.NOTSET: 'NOTSET', logging.DEBUG: 'DEBUG', logging.INFO: 'INFO', logging.WARNING: 'WARNING', logging.ERROR: 'ERROR', logging.CRITICAL: 'CRITICAL'}.get(logger._level, 'UNKNOWN')
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def api(self): """List the methods available on the daemon :return: a list of methods available :rtype: list """ return [x[0]for x in inspect.getmembers(self, predicate=inspect.ismethod) if not x[0].startswith('__')]
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def api_full(self): """List the api methods and their parameters :return: a list of methods and parameters :rtype: dict """ full_api = {} for fun in self.api(): full_api[fun] = {} full_api[fun][u"doc"] = getattr(self, fun).__doc__ full_api[fun][u"args"] = {} spec = inspect.getargspec(getattr(self, fun)) args = [a for a in spec.args if a != 'self'] if spec.defaults: a_dict = dict(zip(args, spec.defaults)) else: a_dict = dict(zip(args, (u"No default value",) * len(args))) full_api[fun][u"args"] = a_dict full_api[u"side_note"] = u"When posting data you have to zlib the whole content" \ u"and cPickle value. Example : " \ u"POST /set_log_level " \ u"zlib.compress({'loglevel' : cPickle.dumps('INFO')})" return full_api
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def remove_from_conf(self, sched_id): """Remove a scheduler connection (internal) :param sched_id: scheduler id to remove :type sched_id: int :return: None """ try: with self.app.conf_lock: del self.app.schedulers[sched_id] except KeyError: pass
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def what_i_managed(self): """Arbiter ask me which scheduler id I manage :return: managed configuration ids :rtype: dict """ print "The arbiter asked me what I manage. It's %s", self.app.what_i_managed() logger.debug("The arbiter asked me what I manage. It's %s", self.app.what_i_managed()) return self.app.what_i_managed()
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def wait_new_conf(self): """Ask the daemon to drop its configuration and wait for a new one :return: None """ with self.app.conf_lock: logger.debug("Arbiter wants me to wait for a new configuration") # Clear can occur while setting up a new conf and lead to error. self.app.schedulers.clear() self.app.cur_conf = None
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_external_commands(self): """Get the external commands from the daemon (internal) Use a lock for this call (not a global one, just for this method) :return: Pickled external command list :rtype: str """ with self.app.external_commands_lock: cmds = self.app.get_external_commands() raw = cPickle.dumps(cmds) return raw
@cherrypy.expose
[docs] def push_actions(self, actions, sched_id): """Get new actions from scheduler(internal) :param actions: list of action to add :type actions: list :param sched_id: id of the scheduler sending actions :type sched_id: int :return:None """ with self.app.lock: self.app.add_actions(actions, int(sched_id))
push_actions.method = 'post' @cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_returns(self, sched_id): """Get actions returns (serialized) for the scheduler with _id = sched_id :param sched_id: id of the scheduler :type sched_id: int :return: serialized list :rtype: str """ with self.app.lock: # print "A scheduler ask me the returns", sched_id ret = self.app.get_return_for_passive(int(sched_id)) # print "Send mack", len(ret), "returns" return cPickle.dumps(ret)
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_broks(self, bname): """Get broks from the daemon :return: Brok list serialized and b64encoded :rtype: str """ with self.app.lock: res = self.app.get_broks() return base64.b64encode(zlib.compress(cPickle.dumps(res), 2))
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_raw_stats(self): """Get raw stats from the daemon :return: daemon stats :rtype: dict """ app = self.app res = {} for sched_id in app.schedulers: sched = app.schedulers[sched_id] lst = [] res[sched_id] = lst for mod in app.q_by_mod: # In workers we've got actions send to queue - queue size for (q_id, queue) in app.q_by_mod[mod].items(): lst.append({ 'scheduler_name': sched['name'], 'module': mod, 'queue_number': q_id, 'queue_size': queue.qsize(), 'return_queue_len': app.get_returns_queue_len()}) return res