Example #1
0
def test_only_wrong_services(submit_result, get_status, get_services):
    logger = FakeLogger()

    message = 'themessage'
    trap_check_name = 'thetrapcheckname'
    instance = 'theinstance'

    services = [
        {
            'service_description': 'notthis'
        },
        {
            'service_description': 'orthis'
        },
    ]
    get_services.return_value = services

    result = snmp_trap_handler.update_check_state(
        message=message,
        trap_check_name=trap_check_name,
        instance=instance,
        logger=logger,
    )

    assert result == 3

    for service in services:
        assert logger.string_appears_in(
            'debug',
            ('considering service', service['service_description']),
        )

    assert logger.string_appears_in('warn', ('service', 'not found'))

    get_services.assert_called_once_with(instance, 'nagios status')
Example #2
0
def test_instance_finder_address_can_find_name(get_host_name):
    logger = FakeLogger()

    expected_name = 'thename'

    action = {
        'instance': {
            'finder': re.compile("^(?P<address>[a-z]+)$"),
            'oid': 'something',
        },
    }

    details = {
        'something': 'anything',
        'unimportant': 'notthis',
    }

    get_host_name.return_value = expected_name

    result = snmp_trap_handler.find_target_instance(
        action=action,
        details=details,
        message_source='notimportant',
        logger=logger,
    )

    assert result == expected_name

    assert logger.string_appears_in('debug', ('look up', 'name'))
    assert logger.string_appears_in('debug', 'details finder found')
Example #3
0
def test_oid_for_message_and_instance():
    logger = FakeLogger()
    config_name = 'instance_and_message_oid'
    lookups = {
        'instanceoid': 'lookedupinstance',
        'messageoid': 'lookedupmessage',
    }
    oid_lookup = FakeOidLookup(lookups=lookups)

    result = snmp_trap_handler.determine_action(
        oid=config_name,
        oid_lookup=oid_lookup,
        logger=logger,
    )

    expected_path = CONF_PATH.format(oid=config_name)
    assert logger.string_appears_in('debug', expected_path)

    assert logger.string_appears_in('debug', 'loading instance')
    assert logger.string_appears_in('debug', 'loading oid_for_message')

    assert result['instance'] == {
        'oid': lookups['instanceoid'],
        'finder': re.compile(u'testfinder'),
    }
    assert result['oid_for_message'] == lookups['messageoid']
Example #4
0
def test_no_instance_finder_cannot_find_name(get_host_name):
    logger = FakeLogger()

    source_address = 'thesource'

    action = {}

    details = {
        'unimportant': 'notthis',
    }

    get_host_name.return_value = None

    with pytest.raises(snmp_trap_handler.MonitoredHostNotFoundError):
        snmp_trap_handler.find_target_instance(
            action=action,
            details=details,
            message_source=source_address,
            logger=logger,
        )

    assert logger.string_appears_in('debug', ('look up', 'name'))
    assert not logger.string_appears_in('debug', 'details finder found')
    assert logger.string_appears_in('error', 'no host found')

    get_host_name.assert_called_once_with(source_address)
Example #5
0
def test_notification_failure(submit_result, get_status, get_services):
    logger = FakeLogger()

    message = 'themessage'
    trap_check_name = 'thetrapcheckname'
    instance = 'theinstance'

    services = [
        {
            'service_description': trap_check_name,
            'current_state': '0'
        },
        {
            'service_description': 'notthis'
        },
    ]
    get_services.return_value = services

    submit_result.side_effect = RuntimeError

    with pytest.raises(RuntimeError):
        snmp_trap_handler.update_check_state(
            message=message,
            trap_check_name=trap_check_name,
            instance=instance,
            logger=logger,
        )

    for expected in ('correct service found', 'submitting check'):
        assert logger.string_appears_in('debug', expected)

    assert not logger.string_appears_in('warn', 'in progress')
Example #6
0
def test_instance_finder_address_cannot_find_name(get_host_name):
    logger = FakeLogger()

    action = {
        'instance': {
            'finder': re.compile("^(?P<address>[a-z]+)$"),
            'oid': 'something',
        },
    }

    details = {
        'something': 'anything',
        'unimportant': 'notthis',
    }

    get_host_name.return_value = None

    with pytest.raises(snmp_trap_handler.MonitoredHostNotFoundError):
        snmp_trap_handler.find_target_instance(
            action=action,
            details=details,
            message_source='notimportant',
            logger=logger,
        )

    assert logger.string_appears_in('debug', ('look up', 'name'))
    assert logger.string_appears_in('debug', 'details finder found')
    assert logger.string_appears_in('error', 'no host found')
def test_run_check_missing_ini(mock_print, exit, mock_subproc, mock_os,
                               mock_get_types):
    logger = FakeLogger()
    script_path = 'something'
    target_type = 'thistargettype'
    hostname = 'thehost'
    oid = 'theoid'
    ignore_unknown = False

    mock_os.path.exists.return_value = False
    ini_names = ['yes', 'that']
    ini_files = [ini_name + '.ini' for ini_name in ini_names]
    mock_os.listdir.return_value = BASE_DIR_LIST + ini_files

    mock_get_types.return_value = ini_names

    nagios_plugin_utils.run_check(script_path, target_type, hostname, oid,
                                  logger, ignore_unknown)

    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'target type' in mock_print_arg
    assert 'valid types' in mock_print_arg
    logger.string_appears_in('error', ('target type', 'valid types'))
    for ini_name in ini_names:
        assert ini_name in mock_print_arg
        logger.string_appears_in('error', ini_name)

    exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_run_check_ignore_not_unknown(mock_print, exit, mock_subproc, mock_os,
                                      mock_get_types):
    logger = FakeLogger()
    script_path = 'something'
    target_type = 'thistargettype'
    hostname = 'thehost'
    oid = 'theoid'
    ignore_unknown = True

    mock_os.path.exists.return_value = True

    mock_os.path.isfile.return_value = True

    exit_status = 42
    exit_output = 'badexitoutput'
    error = subprocess.CalledProcessError(
        exit_status,
        'notarealcommand',
        exit_output,
    )
    mock_subproc.side_effect = error

    nagios_plugin_utils.run_check(script_path, target_type, hostname, oid,
                                  logger, ignore_unknown)

    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert exit_output == mock_print_arg
    logger.string_appears_in('error',
                             ('unknown or error', 'status',
                              text_type(exit_status), 'output', exit_output))

    exit.assert_called_once_with(exit_status)
def test_run_check_ignore_unknown(mock_print, exit, mock_subproc, mock_os,
                                  mock_get_types):
    logger = FakeLogger()
    script_path = 'something'
    target_type = 'thistargettype'
    hostname = 'thehost'
    oid = 'theoid'
    ignore_unknown = True

    mock_os.path.exists.return_value = True

    mock_os.path.isfile.return_value = True

    exit_status = 3
    exit_output = 'badexitoutput'
    error = subprocess.CalledProcessError(
        exit_status,
        'notarealcommand',
        exit_output,
    )
    mock_subproc.side_effect = error

    result = nagios_plugin_utils.run_check(script_path, target_type, hostname,
                                           oid, logger, ignore_unknown)

    logger.string_appears_in('warn', ('unknown state', 'ignoring'))

    assert result is None

    assert mock_print.call_count == 0
    assert exit.call_count == 0
def test_reaction_not_defined(nagios_utils, exit, snmp_utils, logging_utils):
    target_type = 'missing'
    trap_name = 'just_oid_for_message'

    lookups = deepcopy(BASE_LOOKUPS)
    lookups[BASIC_NOTIFICATION_TRAP_VALUE] = trap_name

    logger = FakeLogger()
    oid_lookup = FakeOidLookup(lookups=lookups)
    stdin = FakeStdin(deepcopy(BASIC_NOTIFICATION))

    logging_utils.Logger.return_value = logger
    snmp_utils.OIDLookup.return_value = oid_lookup
    snmp_trap_handler.sys.stdin = stdin
    nagios_utils.get_target_type_for_instance.return_value = target_type

    snmp_trap_handler.main()

    logging_utils.Logger.assert_called_once_with(
        'cloudify_nagios_snmp_trap_handler')

    assert logger.string_appears_in('info', (
        'trap',
        trap_name,
        'from',
        NOTIFICATION_SOURCE,
    ))

    assert logger.string_appears_in('debug', 'looking up target type')
    assert logger.string_appears_in('debug', ('target type', target_type))
    assert logger.string_appears_in('info', 'no reaction')
Example #11
0
def test_found_already_notified(submit_result, get_status, get_services):
    logger = FakeLogger()

    message = 'themessage'
    trap_check_name = 'thetrapcheckname'
    instance = 'theinstance'

    services = [
        {
            'service_description': 'notthis'
        },
        {
            'service_description': trap_check_name,
            'current_state': '2'
        },
    ]
    get_services.return_value = services

    result = snmp_trap_handler.update_check_state(
        message=message,
        trap_check_name=trap_check_name,
        instance=instance,
        logger=logger,
    )

    assert result == 1

    assert logger.string_appears_in('debug', 'correct service found')
    assert logger.string_appears_in('warn', 'in progress')

    get_services.assert_called_once_with(instance, 'nagios status')
Example #12
0
def test_no_instance_finder_can_find_name(get_host_name):
    logger = FakeLogger()

    expected_name = 'thename'
    source_address = 'thesource'

    action = {}

    details = {
        'unimportant': 'notthis',
    }

    get_host_name.return_value = expected_name

    result = snmp_trap_handler.find_target_instance(
        action=action,
        details=details,
        message_source=source_address,
        logger=logger,
    )

    assert result == expected_name

    assert logger.string_appears_in('debug', ('look up', 'name'))
    assert not logger.string_appears_in('debug', 'details finder found')

    get_host_name.assert_called_once_with(source_address)
def test_run_check_missing_script(mock_print, exit, mock_subproc, mock_os,
                                  mock_get_types):
    logger = FakeLogger()
    script_path = 'something'
    target_type = 'thistargettype'
    hostname = 'thehost'
    oid = 'theoid'
    ignore_unknown = False

    mock_os.path.exists.return_value = True

    mock_os.path.isfile.return_value = False

    nagios_plugin_utils.run_check(script_path, target_type, hostname, oid,
                                  logger, ignore_unknown)

    exist_check = mock_os.path.exists.call_args_list[0][0][0]
    assert exist_check.endswith(hashlib.md5(target_type).hexdigest() + '.ini')

    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'check_snmp' in mock_print_arg
    assert 'not found' in mock_print_arg
    logger.string_appears_in('error', ('check_snmp', 'not found'))

    exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
Example #14
0
def test_no_result(mock_print, exit, thresholds, run_check,
                   get_multi_float,
                   calculate_mean, get_instance_addresses, get_host_address,
                   generate_perfdata, generate_check_id,
                   check_thresholds_and_exit, logging_utils):
    logger = FakeLogger()
    logging_utils.Logger.return_value = logger

    run_check_results = None, None
    run_check.side_effect = run_check_results

    returned_thresholds = 'thresholds'
    thresholds.return_value = returned_thresholds

    float_values = 1.5, 2.0
    get_multi_float.return_value = float_values

    mean = 1.75
    calculate_mean.return_value = mean
    old_calculate_mean = calculate_mean.APPROACHES['arithmetic_mean']
    check_snmp_aggregate.APPROACHES['arithmetic_mean'] = calculate_mean

    instance_addresses = '192.0.2.5', '192.0.2.6'
    get_instance_addresses.return_value = instance_addresses

    host_addresses = ['addr1', 'addr2']
    get_host_address.side_effect = host_addresses

    perfdata = 'performance_data'
    generate_perfdata.return_value = perfdata

    check_identifier = 'check_id'
    generate_check_id.return_value = check_identifier

    node = 'therealhost'
    oids = 'somefakeoid,other'
    target_type = 'thetypeoftarget'

    check_snmp_aggregate.main(
        ['--node', node, '--oids', oids,
         '--approach', 'arithmetic_mean',
         '--unknown', 'ignore',
         '--target-type', target_type]
    )

    logger.string_appears_in('error', 'no values')
    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'no values' in mock_print_arg

    exit.assert_called_once_with(STATUS_UNKNOWN)

    check_snmp_aggregate.APPROACHES['arithmetic_mean'] = old_calculate_mean
Example #15
0
def test_broken_instance():
    logger = FakeLogger()
    config_name = 'broken_instance'

    with pytest.raises(KeyError):
        snmp_trap_handler.determine_action(
            oid=config_name,
            oid_lookup=mock.Mock(),
            logger=logger,
        )

    expected_path = CONF_PATH.format(oid=config_name)
    assert logger.string_appears_in('debug', expected_path)

    assert logger.string_appears_in('debug', 'loading instance')
Example #16
0
def test_oid_for_message_lookup_exception():
    logger = FakeLogger()
    config_name = 'just_oid_for_message'
    oid_lookup = mock.Mock()
    oid_lookup.get.side_effect = RuntimeError

    with pytest.raises(RuntimeError):
        snmp_trap_handler.determine_action(
            oid=config_name,
            oid_lookup=oid_lookup,
            logger=logger,
        )

    expected_path = CONF_PATH.format(oid=config_name)
    assert logger.string_appears_in('debug', expected_path)

    assert logger.string_appears_in('debug', 'loading oid_for_message')
def test_multi_oid(mock_print, exit, thresholds, run_check, get_perfdata,
                   get_single_float, get_instance_rate_path, calculate_rate,
                   check_thresholds_and_exit, logging_utils):
    logger = FakeLogger()

    hostname = 'therealhost'
    oid = 'somefakeoid,otheroid'
    target_type = 'thetypeoftarget'

    check_snmp_numeric.main(
        ['--hostname', hostname, '--oid', oid, '--target-type', target_type])

    logger.string_appears_in('error', 'single oid')
    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'single oid' in mock_print_arg

    exit.assert_called_once_with(STATUS_UNKNOWN)
def test_missing_traps():
    logger = FakeLogger()
    target_type = 'missingtraps'
    trap_value = 'test_trap'

    with pytest.raises(KeyError):
        snmp_trap_handler.determine_reaction(
            target_type=target_type,
            trap_value=trap_value,
            logger=logger,
        )

    expected_path = CONF_PATH.format(
        target_type=hashlib.md5(target_type).hexdigest(), )
    assert logger.string_appears_in('debug', expected_path)

    assert logger.string_appears_in('debug', 'loading reaction')
def test_no_reaction_found():
    logger = FakeLogger()
    target_type = 'notrap'
    trap_value = 'test_trap'

    result = snmp_trap_handler.determine_reaction(
        target_type=target_type,
        trap_value=trap_value,
        logger=logger,
    )

    expected_path = CONF_PATH.format(
        target_type=hashlib.md5(target_type).hexdigest(), )
    assert logger.string_appears_in('debug', expected_path)

    assert logger.string_appears_in('debug', 'loading reaction')

    assert result is None
Example #20
0
def test_low_higher_than_high(mock_print, exit):
    logger = FakeLogger()
    low_warning = 42
    low_critical = 42
    high_warning = 32
    high_critical = 32

    nagios_plugin_utils.validate_and_structure_thresholds(
        low_warning, low_critical,
        high_warning, high_critical,
        logger,
    )

    mock_print_arg = mock_print.call_args_list[0][0][0]
    assert 'must be higher' in mock_print_arg
    logger.string_appears_in('error', 'must be higher')

    exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
Example #21
0
def test_just_oid_for_message():
    logger = FakeLogger()
    config_name = 'just_oid_for_message'
    oid_lookup = FakeOidLookup(default='looked_up_message_oid')

    result = snmp_trap_handler.determine_action(
        oid=config_name,
        oid_lookup=oid_lookup,
        logger=logger,
    )

    expected_path = CONF_PATH.format(oid=config_name)
    assert logger.string_appears_in('debug', expected_path)

    assert not logger.string_appears_in('debug', 'loading instance')
    assert logger.string_appears_in('debug', 'loading oid_for_message')

    assert result['oid_for_message'] == 'looked_up_message_oid'
def test_verbose_reaction(nagios_utils, exit, snmp_utils, logging_utils,
                          get_check_name):
    target_type = 'test_main_instance'
    trap_name = 'test_main_instance'
    check_name = 'thecheck'

    lookups = deepcopy(BASE_LOOKUPS)
    lookups[VERBOSE_NOTIFICATION_TRAP_VALUE] = trap_name

    logger = FakeLogger()
    oid_lookup = FakeOidLookup(lookups=lookups)
    stdin = FakeStdin(deepcopy(VERBOSE_NOTIFICATION))

    logging_utils.Logger.return_value = logger
    snmp_utils.OIDLookup.return_value = oid_lookup
    snmp_trap_handler.sys.stdin = stdin
    nagios_utils.get_target_type_for_instance.return_value = target_type
    get_check_name.return_value = check_name
    nagios_utils.get_services_for_host.return_value = [{
        "service_description": check_name,
        "current_state": "0",
    }]

    snmp_trap_handler.main()

    logging_utils.Logger.assert_called_once_with(
        'cloudify_nagios_snmp_trap_handler')

    assert logger.string_appears_in('info', (
        'trap',
        trap_name,
        'from',
        NOTIFICATION_SOURCE,
    ))

    assert logger.string_appears_in('debug', 'looking up target type')
    assert logger.string_appears_in('debug', ('target type', target_type))
    assert logger.string_appears_in('info',
                                    ('reaction defined', 'updating', 'check'))

    exit.assert_called_once_with(0)
Example #23
0
def test_not_yet_notified(submit_result, get_status, get_services):
    logger = FakeLogger()

    message = 'themessage'
    trap_check_name = 'thetrapcheckname'
    instance = 'theinstance'

    services = [
        {
            'service_description': trap_check_name,
            'current_state': '0'
        },
        {
            'service_description': 'notthis'
        },
    ]
    get_services.return_value = services

    result = snmp_trap_handler.update_check_state(
        message=message,
        trap_check_name=trap_check_name,
        instance=instance,
        logger=logger,
    )

    assert result == 0

    for expected in ('correct service found', 'submitting check',
                     'result submitted'):
        assert logger.string_appears_in('debug', expected)

    assert not logger.string_appears_in('warn', 'in progress')

    get_services.assert_called_once_with(instance, 'nagios status')
    submit_result.assert_called_once_with(
        host=instance,
        service=trap_check_name,
        status='2',
        output=message,
    )
def test_trap_in_details():
    logger = FakeLogger()
    lookups = {
        'system.sysUpTime.0': 'uptime',
        'enterprises.52312.900.0.0.1': 'cloudifything',
        snmp_trap_handler.SNMP_TRAP_OID: 'snmptrap',
        'snmp.1.1.4.1.0': 'snmptrap',
    }
    oid_lookup = FakeOidLookup(lookups=lookups)

    raw_details = [
        {
            'raw_oid': 'system.sysUpTime.0',
            'value': '1234'
        },
        {
            'raw_oid': 'snmp.1.1.4.1.0',
            'value': 'enterprises.52312.900.0.0.1'
        },
    ]

    result = snmp_trap_handler.normalise_oids_and_get_trap_value(
        raw_details=raw_details,
        oid_lookup=oid_lookup,
        logger=logger,
    )

    assert result == (
        'cloudifything',
        {
            lookups['system.sysUpTime.0']: '1234',
            lookups['snmp.1.1.4.1.0']: 'enterprises.52312.900.0.0.1',
        },
    )

    assert logger.string_appears_in('debug',
                                    ('trap identity', 'cloudifything'))
    assert logger.string_appears_in('debug', ('uptime', '1234'))
def test_no_trap():
    logger = FakeLogger()
    lookups = {
        'system.sysUpTime.0': 'uptime',
    }
    oid_lookup = FakeOidLookup(lookups=lookups)

    raw_details = [
        {
            'raw_oid': 'system.sysUpTime.0',
            'value': '1234'
        },
    ]

    result = snmp_trap_handler.normalise_oids_and_get_trap_value(
        raw_details=raw_details,
        oid_lookup=oid_lookup,
        logger=logger,
    )

    assert result == (None, {lookups['system.sysUpTime.0']: '1234'})

    assert not logger.string_appears_in('debug', 'trap identity')
    assert logger.string_appears_in('debug', ('uptime', '1234'))
def test_run_check_no_inis(mock_print, exit, mock_subproc, mock_os,
                           mock_get_types):
    logger = FakeLogger()
    script_path = 'something'
    target_type = 'thistargettype'
    hostname = 'thehost'
    oid = 'theoid'
    ignore_unknown = False

    mock_os.path.exists.return_value = False
    mock_os.listdir.return_value = BASE_DIR_LIST

    mock_get_types.return_value = []

    nagios_plugin_utils.run_check(script_path, target_type, hostname, oid,
                                  logger, ignore_unknown)

    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'target type' in mock_print_arg
    assert 'valid types' in mock_print_arg
    assert 'none' in mock_print_arg
    logger.string_appears_in('error', ('target type', 'valid types', 'none'))

    exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_generate_message_without_oid():
    logger = FakeLogger()

    trap_value = 'thetrap'
    action = {}
    details = {}
    expected_prefix = snmp_trap_handler.TRAP_RECEIVED_PREFIX.format(
        oid=trap_value, ).lower()

    result = snmp_trap_handler.generate_check_message(trap_value, details,
                                                      action, logger)

    result = result.lower()
    for component in (expected_prefix, 'no message oid', trap_value):
        assert component in result
        assert logger.string_appears_in('debug', component)
Example #28
0
def test_missing_action():
    logger = FakeLogger()
    config_name = 'missing'

    result = snmp_trap_handler.determine_action(
        oid=config_name,
        oid_lookup=mock.Mock(),
        logger=logger,
    )

    assert result is None

    expected_path = CONF_PATH.format(oid=config_name)
    assert logger.string_appears_in('debug', expected_path)

    assert 'not found' in logger.messages['warn'][-1]
def test_check_name():
    logger = FakeLogger()

    target_type = 'target'
    trap_value = 'trap'
    expected = '{target_type}_instances:SNMPTRAP {trap}'.format(
        target_type=target_type,
        trap=trap_value,
    )

    result = snmp_trap_handler.get_check_name(target_type, trap_value, logger)

    assert result == expected

    assert logger.string_appears_in('debug',
                                    ('check name', 'is', expected.lower()))
Example #30
0
def test_empty_action():
    logger = FakeLogger()
    config_name = 'empty'

    with pytest.raises(ValueError):
        snmp_trap_handler.determine_action(
            oid=config_name,
            oid_lookup=mock.Mock(),
            logger=logger,
        )

    expected_path = CONF_PATH.format(oid=config_name)
    assert logger.string_appears_in('debug', expected_path)

    assert 'not' in logger.messages['exception'][-1]
    assert 'JSON' in logger.messages['exception'][-1]
    assert 'empty' in logger.messages['exception'][-1]