Веб-UI: темы, навигация API, статистика и доработки API
- Шапка: логотип Kubernetes, ссылка на главную, выпадающее меню API (Swagger/ReDoc/Health), переключатель светлой/тёмной темы (localStorage). - Светлая тема в синей гамме; выравнивание кнопки темы в ряду с пилюлями. - Дашборд: единая карточка ошибки health/stats, подсказка Docker/Podman, поле container_cli в GET /stats, total_workers_from_meta всегда число (0 без meta). - Правки кластеров, job_store, compose, документация и частичные шаблоны.
This commit is contained in:
+32
-1
@@ -54,6 +54,10 @@ class ClusterSummary(BaseModel):
|
||||
|
||||
name: str
|
||||
registered_in_kind: bool
|
||||
kind_nodes_running: bool = Field(
|
||||
default=False,
|
||||
description="Запущены контейнеры узлов kind (имя-control-plane, имя-worker…; docker/podman ps)",
|
||||
)
|
||||
has_local_kubeconfig: bool
|
||||
meta: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
@@ -78,12 +82,35 @@ class KindClusterResources(BaseModel):
|
||||
note: str | None = Field(default=None, description="Пояснение, если узлов нет или ошибка списка")
|
||||
|
||||
|
||||
class AggregateResourcesSummary(BaseModel):
|
||||
"""Сводка по всем запущенным узлам kind для донат-диаграмм на главной."""
|
||||
|
||||
nodes_count: int = Field(0, description="Число учтённых контейнеров-нод")
|
||||
cpu_ring: float = Field(0, ge=0, le=100, description="Заполнение кольца «средний CPU», 0–100")
|
||||
cpu_label: str = Field("—", description="Подпись в центре доната")
|
||||
memory_percent_ring: float = Field(0, ge=0, le=100)
|
||||
memory_percent_label: str = Field("—")
|
||||
memory_used_ratio_ring: float = Field(0, ge=0, le=100, description="Доля занятой RAM от лимита по строке MemUsage")
|
||||
memory_used_ratio_label: str = Field("—")
|
||||
network_ring: float = Field(0, ge=0, le=100, description="Индикатор суммарного сетевого I/O (условная шкала)")
|
||||
network_label: str = Field("—")
|
||||
disk_ring: float = Field(0, ge=0, le=100, description="Индикатор суммарного блочного I/O")
|
||||
disk_label: str = Field("—")
|
||||
|
||||
|
||||
class StatsResponse(BaseModel):
|
||||
"""Краткая статистика для дашборда."""
|
||||
|
||||
container_cli: str = Field(
|
||||
description="CLI движка контейнеров (docker или podman): узлы kind и метрики собираются через него",
|
||||
)
|
||||
kind_clusters_count: int
|
||||
local_cluster_dirs_count: int
|
||||
total_workers_from_meta: int | None
|
||||
total_workers_from_meta: int = Field(
|
||||
0,
|
||||
ge=0,
|
||||
description="Сумма worker_nodes по meta.json каталогов; 0 если ни в одном meta нет поля или данных",
|
||||
)
|
||||
jobs_total: int
|
||||
jobs_recent_failed: int
|
||||
cluster_resources: list[KindClusterResources] = Field(
|
||||
@@ -94,6 +121,10 @@ class StatsResponse(BaseModel):
|
||||
default=None,
|
||||
description="Глобальная ошибка сбора метрик (например CLI не найден)",
|
||||
)
|
||||
aggregate_cluster_resources: AggregateResourcesSummary = Field(
|
||||
default_factory=AggregateResourcesSummary,
|
||||
description="Агрегаты по узлам для донатов на главной странице",
|
||||
)
|
||||
|
||||
|
||||
class ClusterWorkloadsResponse(BaseModel):
|
||||
|
||||
Reference in New Issue
Block a user