17:27
This commit is contained in:
@@ -4,23 +4,22 @@ nb_sync_one_device.py
|
|||||||
|
|
||||||
Update a single NetBox device from Cloud by hostname — ONLY if device is online.
|
Update a single NetBox device from Cloud by hostname — ONLY if device is online.
|
||||||
|
|
||||||
Flow
|
Behavior
|
||||||
1) Input: hostname (positional arg).
|
- Liveness gate via /v1/devices/{cloud_id}/liveness (no changes if offline).
|
||||||
2) NetBox: lookup device by name -> read custom_fields.cloud_id.
|
- Updates NetBox fields from Cloud:
|
||||||
3) Cloud: GET /v1/devices/{cloud_id}/liveness; if isConnected == false -> exit with "device is not online".
|
custom_fields.fw_version ← firmwareVersion
|
||||||
4) Cloud: GET /v1/devices/{cloud_id} -> read firmwareVersion, ipAddress, nodeName, sectorName, smallCellName, serialNumber.
|
custom_fields.nodeName ← nodeName
|
||||||
5) NetBox updates (idempotent by default):
|
custom_fields.sectorName ← sectorName
|
||||||
- custom_fields.fw_version ← firmwareVersion
|
custom_fields.smallCellName ← smallCellName
|
||||||
- custom_fields.nodeName ← nodeName
|
serial ← serialNumber
|
||||||
- custom_fields.sectorName ← sectorName
|
- IP handling:
|
||||||
- custom_fields.smallCellName ← smallCellName
|
If Cloud ipAddress is valid (not None/""/"0.0.0.0"):
|
||||||
- serial ← serialNumber
|
ensure eth0, ensure/create IP, MOVE from other device if needed, set primary_ip4,
|
||||||
6) IP handling (only when online):
|
then PRUNE all other IPs on this device (default).
|
||||||
- If Cloud ipAddress is valid (not None/""/"0.0.0.0"):
|
If Cloud ipAddress is placeholder/invalid:
|
||||||
ensure eth0, ensure/create IP, MOVE if needed, set primary_ip4,
|
skip IP changes and do not prune.
|
||||||
then PRUNE all other IPs on the device (default behavior).
|
- --chatty logs step-by-step to stderr; stdout remains one-line OK/FAIL.
|
||||||
- If Cloud ipAddress is placeholder/invalid: skip IP changes and keep NetBox IPs as-is.
|
- NEW: Logs custom field cf_upgrade_cmd as `NB: upgrade_cmd=<value>` when --chatty.
|
||||||
7) Single-line OK/FAIL and proper exit code.
|
|
||||||
|
|
||||||
Exit codes:
|
Exit codes:
|
||||||
0 = success
|
0 = success
|
||||||
@@ -185,12 +184,10 @@ class NetBox:
|
|||||||
|
|
||||||
# --- Helpers for pruning ---
|
# --- Helpers for pruning ---
|
||||||
def list_device_ips(self, dev_id: int) -> List[Dict]:
|
def list_device_ips(self, dev_id: int) -> List[Dict]:
|
||||||
# Try device_id filter (NetBox ≥3.6); otherwise fall back via interface scan
|
|
||||||
r = S_NB.get(self._url("/api/ipam/ip-addresses/"), headers=self._h(),
|
r = S_NB.get(self._url("/api/ipam/ip-addresses/"), headers=self._h(),
|
||||||
params={"device_id": dev_id, "limit": 1000}, timeout=REQ_TIMEOUT)
|
params={"device_id": dev_id, "limit": 1000}, timeout=REQ_TIMEOUT)
|
||||||
if r.status_code == 200:
|
if r.status_code == 200:
|
||||||
return r.json().get("results") or []
|
return r.json().get("results") or []
|
||||||
# Fallback path
|
|
||||||
ips: List[Dict] = []
|
ips: List[Dict] = []
|
||||||
r2 = S_NB.get(self._url("/api/dcim/interfaces/"), headers=self._h(),
|
r2 = S_NB.get(self._url("/api/dcim/interfaces/"), headers=self._h(),
|
||||||
params={"device_id": dev_id, "limit": 1000}, timeout=REQ_TIMEOUT)
|
params={"device_id": dev_id, "limit": 1000}, timeout=REQ_TIMEOUT)
|
||||||
@@ -254,6 +251,11 @@ def run(hostname: str) -> None:
|
|||||||
dev_id = dev["id"]
|
dev_id = dev["id"]
|
||||||
dev_full = nb.get_device(dev_id)
|
dev_full = nb.get_device(dev_id)
|
||||||
cf = dev_full.get("custom_fields") or {}
|
cf = dev_full.get("custom_fields") or {}
|
||||||
|
|
||||||
|
# NEW: log upgrade command if present
|
||||||
|
upgrade_cmd = cf.get("cf_upgrade_cmd")
|
||||||
|
log(f"NB: upgrade_cmd={upgrade_cmd}")
|
||||||
|
|
||||||
cloud_id = cf.get("cloud_id")
|
cloud_id = cf.get("cloud_id")
|
||||||
if cloud_id in (None, "", "null"):
|
if cloud_id in (None, "", "null"):
|
||||||
die(1, f"FAIL {hostname} has no custom_fields.cloud_id in NetBox")
|
die(1, f"FAIL {hostname} has no custom_fields.cloud_id in NetBox")
|
||||||
|
|||||||
Reference in New Issue
Block a user