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)
Example #2
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 #3
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 #4
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)
Example #5
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')
Example #6
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 #7
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 #8
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 #9
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')
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)
def test_trap_not_defined(nagios_utils, exit, snmp_utils, logging_utils):
    trap_name = 'missing'
    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

    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('info', 'no action')
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
Example #13
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 #14
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')
def test_get_good_rate(mock_print, mock_exit, mock_time, run, mock_json):
    mock_time.return_value = 100
    logger = FakeLogger()

    value = 42
    path = 'something'

    opener = FakeOpener()
    opener.write = mock.Mock()
    nagios_plugin_utils.open = opener.open

    mock_json.load.return_value = {
        'timestamp': 90,
        'result': 32,
    }

    expected = 1.0

    result = nagios_plugin_utils.store_value_and_calculate_rate(
        logger, value, path,
    )

    assert mock_exit.call_count == 0
    assert mock_print.call_count == 0

    assert result == expected
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)
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()))
def test_incomplete_opening_previous(mock_print, mock_exit, mock_time, run,
                                     mock_json):
    mock_time.return_value = 100
    logger = FakeLogger()

    value = 42
    path = 'something'

    opener = FakeOpener()
    opener.write = mock.Mock()
    nagios_plugin_utils.open = opener.open

    mock_json.load.return_value = {}

    with pytest.raises(SystemExit):
        nagios_plugin_utils.store_value_and_calculate_rate(
            logger, value, path,
        )

    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'previous' in mock_print_arg
    assert 'incomplete' in mock_print_arg
    assert 'cannot calculate' in mock_print_arg

    mock_exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_pre_seed():
    logger = FakeLogger()
    oid_lookup = mock.Mock()
    oid_lookup.get.side_effect = RuntimeError

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

    with pytest.raises(RuntimeError):
        snmp_trap_handler.normalise_oids_and_get_trap_value(
            raw_details=raw_details,
            oid_lookup=oid_lookup,
            logger=logger,
        )

    oid_lookup.get.assert_called_once_with([
        snmp_trap_handler.SNMP_TRAP_OID,
        'system.sysUpTime.0',
        'snmp.1.1.4.1.0',
    ])
Example #20
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_too_fast(mock_print, mock_exit, mock_time, run, mock_json):
    mock_time.return_value = 100
    logger = FakeLogger()

    value = 42
    path = 'something'

    opener = FakeOpener()
    opener.write = mock.Mock()
    nagios_plugin_utils.open = opener.open

    mock_json.load.return_value = {
        'timestamp': 100,
        'result': 52,
    }

    with pytest.raises(SystemExit):
        nagios_plugin_utils.store_value_and_calculate_rate(
            logger, value, path,
        )

    mock_print_arg = mock_print.call_args_list[0][0][0].lower()
    assert 'too recently' in mock_print_arg
    assert 'cannot calculate' in mock_print_arg

    mock_exit.assert_called_once_with(nagios_plugin_utils.STATUS_UNKNOWN)
def test_no_thresholds(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()
    logging_utils.Logger.return_value = logger

    returned_thresholds = 'thresholds'
    thresholds.return_value = returned_thresholds

    perfdata = 'theperfdata'
    get_perfdata.return_value = perfdata

    float_value = 1.234
    get_single_float.return_value = float_value

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

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

    check_thresholds_and_exit.assert_called_once_with(
        float_value,
        returned_thresholds,
        perfdata,
        False,
    )

    thresholds.assert_called_once_with("", "", "", "", logger)
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_generate_message_with_oid():
    logger = FakeLogger()

    trap_value = 'thetrap'
    expected_message_content = 'thismessage'
    action = {'oid_for_message': 'something'}
    details = {'something': expected_message_content}
    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, expected_message_content):
        assert component in result
        assert logger.string_appears_in('debug', component)
Example #25
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]
Example #26
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_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_thresholds(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

    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

    perfdata = 'performance_data'
    generate_perfdata.return_value = perfdata

    low_warn = 2
    low_crit = 1
    high_warn = 3
    high_crit = 4

    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, '--low-warning',
        text_type(low_warn), '--low-critical',
        text_type(low_crit), '--high-warning',
        text_type(high_warn), '--high-critical',
        text_type(high_crit)
    ])

    check_thresholds_and_exit.assert_called_once_with(
        mean,
        returned_thresholds,
        perfdata,
        False,
    )

    thresholds.assert_called_once_with(
        low_warn,
        low_crit,
        high_warn,
        high_crit,
        logger,
    )

    check_snmp_aggregate.APPROACHES['arithmetic_mean'] = old_calculate_mean
Example #29
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_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