Документация и kubectl из контейнера; Kind Clusters Dashboard
- Цель make docker|podman kubectl CLUSTER=… (KUBECTL_ARGS) — exec kubectl в kind-k8s-web - README: без kubectl на хосте; раздел про проверку API из контейнера - create_cluster/cluster_status: подсказки для UI, make kubectl и exec в контейнере - app/docs: api_routes.md и README.md про kubectl и API workloads - Прочее: переименование проекта, документация, UI документации (ранее в рабочем дереве)
This commit is contained in:
+44
-3
@@ -1,10 +1,11 @@
|
||||
"""Чтение README.md для API ``GET /api/v1/docs/readme`` и страницы «Документация».
|
||||
"""Чтение README.md и безопасное чтение ``app/docs/*.md`` для API документации.
|
||||
|
||||
Разметка Markdown преобразуется в браузере: ``/static/js/vendor/marked.min.js`` и
|
||||
``purify.min.js`` (файлы входят в репозиторий, без CDN).
|
||||
|
||||
Путь к файлу: ``KIND_K8S_README_PATH`` или ``README.md`` в корне рядом с ``app/``;
|
||||
в Docker-образе — ``/opt/kind-k8s/README.md``.
|
||||
README: ``KIND_K8S_README_PATH`` или ``README.md`` в корне рядом с ``app/``;
|
||||
в Docker-образе — ``/opt/kind-k8s/README.md``. Файлы под ``app/docs/`` — через
|
||||
``resolve_app_docs_markdown`` / ``read_app_docs_file_text`` (эндпоинт ``GET /api/v1/docs/file``).
|
||||
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
@@ -86,3 +87,43 @@ def read_readme_text() -> str:
|
||||
[str(x) for x in _candidates_without_env()],
|
||||
)
|
||||
raise FileNotFoundError("README.md")
|
||||
|
||||
|
||||
def repo_root() -> Path:
|
||||
"""Корень репозитория (родитель каталога ``app/``)."""
|
||||
return _LIB_FILE.parents[2]
|
||||
|
||||
|
||||
def resolve_app_docs_markdown(relative_path: str) -> Path | None:
|
||||
"""
|
||||
Безопасно разрешить путь к ``.md`` только внутри ``app/docs/``.
|
||||
|
||||
Ожидается вид ``app/docs/api_routes.md`` (без ``..`` и абсолютных путей).
|
||||
"""
|
||||
raw = (relative_path or "").strip().lstrip("/").replace("\\", "/")
|
||||
if not raw or ".." in raw or "\x00" in raw:
|
||||
return None
|
||||
if not raw.endswith(".md"):
|
||||
return None
|
||||
if not raw.startswith("app/docs/"):
|
||||
return None
|
||||
base = repo_root()
|
||||
try:
|
||||
full = (base / raw).resolve()
|
||||
allowed = (base / "app" / "docs").resolve()
|
||||
full.relative_to(allowed)
|
||||
except (ValueError, OSError):
|
||||
return None
|
||||
if not full.is_file():
|
||||
return None
|
||||
return full
|
||||
|
||||
|
||||
def read_app_docs_file_text(relative_path: str) -> str:
|
||||
"""Прочитать UTF-8 текст файла под ``app/docs/``; ``FileNotFoundError`` если путь недопустим или файла нет."""
|
||||
p = resolve_app_docs_markdown(relative_path)
|
||||
if p is None:
|
||||
raise FileNotFoundError(relative_path)
|
||||
text = p.read_text(encoding="utf-8")
|
||||
logger.debug("Документ app/docs: %s, %s символов", p, len(text))
|
||||
return text
|
||||
|
||||
Reference in New Issue
Block a user