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:
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user