Skip to content
Snippets Groups Projects
interfaces.py 2.86 KiB
import logging
import re

from brian_polling_manager import sensu

logger = logging.getLogger(__name__)


def load_ifc_checks(sensu_params):
    def _is_ifc_check(check):
        name = check['metadata']['name']
        return re.match(r'^check-([^-]+\.geant\.net)-(.+)$', name)
    ifc_checks = filter(_is_ifc_check, sensu.load_all_checks(sensu_params))
    return {c['metadata']['name']: c for c in ifc_checks}


def _check_name(interface):
    ifc_name = interface['name'].replace('/', '-')
    return f'check-{interface["router"]}-{ifc_name}'


def _make_check(check_params, interface):
    command = check_params['command'].format(
        script=check_params['script'],
        measurement=check_params['measurement'],
        community='0pBiFbD',  # TODO: add this to /poller/interfaces response
        hostname=interface['router'],
        interface=interface['name'],
        ifIndex=interface['snmp-index']
    )

    return {
        'command': command,
        'interval': check_params['interval'],
        'subscriptions': sorted(check_params['subscriptions']),
        'proxy_entity_name': interface['router'],
        'round_robin': check_params['round_robin'],
        'output_metric_format': 'influxdb_line',
        'output_metric_handlers': sorted(
            check_params['output_metric_handlers']),
        'metadata': {
            'name': _check_name(interface),
            'namespace': check_params['namespace']
        }
    }


def _checks_match(a, b) -> bool:
    if a['command'] != b['command']:
        return False
    if a['interval'] != b['interval']:
        return False
    if a['proxy_entity_name'] != b['proxy_entity_name']:
        return False
    if a['round_robin'] != b['round_robin']:
        return False
    if a['output_metric_format'] != b['output_metric_format']:
        return False
    if sorted(a['subscriptions']) != sorted(b['subscriptions']):
        return False
    if sorted(a['output_metric_handlers']) \
            != sorted(b['output_metric_handlers']):
        return False
    if a['metadata']['name'] != b['metadata']['name']:
        return False
    if a['metadata']['namespace'] != b['metadata']['namespace']:
        return False
    return True


def refresh(sensu_params, state):

    ifc_checks = load_ifc_checks(sensu_params)

    for interface in state.interfaces:

        expected_check = _make_check(
            sensu_params['interface-check'], interface)

        expected_name = _check_name(interface)
        if expected_name not in ifc_checks:
            sensu.create_check(sensu_params, expected_check)
        elif not _checks_match(ifc_checks[expected_name], expected_check):
            sensu.update_check(sensu_params, expected_check)

    wanted_checks = {_check_name(ifc) for ifc in state.interfaces}
    extra_checks = set(ifc_checks.keys()) - wanted_checks
    for name in extra_checks:
        sensu.delete_check(sensu_params, name)