iac/docs/architecture/scan_ugmk.py

70 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Собирает матрицу «приложение UGMK -> используемый технологический сервис»
из манифестов base + d8-ugmk-prod. Только *.yaml, документацию не читаем."""
import re, pathlib, json, sys, io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8")
ROOT = pathlib.Path(r"C:\Users\user\PycharmProjects\infra\iac")
CLUSTER = "d8-ugmk-prod"
# 1. какие приложения подключены к кластеру
kust = (ROOT / "clusters" / CLUSTER / "kustomization.yaml").read_text(encoding="utf-8")
apps = sorted(set(re.findall(r"\.\./\.\./apps/([a-z0-9-]+)/" + CLUSTER, kust)))
# 2. маркеры использования технологических сервисов
MARKERS = {
"postgres": [r"POSTGRES_[A-Z]", r"DB__HOST", r"postgresql\.postgresql\.svc",
r"secrets/data/apps/[a-z0-9-]+/postgres"],
"rabbitmq": [r"RABBITMQ", r"AMQP__", r"rabbitmq\.rabbitmq\.svc"],
"kafka": [r"KAFKA", r"kafka\.kafka\.svc", r"BOOTSTRAP_SERVERS"],
"camunda": [r"ZEEBE", r"CAMUNDA"],
"s3": [r"S3__", r"S3_ENDPOINT", r"S3_ACCESS", r"S3_BUCKET"],
"redis": [r"REDIS_HOST", r"REDIS__", r"redis\.[a-z-]+\.svc"],
"vault": [r"vault\.hashicorp\.com/agent-inject"],
"oidc": [r"ZITADEL", r"JWKS", r"OIDC", r"jwt-public"],
}
def scan(app):
text = []
for sub in ("base", CLUSTER):
d = ROOT / "apps" / app / sub
if not d.is_dir():
continue
for f in d.rglob("*.yaml"):
text.append(f.read_text(encoding="utf-8", errors="replace"))
blob = "\n".join(text)
return {svc: any(re.search(p, blob) for p in pats) for svc, pats in MARKERS.items()}
matrix = {app: scan(app) for app in apps}
# 3. кто опубликован наружу через istio (destination host -> namespace)
istio_raw = (ROOT / "infrastructure" / "istio-config" / CLUSTER / "istio-config.yaml").read_text(encoding="utf-8")
# закомментированные маршруты не считаем развёрнутыми
istio = "\n".join(l for l in istio_raw.splitlines() if not l.lstrip().startswith("#"))
exposed = sorted(set(re.findall(r"service:\s*([a-z0-9-]+)\.([a-z0-9-]+)\.svc", istio)))
exposed_ns = sorted({ns for _, ns in exposed})
print("ПРИЛОЖЕНИЙ В КОНТУРЕ:", len(apps))
print()
hdr = ["app"] + list(MARKERS) + ["istio"]
print(" | ".join(h.ljust(9) for h in hdr))
print("-" * 110)
for app, row in matrix.items():
cells = [app.ljust(9)] + ["+".ljust(9) if row[s] else "".ljust(9) for s in MARKERS]
cells.append("+".ljust(9) if app in exposed_ns else "".ljust(9))
print(" | ".join(cells))
print()
print("ИТОГО потребителей на сервис:")
for s in MARKERS:
n = sum(1 for r in matrix.values() if r[s])
print(f" {s:10s} {n:2d}")
print(f" {'istio':10s} {len([a for a in apps if a in exposed_ns]):2d}")
print()
print("namespace, опубликованные через istio:", ", ".join(exposed_ns))
print()
print("ВСЕГО SERVING-СВЯЗЕЙ:", sum(sum(r.values()) for r in matrix.values()) + len([a for a in apps if a in exposed_ns]))
(pathlib.Path(sys.argv[1] if len(sys.argv) > 1 else "matrix.json")).write_text(
json.dumps({"apps": apps, "matrix": matrix, "exposed": exposed_ns}, ensure_ascii=False, indent=2),
encoding="utf-8")