Skip to content

Commit

Permalink
feat: add raise_exception option to insert_hosts_to_meta filter
Browse files Browse the repository at this point in the history
  • Loading branch information
bzwei committed Feb 20, 2024
1 parent 5807a9e commit 8aafd46
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
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 raise PathNotExistError 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,6 +30,8 @@
host_path: "app.target"
path_separator: "."
host_separator: ";"
raise_error: true
log_error: true
"""

Expand All @@ -30,22 +40,37 @@
from typing import Any

import dpath
import logging

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)
if raise_error:
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)

0 comments on commit 8aafd46

Please sign in to comment.