From c70fa140b824c4a2136fd55734b9560f6b4176ca Mon Sep 17 00:00:00 2001 From: pavel Date: Tue, 24 Feb 2026 17:56:04 +0200 Subject: [PATCH] 1756 --- files/nats_registration_listener.py | 56 +++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/files/nats_registration_listener.py b/files/nats_registration_listener.py index f8cd0b2..740aeb2 100644 --- a/files/nats_registration_listener.py +++ b/files/nats_registration_listener.py @@ -41,6 +41,10 @@ NB_URL = "http://netbox.gt-tiso.ikeja.co.za" # Base URL NB_TOKEN = "7648e4f5ee370cda7834682e61b47c2ee8e95623" # keep as provided NB_TIMEOUT = 3.0 # seconds per HTTP GET +# Cache for MAC -> NetBox lookup result (seconds). Keeps NetBox load down under chatty devices. +NB_LOOKUP_CACHE_TTL = float(os.environ.get("NB_LOOKUP_CACHE_TTL", "10.0")) +NB_LOOKUP_CACHE = {} # mac_norm -> (expires_monotonic, cached_tuple) + # ========================= # RabbitMQ hardcoded config # ========================= @@ -232,6 +236,22 @@ def nb_lookup_device_by_mac(mac: str, log_status) -> Tuple[ if not mac_norm: return None, None, None, None, None, None, None, None, None + # Step 0: short TTL cache (avoid repeated NetBox GETs for chatty devices) + if NB_LOOKUP_CACHE_TTL > 0: + nowm = monotonic() + cached = NB_LOOKUP_CACHE.get(mac_norm) + if cached: + exp, val = cached + if exp > nowm: + host, iface_id, dev_id, status_val, tag_slugs, action_next, action_last, action_next_timestamp, action_state = val + if tag_slugs is not None: + try: + tag_slugs = set(tag_slugs) + except Exception: + pass + return host, iface_id, dev_id, status_val, tag_slugs, action_next, action_last, action_next_timestamp, action_state + NB_LOOKUP_CACHE.pop(mac_norm, None) + base = NB_URL.rstrip("/") h = { "Accept": "application/json", @@ -240,7 +260,13 @@ def nb_lookup_device_by_mac(mac: str, log_status) -> Tuple[ } # Step 1: MAC lookup - data, code = http_get_json(f"{base}/api/dcim/mac-addresses/", params={"mac_address": mac_norm, "limit": "2"}, headers=h) + data, code = http_get_json( + f"{base}/api/dcim/mac-addresses/", + params={"mac_address": mac_norm, "limit": "2", "fields": "assigned_object_type,assigned_object_id"}, + headers=h, + ) + if code == 400: + data, code = http_get_json(f"{base}/api/dcim/mac-addresses/", params={"mac_address": mac_norm, "limit": "2"}, headers=h) if code != 200 or not data: asyncio.create_task(nb_problem(log_status, f"[{ts()}] nb: mac query http={code} mac={mac_norm}")) return None, None, None, None, None, None, None, None, None @@ -265,7 +291,9 @@ def nb_lookup_device_by_mac(mac: str, log_status) -> Tuple[ return None, aoid, None, None, None, None, None, None, None # Step 2: Interface -> Device (shallow) - iface, code2 = http_get_json(f"{base}/api/dcim/interfaces/{aoid}/", headers=h) + iface, code2 = http_get_json(f"{base}/api/dcim/interfaces/{aoid}/", params={"fields": "device"}, headers=h) + if code2 == 400: + iface, code2 = http_get_json(f"{base}/api/dcim/interfaces/{aoid}/", headers=h) if code2 != 200 or not iface: asyncio.create_task(nb_problem(log_status, f"[{ts()}] nb: iface fetch http={code2} iface_id={aoid}")) return None, aoid, None, None, None, None, None, None, None @@ -278,7 +306,9 @@ def nb_lookup_device_by_mac(mac: str, log_status) -> Tuple[ return None, aoid, None, None, None, None, None, None, None # Step 3: Device detail (single fetch for status, tags, custom_fields.*) - device, code3 = http_get_json(f"{base}/api/dcim/devices/{dev_id}/", headers=h) + device, code3 = http_get_json(f"{base}/api/dcim/devices/{dev_id}/", params={"fields": "status,tags,custom_fields"}, headers=h) + if code3 == 400: + device, code3 = http_get_json(f"{base}/api/dcim/devices/{dev_id}/", headers=h) if code3 != 200 or not device: # treat as "no extra info" return host, aoid, dev_id, None, None, None, None, None, None @@ -297,6 +327,26 @@ def nb_lookup_device_by_mac(mac: str, log_status) -> Tuple[ action_next_timestamp = cf.get("action_next_timestamp") action_state = cf.get("action_state") + # Step 4: populate cache (only on full success) + if NB_LOOKUP_CACHE_TTL > 0: + try: + NB_LOOKUP_CACHE[mac_norm] = ( + monotonic() + NB_LOOKUP_CACHE_TTL, + ( + host, + aoid, + dev_id, + (status_val if isinstance(status_val, str) else None), + (tuple(tag_slugs) if tag_slugs is not None else None), + action_next, + action_last, + action_next_timestamp, + action_state, + ), + ) + except Exception: + pass + return host, aoid, dev_id, (status_val if isinstance(status_val, str) else None), tag_slugs, action_next, action_last, action_next_timestamp, action_state