Kiali anonymous, журнал Helm, kubeconfig для контейнеров, UI аддонов

- Kiali: убран login, anonymous по умолчанию; удалены поля логина/пароля из UI и API
- Журнал Helm: install/upgrade/delete, message и колонка в journal.js
- Аддоны: values свёрнуты при подгрузке для установленных
- GET …/kubeconfig/docker: host.docker.internal:порт + tls-server-name; кнопка в UI
- apply_apiserver_endpoint_to_kubeconfig_file; KIND_K8S_APISERVER_GATEWAY_HOST в compose/env.example
- README и api_routes.md обновлены
This commit is contained in:
Sergey Antropoff
2026-04-04 18:54:10 +03:00
parent 349b78d24d
commit 4b703801e1
13 changed files with 415 additions and 123 deletions
+55 -1
View File
@@ -66,7 +66,11 @@ from core.job_store import (
from core.provision_log import provision_log_file_path, write_cluster_provision_log
from core.kind_guard import kind_cluster_lock
from kind_k8s_paths import clusters_dir
from kubeconfig_patch import kubeconfig_host_file, patch_kubeconfig_server_for_host
from kubeconfig_patch import (
kubeconfig_host_file,
patch_kubeconfig_server_for_docker_network,
patch_kubeconfig_server_for_host,
)
from models.schemas import (
AggregateResourcesSummary,
ClusterConfigGetResponse,
@@ -351,6 +355,56 @@ async def put_cluster_config(name: str, body: ClusterConfigUpdateRequest) -> Clu
)
@router.get(
"/clusters/{name}/kubeconfig/docker",
summary="Скачать kubeconfig для kubectl из другого контейнера (host.docker.internal:порт + SNI)",
responses={404: {"description": "Файл не найден"}, 500: {"description": "Ошибка подготовки файла"}},
)
async def download_kubeconfig_docker_network(name: str) -> FileResponse:
"""
Kubeconfig как для **kubectl внутри веб-контейнера**: ``https://<шлюз>:<порт>`` (по умолчанию
**host.docker.internal** и порт из ``docker port … 6443``) плюс **tls-server-name** (обычно **localhost**).
Доступен из **любого** контейнера, где резолвится шлюз (на Linux: ``extra_hosts: host.docker.internal:host-gateway``).
Запасной вариант без порта на хосте — ``https://<имя>-control-plane:6443`` (нужна общая сеть с kind).
Копия ``clusters/<имя>/kubeconfig`` с подстановкой ``server`` / ``tls-server-name`` (см. ``kubeconfig_patch.py``).
"""
if not validate_cluster_name(name):
raise HTTPException(status_code=400, detail="Некорректное имя кластера")
n = name.strip()
primary = clusters_dir() / n / "kubeconfig"
if not primary.is_file():
raise HTTPException(status_code=404, detail="kubeconfig не найден")
fd, tmp_name = tempfile.mkstemp(suffix=".yaml", prefix="kind-k8s-kube-docker-")
os.close(fd)
tmp_path = Path(tmp_name)
try:
shutil.copyfile(primary, tmp_path, follow_symlinks=True)
except OSError as e:
tmp_path.unlink(missing_ok=True)
logger.warning("Копирование kubeconfig (docker network): %s", e)
raise HTTPException(status_code=500, detail="Не удалось подготовить kubeconfig") from e
patched = await asyncio.to_thread(
partial(patch_kubeconfig_server_for_docker_network, cluster_name=n, kube_path=tmp_path),
)
if not patched:
tmp_path.unlink(missing_ok=True)
raise HTTPException(
status_code=500,
detail="Не удалось подготовить kubeconfig для контейнера (kubectl config set-cluster / tls-server-name)",
)
logger.info("Отдача kubeconfig (docker network) для кластера %s", n)
return FileResponse(
path=str(tmp_path),
filename=f"kubeconfig-docker-{n}.yaml",
media_type="application/x-yaml",
background=BackgroundTask(_unlink_temp_kubeconfig, tmp_path),
)
@router.get(
"/clusters/{name}/kubeconfig",
summary="Скачать kubeconfig",