Files
KindClustersDashboard/app/docs/api_routes.md
T
inecs 73ae5d7032 Веб-UI FastAPI, REST API v1, интерактивный setup без env.example
- Дашборд (Jinja2 + static), управление кластерами kind, задания и kubeconfig.
- API: health, stats, clusters CRUD, versions, jobs; документация app/docs/api_routes.md.
- Docker Compose: том app, uvicorn reload, KIND_K8S_PATCH_KUBECONFIG по умолчанию 1.
- setup_env_interactive.py: список переменных в скрипте, удалён env.example.
- Makefile: явный префикс docker/podman; прочие правки CLI и ядра кластеров.
2026-04-04 05:39:53 +03:00

6.6 KiB
Raw Blame History

Описание REST API веб-интерфейса kind-k8s-develop

Базовый префикс: /api/v1
Автор: Сергей Антропов — devops.org.ru

Интерактивная документация OpenAPI: после запуска make docker up откройте http://127.0.0.1:6000/docs.


GET /api/v1/health

Проверка: kind/kubectl в PATH и ответ движка контейнеров (docker info / podman info по CONTAINER_CLI).
status: ok — всё готово к созданию кластеров; degraded — чего-то не хватает (см. поля ниже).

Пример ответа 200 (JSON):

{
  "status": "ok",
  "kind_in_path": true,
  "kubectl_in_path": true,
  "container_cli": "docker",
  "container_engine_ok": true,
  "container_engine_detail": null
}

Если сокет Docker недоступен:

{
  "status": "degraded",
  "kind_in_path": true,
  "kubectl_in_path": true,
  "container_cli": "docker",
  "container_engine_ok": false,
  "container_engine_detail": "Cannot connect to the Docker daemon..."
}

GET /api/v1/versions

Список стабильных тегов kindest/node с Docker Hub (для выпадающего списка в UI).
При KIND_K8S_SKIP_VERSION_LIST=1 список пустой.

Пример ответа 200:

{
  "tags": ["v1.32.0", "v1.31.4"],
  "skipped": false
}

Пример при пропуске загрузки:

{
  "tags": [],
  "skipped": true,
  "reason": "KIND_K8S_SKIP_VERSION_LIST"
}

GET /api/v1/stats

Сводная статистика для дашборда.

Пример ответа 200:

{
  "kind_clusters_count": 2,
  "local_cluster_dirs_count": 2,
  "total_workers_from_meta": 4,
  "jobs_total": 5,
  "jobs_recent_failed": 1
}

Поле total_workers_from_meta может быть null, если ни в одном meta.json нет worker_nodes.


GET /api/v1/clusters

Список имён: объединение kind get clusters и подкаталогов clusters/*.

Пример ответа 200 (массив):

[
  {
    "name": "dev",
    "registered_in_kind": true,
    "has_local_kubeconfig": true,
    "meta": {
      "cluster_name": "dev",
      "kubernetes_version_tag": "v1.29.4",
      "node_image": "kindest/node:v1.29.4",
      "worker_nodes": 2,
      "kubeconfig_patched_for_host": true
    }
  }
]

GET /api/v1/jobs

Список последних фоновых заданий (создание кластера), от новых к старым. Данные только в памяти процесса.

Query: limit (1–200, по умолчанию 30).

Пример ответа 200 (массив JobView):

[
  {
    "job_id": "abc123",
    "kind": "create_cluster",
    "status": "success",
    "cluster_name": "dev",
    "created_at_utc": "2026-04-04T12:00:00+00:00",
    "message": "Кластер создан",
    "result": { "cluster_name": "dev", "kubernetes_version_tag": "v1.29.4" }
  }
]

GET /api/v1/clusters/{name}/kubeconfig

Скачать файл kubeconfig (ответ — тело файла, Content-Disposition с именем kubeconfig-{name}.yaml).

Ошибка 404: файла нет в clusters/{name}/.


GET /api/v1/clusters/{name}/workloads

kubectl get nodes -o wide и kubectl get pods -A по сохранённому kubeconfig.

Пример ответа 200:

{
  "cluster_name": "dev",
  "nodes_rc": 0,
  "nodes_output": "NAME                 STATUS   ROLES           ...",
  "pods_rc": 0,
  "pods_output": "NAMESPACE     NAME                           READY   STATUS    ...",
  "error": null
}

Если kubeconfig нет: "error": "Нет сохранённого kubeconfig...", остальные поля подов/узлов — null.


GET /api/v1/clusters/{name}

Детали и попытка kubectl get nodes -o wide с сохранённого clusters/{name}/kubeconfig (если файл есть).

Пример ответа 200:

{
  "name": "dev",
  "registered_in_kind": true,
  "has_local_kubeconfig": true,
  "kubeconfig_path": "/work/clusters/dev/kubeconfig",
  "meta": { "worker_nodes": 2 },
  "kubectl_get_nodes_rc": 0,
  "kubectl_get_nodes": "NAME                 STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION   CONTAINER-RUNTIME\n..."
}

POST /api/v1/clusters

Создание кластера в фоне (ответ 202).

Тело запроса (JSON):

{
  "name": "dev",
  "kubernetes_version": "1.29.4",
  "workers": 2
}

Пример ответа 202:

{
  "job_id": "a1b2c3d4e5f6...",
  "status": "queued",
  "message": "Создание кластера выполняется в фоне; опросите GET /api/v1/jobs/{job_id}"
}

Ошибка 409 (кластер уже есть в kind):

{
  "detail": "Кластер с таким именем уже есть в kind"
}

GET /api/v1/jobs/{job_id}

Статус фонового задания создания.

В процессе (пример 200):

{
  "job_id": "a1b2...",
  "kind": "create_cluster",
  "status": "running",
  "cluster_name": "dev",
  "created_at_utc": "2026-04-04T12:00:00+00:00",
  "message": null,
  "result": null
}

Успех (пример 200):

{
  "job_id": "a1b2...",
  "kind": "create_cluster",
  "status": "success",
  "cluster_name": "dev",
  "created_at_utc": "2026-04-04T12:00:00+00:00",
  "message": "Кластер создан",
  "result": {
    "cluster_name": "dev",
    "kubernetes_version_tag": "v1.29.4",
    "node_image": "kindest/node:v1.29.4",
    "workers": 2,
    "kubeconfig_path": "/work/clusters/dev/kubeconfig",
    "kubeconfig_patched_for_host": true,
    "nodes_ready": true,
    "nodes_ready_message": "..."
  }
}

Ошибка 404:

{
  "detail": "Задание не найдено"
}

DELETE /api/v1/clusters/{name}

kind delete cluster и удаление каталога clusters/{name}/.

Пример ответа 200:

{
  "name": "dev",
  "kind_delete_ok": true,
  "summary": "kind delete: OK; удалена папка /work/clusters/dev"
}

GET /

HTML-дашборд (не JSON): форма создания, таблица кластеров, ссылки на Swagger.