Ejemplo n.º 1
0
def load_services(services):
    for service in services:
        service_plugins[service] = {}

        service_config = cf.config('config:' + service)
        if service_config is None:
            logger.error("Service `%s' has no config section" % service)
            sys.exit(1)

        service_plugins[service]['config'] = service_config

        module = cf.g('config:' + service, 'module', service)

        if '.' in module:
            try:
                service_plugins[service]['module'] = load_module_by_name(module)
                logger.info('Successfully loaded service "{}" from module "{}"'.format(service, module))
            except Exception as ex:
                logger.exception('Unable to load service "{}" from module "{}": {}'.format(service, module, ex))

        else:
            modulefile = resource_filename('mqttwarn.services', module + '.py')
            try:
                service_plugins[service]['module'] = load_module_from_file(modulefile)
                logger.info('Successfully loaded service "{}"'.format(service))
            except Exception as ex:
                logger.exception('Unable to load service "{}" from file "{}": {}'.format(service, modulefile, ex))
Ejemplo n.º 2
0
def test_apprise_multi_basic_success(apprise_asset, apprise_mock, srv, caplog):

    with caplog.at_level(logging.DEBUG):

        module = load_module_by_name("mqttwarn.services.apprise_multi")

        item = Item(
            addrs=[
                {
                    "baseuri": "json://localhost:1234/mqtthook"
                },
                {
                    "baseuri": "json://daq.example.org:5555/foobar"
                },
            ],
            title="⚽ Message title ⚽",
            message="⚽ Notification message ⚽",
        )

        outcome = module.plugin(srv, item)

        assert apprise_mock.mock_calls == [
            call(asset=mock.ANY),
            call().add("json://localhost:1234/mqtthook"),
            call().add("json://daq.example.org:5555/foobar"),
            call().notify(body="⚽ Notification message ⚽",
                          title="⚽ Message title ⚽"),
            call().notify().__bool__(),
        ]

        assert outcome is True
        assert (
            "Sending notification to Apprise. target=None, addresses=[{'baseuri': 'json://localhost:1234/mqtthook'}, {'baseuri': 'json://daq.example.org:5555/foobar'}]"
            in caplog.messages)
        assert "Successfully sent message using Apprise" in caplog.messages
Ejemplo n.º 3
0
def load_services(services):
    for service in services:
        service_plugins[service] = {}

        service_config = cf.config('config:' + service)
        if service_config is None:
            logger.error("Service `%s' has no config section" % service)
            sys.exit(1)

        service_plugins[service]['config'] = service_config

        module = cf.g('config:' + service, 'module', service)

        # Load external service from file.
        modulefile_candidates = []
        if module.endswith(".py"):
            # Add two candidates: a) Use the file as given and b) treat the file as relative to
            # the directory of the configuration file. That retains backward compatibility.
            modulefile_candidates.append(module)
            modulefile_candidates.append(os.path.join(cf.configuration_path, module))

        # Load external service with module specification.
        elif '.' in module:
            logger.debug('Trying to load service "{}" from module "{}"'.format(service, module))
            try:
                service_plugins[service]['module'] = load_module_by_name(module)
                logger.info('Successfully loaded service "{}" from module "{}"'.format(service, module))
                continue
            except Exception as ex:
                logger.exception('Unable to load service "{}" from module "{}": {}'.format(service, module, ex))

        # Load built-in service module.
        else:
            # Backward-compatibility patch for honoring the renaming of the `http.py` module.
            if module == "http":
                module = "http_urllib"
            logger.debug('Trying to load built-in service "{}" from "{}"'.format(service, module))
            modulefile_candidates = [ resource_filename('mqttwarn.services', module + '.py') ]

        success = False
        for modulefile in modulefile_candidates:
            if not os.path.isfile(modulefile):
                continue
            logger.debug('Trying to load service "{}" from file "{}"'.format(service, modulefile))
            try:
                service_plugins[service]['module'] = load_module_from_file(modulefile)
                logger.info('Successfully loaded service "{}"'.format(service))
                success = True
            except Exception as ex:
                logger.exception('Unable to load service "{}" from file "{}": {}'.format(service, modulefile, ex))

        if not success:
            logger.critical('Unable to load service "{}"'.format(service))
            sys.exit(1)
Ejemplo n.º 4
0
def test_apprise_multi_error(srv, caplog):

    with caplog.at_level(logging.DEBUG):

        mock_connection = mock.MagicMock()

        # Make the call to `notify` raise an exception.
        def error(*args, **kwargs):
            raise Exception("something failed")

        mock_connection.notify = error

        with mock.patch("apprise.Apprise",
                        side_effect=[mock_connection],
                        create=True) as mock_client:
            with mock.patch("apprise.AppriseAsset", create=True) as mock_asset:
                module = load_module_by_name("mqttwarn.services.apprise_multi")

                item = Item(
                    addrs=[{
                        "baseuri": "json://localhost:1234/mqtthook"
                    }],
                    title="⚽ Message title ⚽",
                    message="⚽ Notification message ⚽",
                )

                outcome = module.plugin(srv, item)

                assert mock_client.mock_calls == [
                    mock.call(asset=mock.ANY),
                ]
                assert mock_connection.mock_calls == [
                    call.add("json://localhost:1234/mqtthook"),
                ]

                assert outcome is False
                assert (
                    "Sending notification to Apprise. target=None, addresses=[{'baseuri': 'json://localhost:1234/mqtthook'}]"
                    in caplog.messages)
                assert (
                    "Sending message using Apprise failed. target=None, error=something failed"
                    in caplog.messages)
Ejemplo n.º 5
0
def test_amqp_failure(srv, caplog):
    module = load_module_by_name("mqttwarn.services.amqp")

    exchange, routing_key = ["name_of_exchange", "my_routing_key"]
    item = Item(
        config={"uri": "amqp://*****:*****@localhost:5672/"},
        target="test",
        addrs=[exchange, routing_key],
        message="⚽ Notification message ⚽",
    )

    with caplog.at_level(logging.DEBUG):

        mock_connection = mock.MagicMock()

        # Make the call to `basic_publish` raise an exception.
        def error(*args, **kwargs):
            raise Exception("something failed")

        mock_connection.basic_publish = error

        with mock.patch("puka.Client",
                        side_effect=[mock_connection],
                        create=True) as mock_client:

            outcome = module.plugin(srv, item)

            assert mock_client.mock_calls == [
                mock.call("amqp://*****:*****@localhost:5672/"),
            ]
            assert mock_connection.mock_calls == [
                call.connect(),
                call.wait(mock.ANY),
            ]

            assert outcome is False
            assert ("AMQP publish to test [name_of_exchange/my_routing_key]"
                    in caplog.text)
            assert (
                "Error on AMQP publish to test [name_of_exchange/my_routing_key]: something failed"
                in caplog.text)
Ejemplo n.º 6
0
def test_amqp_success(mock_puka_client, srv, caplog):
    module = load_module_by_name("mqttwarn.services.amqp")

    exchange, routing_key = ["name_of_exchange", "my_routing_key"]
    item = Item(
        config={"uri": "amqp://*****:*****@localhost:5672/"},
        target="test",
        addrs=[exchange, routing_key],
        message="⚽ Notification message ⚽",
    )

    with caplog.at_level(logging.DEBUG):

        outcome = module.plugin(srv, item)

        assert mock_puka_client.mock_calls == [
            mock.call("amqp://*****:*****@localhost:5672/"),
            call().connect(),
            call().wait(mock.ANY),
            call().basic_publish(
                exchange="name_of_exchange",
                routing_key="my_routing_key",
                headers={
                    "content_type": "text/plain",
                    "x-agent": "mqttwarn",
                    "delivery_mode": 1,
                },
                body="⚽ Notification message ⚽",
            ),
            call().wait(mock.ANY),
            call().close(),
        ]

        assert outcome is True
        assert "AMQP publish to test [name_of_exchange/my_routing_key]" in caplog.text
        assert "Successfully published AMQP notification" in caplog.text
Ejemplo n.º 7
0
def test_apprise_multi_mailto_success(apprise_asset, apprise_mock, srv,
                                      caplog):

    with caplog.at_level(logging.DEBUG):

        module = load_module_by_name("mqttwarn.services.apprise_multi")

        item = Item(
            addrs=[{
                "baseuri":
                "mailtos://*****:*****@mail.example.org",
                "recipients": ["*****@*****.**", "*****@*****.**"],
                "sender": "*****@*****.**",
                "sender_name": "Example Monitoring",
            }],
            title="⚽ Message title ⚽",
            message="⚽ Notification message ⚽",
        )

        outcome = module.plugin(srv, item)

        assert apprise_mock.mock_calls == [
            call(asset=mock.ANY),
            call().add(
                "mailtos://*****:*****@mail.example.org?to=foo%40example.org%2Cbar%40example.org&from=monitoring%40example.org&name=Example+Monitoring"
            ),
            call().notify(body="⚽ Notification message ⚽",
                          title="⚽ Message title ⚽"),
            call().notify().__bool__(),
        ]

        assert outcome is True
        assert (
            "Sending notification to Apprise. target=None, addresses=[{'baseuri': 'mailtos://*****:*****@mail.example.org', 'recipients': ['*****@*****.**', '*****@*****.**'], 'sender': '*****@*****.**', 'sender_name': 'Example Monitoring'}]"
            in caplog.messages)
        assert "Successfully sent message using Apprise" in caplog.messages
Ejemplo n.º 8
0
def test_load_module_by_name_bad():
    with pytest.raises(ImportError) as excinfo:
        load_module_by_name("mqttwarn.services.unknown")
        assert str(excinfo.value) == "ImportError: No module named unknown"
Ejemplo n.º 9
0
def test_load_module_by_name_good():
    module = load_module_by_name("mqttwarn.services.file")
    assert "plugin" in dir(module)
    assert module.plugin.__code__.co_argcount == 2
    assert "srv" in module.plugin.__code__.co_varnames
    assert "item" in module.plugin.__code__.co_varnames
Ejemplo n.º 10
0
def test_load_module_by_name_good():
    module = load_module_by_name('mqttwarn.services.file')
    assert 'plugin' in dir(module)
    assert module.plugin.__code__.co_argcount == 2
    assert 'srv' in module.plugin.__code__.co_varnames
    assert 'item' in module.plugin.__code__.co_varnames