This commit is contained in:
2026-02-24 17:56:04 +02:00
parent 94e55887a7
commit c70fa140b8

View File

@@ -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