Initial commit: add compliance_checks table, per-check metadata on assets, and compliance audit trail

This commit is contained in:
2026-04-24 07:14:27 +03:00
commit e63b486ec2
58 changed files with 6468 additions and 0 deletions

View File

@@ -0,0 +1,164 @@
"""
Dell asset lookup service.
Two modes (chosen automatically):
1. **No credentials** Returns a partial pre-fill (brand=Dell, OS default, service_tag).
Model and warranty must be filled in manually; a link to Dell's support page is provided.
Dell's public website is protected by Akamai and cannot be scraped reliably.
2. **TechDirect API** Full data including model, warranty dates, serial number.
Register free at https://tdm.dell.com → API Services → Create an API key pair.
Set DELL_CLIENT_ID and DELL_CLIENT_SECRET in your .env file.
"""
import logging
from datetime import datetime
import requests
from flask import current_app
log = logging.getLogger(__name__)
_TOKEN_URL = "https://apigtwb2c.us.dell.com/auth/oauth/v2/token"
_ASSET_URL = "https://apigtwb2c.us.dell.com/PROD/sbil/eapi/v5/asset-entitlements"
_SUPPORT_PAGE = "https://www.dell.com/support/home/en-us/product-support/servicetag/{tag}/overview"
_TYPE_MAP = [
(["latitude", "inspiron", "xps", "vostro", "precision 5", "precision 7"], "Laptop"),
(["optiplex", "precision tower", "precision 3", "precision 9",
"optiplex micro", "optiplex small"], "Desktop"),
(["poweredge", "server"], "Server"),
(["wyse", "thin client"], "Other"),
(["monitor", "display", "screen", "s24", "s27", "p24", "u27"], "Monitor"),
]
def _detect_type(description: str) -> str:
desc = description.lower()
for keywords, asset_type in _TYPE_MAP:
if any(kw in desc for kw in keywords):
return asset_type
return "Laptop" # sensible default for Dell business hardware
# ------------------------------------------------------------------
# Partial pre-fill (no credentials)
# ------------------------------------------------------------------
def _partial_prefill(tag: str) -> dict:
"""
Return a minimal pre-fill dict using only what we know without querying Dell.
Includes a link to Dell's support page so the user can look up the rest.
"""
return {
"service_tag": tag,
"serial_number": "",
"brand": "Dell",
"model": "",
"asset_type": "Laptop",
"operating_system": "Windows 11 Pro",
"warranty_expiry": "",
"purchase_date": "",
"source": "partial",
"support_url": _SUPPORT_PAGE.format(tag=tag),
}
# ------------------------------------------------------------------
# Official TechDirect API (requires credentials)
# ------------------------------------------------------------------
def _get_token(client_id: str, client_secret: str) -> str:
resp = requests.post(
_TOKEN_URL,
data={
"grant_type": "client_credentials",
"client_id": client_id,
"client_secret": client_secret,
},
timeout=10,
)
resp.raise_for_status()
return resp.json()["access_token"]
def _lookup_api(tag: str, client_id: str, client_secret: str) -> dict:
try:
token = _get_token(client_id, client_secret)
except Exception as exc:
raise RuntimeError(f"Failed to obtain Dell API token: {exc}") from exc
try:
resp = requests.get(
_ASSET_URL,
params={"servicetags": tag},
headers={"Authorization": f"Bearer {token}"},
timeout=15,
)
resp.raise_for_status()
data = resp.json()
except Exception as exc:
raise RuntimeError(f"Dell API request failed: {exc}") from exc
if not data:
raise RuntimeError(f"No data returned for service tag '{tag}'.")
item = data[0] if isinstance(data, list) else data
system_desc = item.get("productLineDescription") or item.get("systemDescription") or ""
model = system_desc.strip()
serial_number = (item.get("serviceTag") or tag).upper()
warranty_expiry = None
for ent in (item.get("entitlements") or []):
end_str = ent.get("endDate") or ""
if end_str:
try:
dt = datetime.fromisoformat(end_str[:10])
if warranty_expiry is None or dt > warranty_expiry:
warranty_expiry = dt
except ValueError:
pass
ship_date = item.get("shipDate") or ""
purchase_date = None
if ship_date:
try:
purchase_date = datetime.fromisoformat(ship_date[:10])
except ValueError:
pass
return {
"service_tag": tag,
"serial_number": serial_number,
"brand": "Dell",
"model": model,
"asset_type": _detect_type(f"{system_desc} {item.get('productFamily', '')}"),
"operating_system": "Windows 11 Pro",
"warranty_expiry": warranty_expiry.strftime("%Y-%m-%d") if warranty_expiry else "",
"purchase_date": purchase_date.strftime("%Y-%m-%d") if purchase_date else "",
"source": "techdirect_api",
"support_url": _SUPPORT_PAGE.format(tag=tag),
}
# ------------------------------------------------------------------
# Public entry point
# ------------------------------------------------------------------
def lookup_service_tag(service_tag: str) -> dict:
"""
Look up a Dell service tag.
Uses TechDirect API when DELL_CLIENT_ID + DELL_CLIENT_SECRET are configured;
otherwise returns a partial pre-fill with a link to Dell's support page.
"""
tag = service_tag.strip().upper()
client_id = current_app.config.get("DELL_CLIENT_ID", "")
client_secret = current_app.config.get("DELL_CLIENT_SECRET", "")
if client_id and client_secret:
log.debug("Dell lookup via TechDirect API for %s", tag)
return _lookup_api(tag, client_id, client_secret)
log.debug("Dell lookup returning partial pre-fill for %s (no API credentials)", tag)
return _partial_prefill(tag)