Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add raise_error and log_error option to insert_hosts_to_meta filter #197

Merged
merged 1 commit into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion extensions/eda/plugins/event_filter/insert_hosts_to_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
string but contains multiple hosts, use this parameter to
delimits the hosts. Treat the vale as a single host if the
parameter is not present.
raise_error: Whether raise PathNotExistError if host_path does not
exist in the event. Default to false.
It is recommended to turn it on during the rulebook
development time. You can then turn it off for production.
log_error: Whether log an error message if host_path does not
exist in the event. Default to true.
You can turn if off if it is expected to have events not
having the host_path to avoid noises in the log.

Example:
-------
Expand All @@ -22,30 +30,47 @@
host_path: "app.target"
path_separator: "."
host_separator: ";"
raise_error: true
log_error: true

"""

from __future__ import annotations

import logging
from typing import Any

import dpath

LOGGER = logging.getLogger(__name__)


class PathNotExistError(Exception):
"""Cannot find the path in the event."""


def main(
event: dict[str, Any],
host_path: str | None = None,
host_separator: str | None = None,
path_separator: str = ".",
*,
raise_error: bool = False,
log_error: bool = True,
) -> dict[str, Any]:
"""Extract hosts from event data and insert into meta dict."""
if not host_path:
return event

try:
hosts = dpath.get(event, host_path, path_separator)
except KeyError:
except KeyError as error:
# does not contain host
msg = f"Event {event} does not contain {host_path}"
if log_error:
LOGGER.error(msg) # noqa: TRY400
if raise_error:
Alex-Izquierdo marked this conversation as resolved.
Show resolved Hide resolved
raise PathNotExistError(msg) from error
return event

if isinstance(hosts, str):
Expand Down
7 changes: 7 additions & 0 deletions extensions/eda/plugins/event_source/webhook.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
An ansible-rulebook event source module for receiving events via a webhook.
The message must be a valid JSON object.
The body received from the webhook post is placed under the key payload in
the data pushed to the event queue. Do not expect the host(s) in the path
"payload.meta.limit" will be automatically used to limit an ansible action
running on these hosts. Use insert_hosts_to_meta filter instead. See
https://ansible.readthedocs.io/projects/rulebook/en/latest/host_limit.html
for more details.
Arguments:
---------
host: The hostname to listen to. Defaults to 0.0.0.0 (all interfaces)
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/event_filter/test_insert_hosts_to_meta.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest

from extensions.eda.plugins.event_filter.insert_hosts_to_meta import PathNotExistError
from extensions.eda.plugins.event_filter.insert_hosts_to_meta import main as hosts_main

EVENT_DATA_1 = [
Expand Down Expand Up @@ -66,3 +67,16 @@ def test_find_hosts(data, args, expected_hosts):
def test_fail_find_hosts(data, args):
with pytest.raises(TypeError):
hosts_main(data, **args)


def test_host_path_not_exist():
event = {"app": {"target": 5000}}
host_path = "app.bad"
assert hosts_main(event, host_path=host_path) == event


def test_host_path_not_exist_exception():
event = {"app": {"target": 5000}}
host_path = "app.bad"
with pytest.raises(PathNotExistError):
hosts_main(event, host_path=host_path, raise_error=True)
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ basepython = python3.9, python3.10

[testenv:ruff]
deps = -r{toxinidir}/lint_requirements.txt
commands = ruff check --select ALL --ignore INP001,RUF100,FA102 -q extensions/eda/plugins
commands = ruff check --select ALL --ignore INP001,RUF100,FA102,PLR0913 -q extensions/eda/plugins

[testenv:darglint]
deps = darglint
Expand Down
Loading