Source code for alignak.http.scheduler_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 specific HTTP interface for a SCheduler."""

import cherrypy
import base64
import cPickle
import zlib

from alignak.log import logger
from alignak.http.generic_interface import GenericInterface
from alignak.util import nighty_five_percent


[docs]class SchedulerInterface(GenericInterface): """This module provide a specific HTTP interface for a Scheduler.""" @cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_checks(self, do_checks=False, do_actions=False, poller_tags=['None'], reactionner_tags=['None'], worker_name='none', module_types=['fork']): """Get checks from scheduler, used by poller or reactionner (active ones) :param do_checks: used for poller to get checks :type do_checks: bool :param do_actions: used for reactionner to get actions :type do_actions: bool :param poller_tags: pollers tags to filter on this poller :type poller_tags: list :param reactionner_tags: reactionner tags to filter on this reactionner :type reactionner_tags: list :param worker_name: Worker name asking (so that the scheduler add it to actions objects) :type worker_name: str :param module_types: Module type to filter actions/checks :type module_types: list :return: base64 zlib compress pickled check/action list :rtype: str """ # print "We ask us checks" do_checks = (do_checks == 'True') do_actions = (do_actions == 'True') res = self.app.sched.get_to_run_checks(do_checks, do_actions, poller_tags, reactionner_tags, worker_name, module_types) # print "Sending %d checks" % len(res) self.app.sched.nb_checks_send += len(res) return base64.b64encode(zlib.compress(cPickle.dumps(res), 2))
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def put_results(self, results): """Put results to scheduler, used by poller and reactionners :param results: results to handle :type results: :return: True or ?? (if lock acquire fails) :rtype: bool """ nb_received = len(results) self.app.sched.nb_check_received += nb_received if nb_received != 0: logger.debug("Received %d results", nb_received) for result in results: result.set_type_active() with self.app.sched.waiting_results_lock: self.app.sched.waiting_results.extend(results) # for c in results: # self.sched.put_results(c) return True
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_broks(self, bname): """Get checks from scheduler, used by brokers :param bname: broker name, used to filter broks :type bname: str :return: 64 zlib compress pickled brok list :rtype: str """ # Maybe it was not registered as it should, if so, # do it for it if bname not in self.app.sched.brokers: self.fill_initial_broks(bname) # Now get the broks for this specific broker res = self.app.sched.get_broks(bname) # got only one global counter for broks self.app.sched.nb_broks_send += len(res) # we do not more have a full broks in queue self.app.sched.brokers[bname]['has_full_broks'] = False return base64.b64encode(zlib.compress(cPickle.dumps(res), 2))
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def fill_initial_broks(self, bname): """Get initial_broks type broks from scheduler, used by brokers Do not send broks, only make scheduler internal processing :param bname: broker name, used to filter broks :type bname: str :return: None TODO: Maybe we should check_last time we did it to prevent DDoS """ with self.app.conf_lock: if bname not in self.app.brokers: logger.info("A new broker just connected : %s", bname) self.app.sched.brokers[bname] = {'broks': {}, 'has_full_broks': False} env = self.app.sched.brokers[bname] if not env['has_full_broks']: env['broks'].clear() self.app.sched.fill_initial_broks(bname, with_logs=True)
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def get_raw_stats(self): """Get raw stats from the daemon:: * nb_scheduled: number of scheduled checks (to launch in the future) * nb_inpoller: number of check take by the pollers * nb_zombies: number of zombie checks (should be close to zero) * nb_notifications: number of notifications+event handlers * latency: avg,min,max latency for the services (should be <10s) :return: stats for scheduler :rtype: dict """ sched = self.app.sched res = sched.get_checks_status_counts() res = { 'nb_scheduled': res['scheduled'], 'nb_inpoller': res['inpoller'], 'nb_zombies': res['zombie'], 'nb_notifications': len(sched.actions) } # Spare schedulers do not have such properties if hasattr(sched, 'services'): # Get a overview of the latencies with just # a 95 percentile view, but lso min/max values latencies = [s.latency for s in sched.services] lat_avg, lat_min, lat_max = nighty_five_percent(latencies) res['latency'] = (0.0, 0.0, 0.0) if lat_avg: res['latency'] = (lat_avg, lat_min, lat_max) return res
@cherrypy.expose
[docs] def run_external_commands(self, cmds): """Post external_commands to scheduler (from arbiter) Wrapper to to app.sched.run_external_commands method :param cmds: external commands list ro run :type cmds: list :return: None """ with self.app.lock: self.app.sched.run_external_commands(cmds)
@cherrypy.expose
[docs] def put_conf(self, conf): """Post conf to scheduler (from arbiter) :param conf: new configuration to load :type conf: dict :return: None """ self.app.sched.die() super(SchedulerInterface, self).put_conf(conf)
@cherrypy.expose @cherrypy.tools.json_out()
[docs] def wait_new_conf(self): """Ask to scheduler to wait for new conf (HTTP GET from arbiter) :return: None """ with self.app.conf_lock: logger.debug("Arbiter wants me to wait for a new configuration") self.app.sched.die() super(SchedulerInterface, self).wait_new_conf()