16 Commits

Author SHA1 Message Date
139e675794 1231 2026-04-25 12:31:18 +03:00
8c59d94aff 1712 2026-04-24 17:12:46 +03:00
04ab48c314 1711 2026-04-24 17:11:43 +03:00
b1f6de5c65 1703 2026-04-24 17:03:55 +03:00
773a74c27c 0805 2026-04-23 08:05:08 +03:00
98d3e57737 0744 2026-04-23 07:44:11 +03:00
c41ae67ee8 1947 2026-04-22 19:47:44 +03:00
81964183e8 1347 2026-04-08 13:47:31 +03:00
7289430fc3 1335 2026-04-08 13:35:57 +03:00
651e4dc1bc 171 2026-04-08 02:50:05 +03:00
7e624e48f8 0538 2026-04-07 05:38:48 +03:00
a60b8c7012 0951 2026-04-06 09:51:11 +03:00
5f29ea2e1d 0830 2026-04-05 08:30:03 +03:00
7540952328 1739 2026-04-04 17:39:56 +03:00
26908890be 2022 2026-04-03 20:22:59 +03:00
1571f70ddd 2011 2026-04-03 20:11:33 +03:00
3 changed files with 95 additions and 36 deletions

31
docker-compose-old.yml Normal file
View File

@@ -0,0 +1,31 @@
services:
nats-registration-listener:
build:
context: .
dockerfile: Dockerfile
image: nats-registration-listener:latest
# Share host network so 'localhost:4222' talks to NATS on the host (if that's your setup)
network_mode: host
working_dir: /opt/containers/nats-registration-listener/app
# entrypoint: ["/usr/bin/tini", "--", "/bin/bash", "-lc", "/usr/local/bin/nats-registration-entrypoint"]
entrypoint: ["/usr/bin/tini","--","/bin/bash","-lc","/usr/local/bin/nats-registration-entrypoint"]
# command: ["/opt/containers/nats-registration-listener/app/bin/nats-registration-listener.sh"]
restart: unless-stopped
tty: true
stdin_open: true
# One .env to rule them all
env_file:
- .env
volumes:
- ./data:/opt/containers/nats-registration-listener/data:rw
healthcheck:
test: ["CMD-SHELL", "/usr/local/bin/nats-registration-healthcheck"]
interval: 30s
timeout: 10s
retries: 5

View File

@@ -1,31 +1,50 @@
services:
nats-registration-listener:
nats-registration-listener-even:
build:
context: .
dockerfile: Dockerfile
image: nats-registration-listener:latest
# Share host network so 'localhost:4222' talks to NATS on the host (if that's your setup)
network_mode: host
working_dir: /opt/containers/nats-registration-listener/app
# entrypoint: ["/usr/bin/tini", "--", "/bin/bash", "-lc", "/usr/local/bin/nats-registration-entrypoint"]
entrypoint: ["/usr/bin/tini","--","/bin/bash","-lc","/usr/local/bin/nats-registration-entrypoint"]
# command: ["/opt/containers/nats-registration-listener/app/bin/nats-registration-listener.sh"]
restart: unless-stopped
tty: true
stdin_open: true
# One .env to rule them all
environment:
EVENT_LOG_PATH: "/opt/containers/nats-registration-listener/logs/registration_events_even.jsonl"
EVENODD: "even"
env_file:
- .env
volumes:
- ./data:/opt/containers/nats-registration-listener/data:rw
- ./logs:/opt/containers/nats-registration-listener/logs:rw
healthcheck:
test: ["CMD-SHELL", "/usr/local/bin/nats-registration-healthcheck"]
interval: 30s
timeout: 10s
retries: 5
nats-registration-listener-odd:
build:
context: .
dockerfile: Dockerfile
image: nats-registration-listener:latest
network_mode: host
working_dir: /opt/containers/nats-registration-listener/app
entrypoint: ["/usr/bin/tini","--","/bin/bash","-lc","/usr/local/bin/nats-registration-entrypoint"]
restart: unless-stopped
tty: true
stdin_open: true
environment:
EVENT_LOG_PATH: "/opt/containers/nats-registration-listener/logs/registration_events_odd.jsonl"
EVENODD: "odd"
env_file:
- .env
volumes:
- ./data:/opt/containers/nats-registration-listener/data:rw
- ./logs:/opt/containers/nats-registration-listener/logs:rw
healthcheck:
test: ["CMD-SHELL", "/usr/local/bin/nats-registration-healthcheck"]
interval: 30s
timeout: 10s
retries: 5

View File

@@ -61,7 +61,7 @@ RMQ_TIMEOUT = 5.0
# ---- Human-editable delay (milliseconds). Set to 0 to disable delay.
# Example: 600000 = 10 minutes
RMQ_DELAY_MS = 15000
RMQ_DELAY_MS = 300000
# Posture analyzer gate: skip re-running sot-updater-scheduler if recently run (seconds)
posture_analyzer = "sot-updater-scheduler"
@@ -79,29 +79,14 @@ PRODUCT_TAG_SLUG = {
# MACs to ignore completely when seen in registrations
IGNORE_MACS_RAW = [
"AA:BB:CC:DD:EE:FF",
"D0:6C:37:01:26:02",
"D0:6C:37:01:25:B2",
"D0:6C:37:01:25:EA",
"D0:6C:37:01:25:F2",
"D0:6C:37:01:26:02",
"D0:6C:37:01:26:1E",
"D0:6C:37:01:26:3A",
"D0:6C:37:01:26:D2",
"D0:6C:37:01:26:D6",
"D0:6C:37:01:26:E2",
"D0:6C:37:01:0C:C0",
"D0:6C:37:00:91:88",
"C4:93:00:4E:96:0C",
"D0:6C:37:01:0C:78",
"C4:93:00:51:9A:12",
"D0:6C:37:00:BD:B0",
"C4:93:00:4E:97:B0",
#"D0:6C:37:00:A9:68",
"D0:6C:37:00:B0:1C",
"C4:93:00:4E:96:F0",
"D0:6C:37:00:B6:1C",
"D0:6C:37:00:EA:40",
"D0:6C:37:01:06:BC",
"D0:6C:37:01:4A:25",
"C4:93:00:4E:9E:C0", # 84823
"C4:93:00:4E:97:B0", # 6667
"D0:6C:37:01:26:D2", #NOT known for webapps
"D0:6C:37:01:0C:C0", #NOT known for webapps
"D0:6C:37:01:0C:7C", #NOT known for webapps
"d0:6c:37:00:b0:1c", # 101200 flaps a lot
"d0:6c:37:01:06:bc", #ikeja93929
]
# Global counter for any NetBox-related problems
@@ -111,6 +96,10 @@ NB_PROBLEM_LOCK = asyncio.Lock()
# Structured event log output (JSON Lines)
EVENT_LOG_PATH = os.environ.get("EVENT_LOG_PATH", "/opt/containers/nats-registration-listener/logs/registration_events.jsonl")
EVENODD = (os.environ.get("EVENODD", "") or "").strip().lower()
if EVENODD not in ("", "even", "odd"):
raise SystemExit("ERROR: EVENODD must be unset, 'even', or 'odd'")
# =========================
# Arg parsing
@@ -282,6 +271,18 @@ def normalize_mac(mac: str) -> Optional[str]:
return None
def mac_belongs_to_this_shard(mac_norm: Optional[str]) -> bool:
if EVENODD == "":
return True
if not mac_norm:
return True
md5_hex = hashlib.md5(mac_norm.encode("utf-8")).hexdigest()
last_nibble = int(md5_hex[-1], 16)
if EVENODD == "even":
return (last_nibble % 2) == 0
return (last_nibble % 2) == 1
IGNORE_MACS = {m for m in (normalize_mac(x) for x in IGNORE_MACS_RAW) if m}
@@ -570,11 +571,11 @@ async def main():
recent_payloads.pop(k, None)
product = mac = fw = "-"
obj = None
try:
text = payload.decode("utf-8", errors="replace")
obj = json.loads(text)
product, mac, fw = extract_fields(obj)
event["reg_age_s"] = extract_registration_age_s(obj)
except Exception:
pass
@@ -583,7 +584,15 @@ async def main():
event["fw"] = fw
mac_norm = normalize_mac(mac)
if not mac_belongs_to_this_shard(mac_norm):
return
event["mac_norm"] = mac_norm
if obj is not None:
try:
event["reg_age_s"] = extract_registration_age_s(obj)
except Exception:
pass
if mac_norm in IGNORE_MACS:
event["ignored"] = True
event["ignore_reason"] = "mac_ignore_list"