UI: карточка установленных аддонов на странице кластера; API аддонов и правки стилей

- Отдельная section.card после сводки ресурсов узлов, выравнивание бейджа Helm с заголовком
- Расширение эндпоинтов аддонов, схемы, helm_addons, cluster_addons.js/html
- Обновление api_routes.md
This commit is contained in:
Sergey Antropoff
2026-04-04 14:13:01 +03:00
parent eb063aec20
commit d55e69c756
9 changed files with 1238 additions and 229 deletions
+65 -4
View File
@@ -22,7 +22,8 @@ from fastapi import APIRouter, Body, HTTPException
from core.cluster_lifecycle import validate_cluster_name
from core.helm_addons import (
HelmAddonError,
addon_status,
collect_installed_addons_values,
helm_addon_snapshot,
require_helm_binary,
install_ingress_nginx,
install_istio_and_kiali,
@@ -36,8 +37,11 @@ from core.helm_addons import (
from core.kind_guard import kind_cluster_lock
from core.provision_log import write_cluster_helm_addon_log
from models.schemas import (
ClusterAddonsInstalledValuesResponse,
ClusterAddonsStatusResponse,
HelmAddonApplyResponse,
InstalledAddonValuesBlob,
IstioKialiInstalledValuesBlob,
IngressNginxInstallRequest,
IstioKialiInstallRequest,
KubePrometheusStackInstallRequest,
@@ -151,10 +155,10 @@ async def get_cluster_addons_status(name: str) -> ClusterAddonsStatusResponse:
except HelmAddonError as e:
raise _map_helm_error(e) from e
try:
st = await asyncio.to_thread(addon_status, n)
st = await asyncio.to_thread(helm_addon_snapshot, n)
except HelmAddonError as e:
raise _map_helm_error(e) from e
mesh = bool(st.get("istio_base") and st.get("istiod") and st.get("kiali"))
mesh = bool(st.get("istio_mesh_ready"))
return ClusterAddonsStatusResponse(
cluster_name=n,
ingress_nginx=bool(st.get("ingress_nginx")),
@@ -162,8 +166,65 @@ async def get_cluster_addons_status(name: str) -> ClusterAddonsStatusResponse:
metrics_server=bool(st.get("metrics_server")),
istio_base=bool(st.get("istio_base")),
istiod=bool(st.get("istiod")),
kiali_server=bool(st.get("kiali")),
kiali_server=bool(st.get("kiali_server")),
istio_mesh_ready=mesh,
ingress_nginx_chart_version=st.get("ingress_nginx_chart_version"),
kube_prometheus_stack_chart_version=st.get("kube_prometheus_stack_chart_version"),
metrics_server_chart_version=st.get("metrics_server_chart_version"),
istiod_chart_version=st.get("istiod_chart_version"),
istio_base_chart_version=st.get("istio_base_chart_version"),
kiali_server_chart_version=st.get("kiali_server_chart_version"),
)
@router.get(
"/clusters/{name}/addons/installed-values",
response_model=ClusterAddonsInstalledValuesResponse,
summary="Values установленных аддонов из кластера (helm get values --all)",
)
async def get_cluster_addons_installed_values(name: str) -> ClusterAddonsInstalledValuesResponse:
"""
Для каждого установленного логического аддона возвращает версию чарта (как в ``helm list``)
и полный YAML эффективных values (``helm get values --all -o yaml``) для правки перед upgrade.
"""
n = name.strip()
if not validate_cluster_name(n):
raise HTTPException(status_code=400, detail="Некорректное имя кластера")
try:
require_helm_binary()
except HelmAddonError as e:
raise _map_helm_error(e) from e
try:
raw = await asyncio.to_thread(collect_installed_addons_values, n)
except HelmAddonError as e:
raise _map_helm_error(e) from e
def blob(key: str) -> InstalledAddonValuesBlob | None:
b = raw.get(key)
if not isinstance(b, dict):
return None
return InstalledAddonValuesBlob(
chart_version=b.get("chart_version"),
values_yaml=str(b.get("values_yaml") or ""),
)
istio = raw.get("istio_kiali")
istio_model: IstioKialiInstalledValuesBlob | None = None
if isinstance(istio, dict):
istio_model = IstioKialiInstalledValuesBlob(
istio_chart_version=istio.get("istio_chart_version"),
kiali_chart_version=istio.get("kiali_chart_version"),
istio_base_values_yaml=str(istio.get("istio_base_values_yaml") or ""),
istiod_values_yaml=str(istio.get("istiod_values_yaml") or ""),
kiali_values_yaml=str(istio.get("kiali_values_yaml") or ""),
)
return ClusterAddonsInstalledValuesResponse(
cluster_name=n,
ingress_nginx=blob("ingress_nginx"),
kube_prometheus_stack=blob("kube_prometheus_stack"),
metrics_server=blob("metrics_server"),
istio_kiali=istio_model,
)