Exemple #1
0
 def test_wait_before_retry(self):
     must_stop = mock.Mock()
     stdout_consumer = (
         ConsumerRegister.get_consumer('Stdout')['consumer_cls']({}))
     stdout_consumer._wait_before_retry(must_stop)
     must_stop.wait.assert_called_once_with(
         timeout=stdout_consumer.retry_delay)
Exemple #2
0
 def test_wait_before_retry(self, time_mock):
     must_stop = threading.Event()
     stdout_consumer = (
         ConsumerRegister.get_consumer('Stdout')['consumer_cls']({}))
     stdout_consumer._wait_before_retry(must_stop)
     time_mock.sleep.assert_called_with(1)
     self.assertEquals(time_mock.sleep.call_count,
                       stdout_consumer.retry_delay)
Exemple #3
0
    def launch(self):
        """Launch sauna daemon

        Start consumers and producer threads.
        """
        signal.signal(signal.SIGTERM, self.term_handler)
        signal.signal(signal.SIGINT, self.term_handler)

        consumers_threads = []
        for consumer_data in self.consumers:

            consumer_name = consumer_data['type']

            consumer_info = ConsumerRegister.get_consumer(consumer_name)
            if not consumer_info:
                print('Plugin {} does not exist'.format(consumer_name))
                exit(1)

            try:
                consumer = consumer_info['consumer_cls'](consumer_data)
            except DependencyError as e:
                print(str(e))
                self.term_handler()
                exit(1)

            if isinstance(consumer, QueuedConsumer):
                consumer_queue = queue.Queue()
                self._consumers_queues.append(consumer_queue)
            else:
                consumer_queue = None

            consumer_thread = threading.Thread(
                name='consumer_{}'.format(consumer_name),
                target=consumer.run,
                args=(self.must_stop, consumer_queue)
            )

            consumer_thread.start()
            consumers_threads.append(consumer_thread)
            logging.debug(
                'Running consumer {}'.format(consumer_name)
            )

        producer = threading.Thread(
            name='producer', target=self.run_producer
        )
        producer.start()
        producer.join()

        self.term_handler()

        for consumer_thread in consumers_threads:
            consumer_thread.join()

        logging.debug('Exited main thread')
Exemple #4
0
    def launch(self):
        """Launch sauna daemon

        Start consumers and producer threads.
        """
        signal.signal(signal.SIGTERM, self.term_handler)
        signal.signal(signal.SIGINT, self.term_handler)

        consumers_threads = []
        for consumer_data in self.consumers:

            consumer_name = consumer_data['type']

            consumer_info = ConsumerRegister.get_consumer(consumer_name)
            if not consumer_info:
                print('Plugin {} does not exist'.format(consumer_name))
                sys.exit(1)

            try:
                consumer = consumer_info['consumer_cls'](consumer_data)
            except DependencyError as e:
                print(str(e))
                self.term_handler()
                sys.exit(1)

            if isinstance(consumer, QueuedConsumer):
                consumer_queue = queue.Queue()
                self._consumers_queues.append(consumer_queue)
            else:
                consumer_queue = None

            consumer_thread = threading.Thread(
                name='consumer_{}'.format(consumer_name),
                target=consumer.run,
                args=(self.must_stop, consumer_queue)
            )

            consumer_thread.start()
            consumers_threads.append(consumer_thread)
            logger.debug(
                'Running consumer {}'.format(consumer_name)
            )

        producer = threading.Thread(
            name='producer', target=self.run_producer
        )
        producer.start()
        producer.join()

        self.term_handler()

        for consumer_thread in consumers_threads:
            consumer_thread.join()

        logger.debug('Exited main thread')
Exemple #5
0
    def launch(self):
        # Start producer and consumer threads
        producer = threading.Thread(name='producer', target=self.run_producer)
        producer.start()

        consumers_threads = []
        for consumer_name, consumer_config in self.config['consumers'].items():

            consumer_info = ConsumerRegister.get_consumer(consumer_name)
            if not consumer_info:
                print('Plugin {} does not exist'.format(consumer_name))
                exit(1)

            try:
                consumer = consumer_info['consumer_cls'](consumer_config)
            except DependencyError as e:
                print(str(e))
                exit(1)

            if isinstance(consumer, QueuedConsumer):
                consumer_queue = queue.Queue()
                self._consumers_queues.append(consumer_queue)
            else:
                consumer_queue = None

            consumer_thread = threading.Thread(
                name='consumer_{}'.format(consumer_name),
                target=consumer.run,
                args=(self.must_stop, consumer_queue))

            consumer_thread.start()
            consumers_threads.append(consumer_thread)
            logging.debug('Running {} with {}'.format(consumer_name,
                                                      consumer_config))

        signal.signal(signal.SIGTERM, self.term_handler)
        signal.signal(signal.SIGINT, self.term_handler)

        producer.join()
        self.term_handler()

        for consumer_thread in consumers_threads:
            consumer_thread.join()

        logging.debug('Exited main thread')
Exemple #6
0
 def test_get_consumer(self):
     stdout_consumer = ConsumerRegister.get_consumer('Stdout')
     self.assert_(issubclass(stdout_consumer['consumer_cls'],
                             base.Consumer))
     must_be_none = ConsumerRegister.get_consumer('Unknown')
     self.assertIsNone(must_be_none)
Exemple #7
0
 def test_get_consumer(self):
     stdout_consumer = ConsumerRegister.get_consumer('Stdout')
     self.assert_(issubclass(stdout_consumer['consumer_cls'],
                             base.Consumer))
     must_be_none = ConsumerRegister.get_consumer('Unknown')
     self.assertIsNone(must_be_none)
Exemple #8
0
from sauna.consumers.base import QueuedConsumer
from sauna.consumers import ConsumerRegister

my_consumer = ConsumerRegister('HTTP')


@my_consumer.consumer()
class HTTPConsumer(QueuedConsumer):
    def __init__(self, config):
        super().__init__(config)
        try:
            import requests
            self.requests = requests
        except ImportError:
            from ... import DependencyError
            raise DependencyError(self.__class__.__name__, 'requests',
                                  'requests', 'python3-requests')
        self.config = {
            'url': config.get('url', 'http://localhost'),
            'timeout': config.get('timeout', 60),
            'headers': config.get('headers', None)
        }

    def _send(self, service_check):
        data = {
            'timestamp': service_check.timestamp,
            'hostname': service_check.hostname,
            'service': service_check.name,
            'status': service_check.status,
            'output': service_check.output
        }
Exemple #9
0
from sauna.consumers.base import QueuedConsumer
from sauna.consumers import ConsumerRegister

my_consumer = ConsumerRegister('Stdout')


@my_consumer.consumer()
class StdoutConsumer(QueuedConsumer):

    def _send(self, service_check):
        print(service_check)

    @staticmethod
    def config_sample():
        return '''
        # Just prints checks on the standard output
        Stdout:
        '''
Exemple #10
0
import socket
import select
from collections import defaultdict

from sauna.consumers.base import AsyncConsumer
from sauna.consumers import ConsumerRegister

my_consumer = ConsumerRegister('TCPServer')


@my_consumer.consumer()
class TCPServerConsumer(AsyncConsumer):

    service_checks = {}

    def __init__(self, config):
        super().__init__(config)
        self.config = {
            'port': config.get('port', 5555),
            'backlog': config.get('port', 128),
            'keepalive': config.get('keepalive', True)
        }
        self.read_wanted, self.write_wanted = ([], [])
        self.write_buffers = defaultdict(bytes)

    def _create_server(self):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setblocking(0)
        self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.server.bind(('', self.config['port']))
        self.server.listen(self.config['backlog'])
Exemple #11
0
import socket
import struct
import binascii
from copy import deepcopy
import itertools

from sauna.consumers.base import QueuedConsumer
from sauna.consumers import ConsumerRegister

my_consumer = ConsumerRegister('NSCA')


def encrypt_xor(data, iv, key):
    for i in (iv, key):
        i = itertools.cycle(i)
        data = bytes(x ^ y for x, y in zip(data, i))
    return data


@my_consumer.consumer()
class NSCAConsumer(QueuedConsumer):

    protocol_version = 3
    max_hostname_size = 64
    max_service_size = 128
    max_output_size = 4096

    init_payload_fmt = '!128sL'
    init_payload_size = struct.calcsize(init_payload_fmt)
    service_payload_fmt = '!hhIIh{}s{}s{}sh'.format(max_hostname_size,
                                                    max_service_size,
Exemple #12
0
# forked from http.py to match icinga Rest API
from sauna.consumers.base import QueuedConsumer
from sauna.consumers import ConsumerRegister

my_consumer = ConsumerRegister('HTTP-icinga')


@my_consumer.consumer()
class HTTPIcingaConsumer(QueuedConsumer):
    def __init__(self, config):
        super().__init__(config)
        try:
            import requests
            self.requests = requests
        except ImportError:
            from ... import DependencyError
            raise DependencyError(self.__class__.__name__, 'requests',
                                  'requests', 'python3-requests')
        self.config = {
            'url': config.get('url', 'http://localhost'),
            'timeout': config.get('timeout', 60),
            'headers': config.get('headers', None)
        }

    def _send(self, service_check):
        data = {
            "filter": ("host.name==\"" + service_check.hostname +
                       "\" && service.name==\"" + service_check.name + "\""),
            "exit_status":
            service_check.status,
            "plugin_output":
Exemple #13
0
import json
from http.server import HTTPServer, BaseHTTPRequestHandler

from sauna.consumers.base import AsyncConsumer
from sauna.consumers import ConsumerRegister
from sauna import __version__

my_consumer = ConsumerRegister('HTTPServer')


class StoppableHTTPServer(HTTPServer):
    """HTTPServer that stops itself when receiving a threading.Event"""
    def __init__(self, must_stop, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._must_stop = must_stop

    def service_actions(self):
        """Called by the serve_forever() loop.

        Check if Sauna requested the server to shutdown.
        It cannot call self.shutdown() because the server does not run in
        a separated thread.
        """
        if self._must_stop.is_set():
            self._BaseServer__shutdown_request = True


@my_consumer.consumer()
class HTTPServerConsumer(AsyncConsumer):
    def __init__(self, config):
        super().__init__(config)
Exemple #14
0
import json
import re
from typing import Optional, Set, List

from sauna.consumers.base import BatchQueuedConsumer
from sauna.consumers import ConsumerRegister

my_consumer = ConsumerRegister('HomeAssistantMQTT')


status_to_name = {
    0: 'OK',
    1: 'Warning',
    2: 'Critical',
    3: 'Unknown'
}


@my_consumer.consumer()
class HomeAssistantMQTTConsumer(BatchQueuedConsumer):
    """Report checks to Home Assistant via MQTT.

    Uses the Home Assistant MQTT discovery functionnality to
    dynamically create sensors for each couple of host/check.
    The first time Sauna sees a new check for a host, it inserts
    a MQTT message on a well known topic that HA monitors with the
    configuration for the new sensor. Each host/check gets its own
    MQTT topic that HA starts subscribing to.

    Afterwards checks are just sent on their own topic.
    """