From 970fa6e0a49d6b32befbc6425d84da66772907d6 Mon Sep 17 00:00:00 2001 From: pavel Date: Fri, 31 Oct 2025 06:38:41 +0200 Subject: [PATCH] 06:38 --- files/nats_registration_listener.py | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/files/nats_registration_listener.py b/files/nats_registration_listener.py index 06c28e0..dc21937 100644 --- a/files/nats_registration_listener.py +++ b/files/nats_registration_listener.py @@ -2,16 +2,9 @@ """ NATS Registration Listener (fox100 + NetBox hostname/tag lookup + timing + problem counter) ------------------------------------------------------------------------------------------- -Removes duplicate device GET: - - Single /devices/{id}/ fetch provides both status and tags. - -Adds/keeps: - - nb_problems= prefix on every stdout line - - For product=fox100: MAC -> interface -> device lookup in NetBox (urllib only) - - Device tag check for slug 'fox100-auto-upgrade-latest' when status=active - - If tag present & active: append "action=ok, i'm ready to schedule this device upgrade" - - Measures per-fox100 NetBox lookup duration (netbox_ms) and total latency (total_ms) - - Increments problem counter for NetBox anomalies, includes iface_id where applicable +- One device GET (status + tags), no duplicate fetch +- On tag match (and status=active), prepend ASCII BEL to stdout line to alert +- Keeps: nb_problems counter, timings, iface_id diagnostics, same formatting """ import argparse @@ -213,10 +206,10 @@ def nb_lookup_device_by_mac(mac: str, log_status) -> Tuple[Optional[str], Option asyncio.create_task(nb_problem(log_status, f"[{ts()}] nb: iface has no device iface_id={aoid}")) return None, aoid, None, None, None - # Step 3: Device detail (single fetch now provides BOTH status and tags) + # Step 3: Device detail (single fetch for BOTH status and tags) device, code3 = http_get_json(f"{base}/api/dcim/devices/{dev_id}/", headers=h) if code3 != 200 or not device: - # treat as "no tag info" (no problem increment per Pavel's guidance) + # treat as "no tag info" (no problem increment) return host, aoid, dev_id, None, None status_val = ((device.get("status") or {}).get("value")) or None @@ -302,6 +295,7 @@ async def main(): host_suffix = "" action_suffix = "" + bell_prefix = "" # ASCII BEL when we have a tag match netbox_time_ms = 0.0 desired_slug = PRODUCT_TAG_SLUG.get(product) @@ -314,9 +308,11 @@ async def main(): if iface_id and not host: host_suffix += f" iface_id={iface_id}" - # Only attempt the tag-based action if we have device info and it's active + # Tag-based action if dev_id is not None and status_val == "active" and isinstance(desired_slug, str) and isinstance(tag_slugs, set): if desired_slug in tag_slugs: + # Beep to draw attention + bell_prefix = "\a" action_suffix = f" action=ok, i'm ready to schedule this device {host if host else dev_id} upgrade" except Exception as e: await nb_problem(log_status, f"[{ts()}] nb: unexpected error mac={mac!r} err={e!r}") @@ -334,7 +330,9 @@ async def main(): line += f" subject={msg.subject}" async with print_lock: - print(line, flush=True) + # Prepend BEL only when we had a tag match + sys.stdout.write(bell_prefix + line + "\n") + sys.stdout.flush() if args.queue: await nc.subscribe(args.subject, queue=args.queue, cb=message_handler)