Select Git revision
Erik Reid authored
main.py 3.94 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, interfaces, configuration
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': {
'interfaces': {'$ref': '#/definitions/refresh-result'}
},
'required': ['interfaces'],
'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
"""
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'])
result = {
'interfaces': interfaces.refresh(config['sensu'], state)
}
statsd_config = config.get('statsd', None)
if statsd_config:
statsd = StatsClient(
host=statsd_config['hostname'],
port=statsd_config['port'],
prefix=f'{statsd_config["prefix"]}_interfaces')
statsd.gauge('checks', result['interfaces']['checks'])
statsd.gauge('input', result['interfaces']['input'])
statsd.gauge('created', result['interfaces']['created'])
statsd.gauge('updated', result['interfaces']['updated'])
statsd.gauge('deleted', result['interfaces']['deleted'])
jsonschema.validate(result, REFRESH_RESULT_SCHEMA) # sanity
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()