Skip to content
Snippets Groups Projects
Select Git revision
  • 8b533abe221883f9aa744330880d8e928ae84267
  • develop default protected
  • master protected
  • feature/POL1-813-error-report-sensu-check
  • 0.23
  • 0.22
  • 0.21
  • 0.20
  • 0.19
  • 0.18
  • 0.17
  • 0.16
  • 0.15
  • 0.14
  • 0.13
  • 0.12
  • 0.11
  • 0.10
  • 0.9
  • 0.8
  • 0.7
  • 0.6
  • 0.5
  • 0.4
24 results

main.py

Blame
  • main.py 5.11 KiB
    """
    This script queries Inventory Provider for changes
    and configures Sensu with the snmp polling checks
    required by BRIAN.
    
    .. code-block:: console
    
        % brian-polling-manager --help
        Usage: brian-polling-manager [OPTIONS]
    
          Update BRIAN snmp checks based on Inventory Provider data.
    
        Options:
          --config TEXT         configuration filename
          --force / --no-force  update even if inventory hasn't been updated
          --help                Show this message and exit.
    
    The required configuration file must be
    formatted according to the following schema:
    
    .. asjson::
        brian_polling_manager.configuration.CONFIG_SCHEMA
    
    """
    import json
    import logging
    
    import click
    import jsonschema
    from statsd import StatsClient
    
    from brian_polling_manager import inventory, configuration, \
        interfaces, gws_direct, gws_indirect, eumetsat_multicast, sensu
    
    logger = logging.getLogger(__name__)
    
    REFRESH_RESULT_SCHEMA = {
        '$schema': 'http://json-schema.org/draft-07/schema#',
        'definitions': {
            'refresh-result': {
                'type': 'object',
                'properties': {
                    'checks': {'type': 'integer'},
                    'input': {'type': 'integer'},
                    'created': {'type': 'integer'},
                    'updated': {'type': 'integer'},
                    'deleted': {'type': 'integer'}
                },
                'required': ['checks', 'input', 'created', 'updated', 'deleted'],
                'additionalProperties': False
            }
        },
        'type': 'object',
        'properties': {
            'netconf': {'$ref': '#/definitions/refresh-result'},
            'snmp': {'$ref': '#/definitions/refresh-result'},
            'gws_direct': {'$ref': '#/definitions/refresh-result'},
            'gws_indirect': {'$ref': '#/definitions/refresh-result'},
            'eumetsat_multicast': {'$ref': '#/definitions/refresh-result'},
        },
        'required': ['netconf'],
        'additionalProperties': False
    }
    
    
    def refresh(config, force=False):
        """
        reload inventory data & update sensu checks
    
        The output will be a dict formatted according to the following schema:
    
        .. asjson::
            brian_polling_manager.main.REFRESH_RESULT_SCHEMA
    
        :param config: a dict returned by configuration.load_config
        :param force: if True, reload inventory data even if timestamp is same
        :return: a dict, formatted as above
        """
        sensu.clear_cached_values()
    
        state = configuration.State(config['statedir'])
        last = inventory.last_update_timestamp(config['inventory'])
        if force or not last or last != state.last:
            state.last = last
            state.interfaces = inventory.load_interfaces(config['inventory'])
            state.gws_direct = inventory.load_gws_direct_interfaces(
                config['inventory'])
            state.gws_indirect = inventory.load_gws_indirect_services(
                config['inventory'])
            state.eumetsat_multicast \
                = inventory.load_eumetsat_multicast_subscriptions(
                    config['inventory'])
        result = {
            'netconf': interfaces.netconf_router_refresh(config['sensu'], state.interfaces),
            'snmp': interfaces.snmp_interfaces_refresh(config['sensu'], state.interfaces),
            'gws_direct': gws_direct.refresh(config['sensu'], state.gws_direct),
            'gws_indirect': gws_indirect.refresh(
                config['sensu'], state.gws_indirect),
            'eumetsat_multicast': eumetsat_multicast.refresh(
                config['sensu'], state.eumetsat_multicast),
    
        }
        jsonschema.validate(result, REFRESH_RESULT_SCHEMA)  # sanity
    
        # remove events for deleted checks, otherwise they stick around forever
        sensu.clean_events(config['sensu'])
    
        statsd_config = config.get('statsd', None)
        if statsd_config:
            for key, counts in result.items():
                statsd = StatsClient(
                    host=statsd_config['hostname'],
                    port=statsd_config['port'],
                    prefix=f'{statsd_config["prefix"]}_{key}')
                statsd.gauge('checks', counts['checks'])
                statsd.gauge('input', counts['input'])
                statsd.gauge('created', counts['created'])
                statsd.gauge('updated', counts['updated'])
                statsd.gauge('deleted', counts['deleted'])
    
        return result
    
    
    def _validate_config(_ctx, _param, file):
        """
        loads, validates and returns configuration parameters
    
        :param _ctx: unused
        :param _param: unused
        :param value: file (file-like object open for reading)
        :return: a dict containing configuration parameters
        """
        try:
            return configuration.load_config(file)
        except (json.JSONDecodeError, jsonschema.ValidationError, OSError,
                AttributeError, ValueError, TypeError, ImportError) as e:
            raise click.BadParameter(str(e))
    
    
    @click.command()
    @click.option(
        '--config',
        default=None,
        type=click.File('r'),
        callback=_validate_config,
        help='configuration filename')
    @click.option(
        '--force/--no-force',
        default=False,
        help="refresh inventory data even if it hasn't been updated")
    def cli(config, force):
        """
        Update BRIAN snmp checks based on Inventory Provider data.
        """
        logger.info(json.dumps(refresh(config, force)))
    
    
    if __name__ == '__main__':
        cli()