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

Added state tracking and conditional event triggering for URL status … #212

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
40 changes: 28 additions & 12 deletions extensions/eda/plugins/event_source/url_check.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""url_check.py.
"""
url_check.py.

An ansible-rulebook event source plugin that polls a set of URLs and sends
events with their status.
Expand Down Expand Up @@ -26,30 +27,46 @@

OK = 200


async def main(queue: asyncio.Queue, args: dict[str, Any]) -> None:
"""Poll a set of URLs and send events with status."""
urls = args.get("urls", [])
delay = int(args.get("delay", 1))
verify_ssl = args.get("verify_ssl", True)

# Added initialization for client_error to handle cases where an exception occurs
client_error = ""

if not urls:
return

# Added url_states dictionary to track the last known status of each URL
url_states = {url: None for url in urls}

while True:
try:
async with aiohttp.ClientSession() as session:
for url in urls:
async with session.get(url, verify_ssl=verify_ssl) as resp:
await queue.put(
{
"url_check": {
"url": url,
"status": "up" if resp.status == OK else "down",
"status_code": resp.status,
},
try:
async with session.get(url, ssl=verify_ssl) as resp:
status = "up" if resp.status == OK else "down"
status_code = resp.status
except aiohttp.ClientError as exc:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think to set the status to "down" is not correct, since the ClientError can be raised by a variety of reasons that doesn't necessarily mean the url is down, like for example networking issues in the client side. This would be something that the plugin is already doing wrong in the upper try/except block.

Instead, I suggest a new option with "false" as default named for example "send_error_events" and send the ClientError as event if its set.

thoughts? @bzwei

status = "down"
status_code = None
client_error = str(exc)
# Only trigger event if the status has changed
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if that logic should be handled by the plugin and it would change the existing behavior so it could break existing rulebooks.

if url_states[url] != status:
url_states[url] = status
event = {
"url_check": {
"url": url,
"status": status,
"status_code": status_code,
},
)
}
if status == "down" and client_error:
event["url_check"]["error_msg"] = client_error
await queue.put(event)

except aiohttp.ClientError as exc:
client_error = str(exc)
Expand All @@ -65,7 +82,6 @@ async def main(queue: asyncio.Queue, args: dict[str, Any]) -> None:

await asyncio.sleep(delay)


if __name__ == "__main__":
"""MockQueue if running directly."""

Expand Down