Files
KindClustersDashboard/app/templates/cluster_addons.html
Sergey Antropoff 4b703801e1 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 обновлены
2026-04-04 18:54:10 +03:00

322 lines
18 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{# Установка и удаление Helm-аддонов в выбранном кластере.
Автор: Сергей Антропов — https://devops.org.ru #}
{% extends "base.html" %}
{% block page_title %}Аддоны кластера{% endblock %}
{% block body_extra_class %} cluster-addons-page-loading{% endblock %}
{% block body_attrs %}data-dashboard-mode="addons"{% endblock %}
{% block footer %}
<div class="footer-inner">
<p class="footer-copyright">
© {{ app_title }} ·
<a href="https://devops.org.ru" target="_blank" rel="noopener">devops.org.ru</a>
</p>
</div>
{% endblock %}
{% block content %}
{# Полноэкранный спиннер до списка кластеров и статуса; версии чартов подгружаются после (helm repo update может быть долгим). #}
<div
id="addons-page-loading-overlay"
class="page-loading-overlay"
role="status"
aria-live="polite"
aria-busy="true"
aria-label="Загрузка страницы аддонов"
>
<div class="page-loading-backdrop" aria-hidden="true"></div>
<div class="page-loading-center">
<span class="spinner page-loading-spinner" aria-hidden="true"></span>
<span class="page-loading-label">Загрузка списка кластеров…</span>
</div>
</div>
<section class="card hero-panel cluster-create-hero" aria-labelledby="addons-hero-title">
<h1 class="page-title" id="addons-hero-title">Дополнения кластера (Helm)</h1>
<p class="muted page-lead">
Выберите кластер с сохранённым kubeconfig. Установка и удаление выполняются через <code>helm</code> в контейнере веб-приложения;
операции могут занимать несколько минут — ход и вывод команд отображаются в журнале ниже (как при развёртывании кластера). История операций сохраняется в каталоге кластера.
</p>
</section>
<section class="card create-cluster-card cluster-addons-toolbar-card">
<h2 class="create-cluster-card__title">Кластер</h2>
<div class="cluster-addons-cluster-row">
<label for="addons-cluster-select" class="cluster-addons-cluster-label">Выберите кластер для просмотра статуса аддонов.</label>
<select id="addons-cluster-select" class="cluster-addons-cluster-select" aria-label="Выберите кластер для просмотра статуса аддонов">
<option value="">— загрузка списка —</option>
</select>
<button type="button" class="btn-secondary" id="addons-refresh-status">Обновить статус</button>
</div>
<div id="addons-status-bar" class="cluster-addons-status-bar" role="status" aria-live="polite"></div>
<p id="addons-bootstrap-msg" class="cluster-addons-bootstrap-msg muted hidden" role="status" aria-live="polite"></p>
</section>
<div
id="addons-cards-wrap"
class="cluster-addons-cards-wrap hidden"
aria-hidden="true"
>
<div class="cluster-addons-grid">
<section class="card cluster-addon-card" data-addon="ingress-nginx">
<header class="cluster-addon-card__header">
<h2 class="cluster-addon-card__title">ingress-nginx</h2>
<span class="cluster-addon-card__badge cluster-addon-card__badge--off" role="status">Не установлен</span>
</header>
<p class="muted cluster-addon-card__desc">Контроллер Ingress.</p>
<div class="create-form-field">
<span class="cluster-addon-card__field-label" id="addons-ing-version-label">Версия чарта</span>
<div class="cluster-addon-version-row" role="group" aria-labelledby="addons-ing-version-label">
<select id="addons-ing-version-select" class="cluster-addons-version-select" aria-label="Версия чарта ingress-nginx">
<option value="">Последняя (из репозитория)</option>
</select>
<button type="button" class="btn-secondary btn-addon-load-values" data-addon="ingress-nginx">Загрузить values</button>
</div>
</div>
<div id="addons-values-panel-ingress-nginx" class="cluster-addon-card__values-panel hidden" hidden aria-hidden="true">
<details class="cluster-addon-card__values-details">
<summary class="cluster-addon-card__values-summary">Values чарта (YAML)</summary>
<p class="muted cluster-addon-card__values-hint">
Содержимое из <code>helm show values</code> плюс сервис для kind. После <code>-f</code> Helm применяет <code>--set</code> для NodePort. Нажмите «Загрузить values» для выбранной версии.
</p>
<label for="addons-values-yaml-ingress-nginx" class="sr-only">Полные YAML values для ingress-nginx</label>
<textarea
id="addons-values-yaml-ingress-nginx"
class="cluster-addon-card__values-textarea mono"
rows="12"
spellcheck="false"
aria-label="Полные YAML values чарта ingress-nginx"
></textarea>
</details>
</div>
<div class="cluster-addon-card__actions row cluster-addon-card__actions--inline">
<button type="button" class="btn-addon-install" data-endpoint="ingress-nginx">Установить</button>
<button type="button" class="btn-secondary btn-addon-remove hidden" data-endpoint="ingress-nginx" hidden>Удалить</button>
</div>
</section>
<section class="card cluster-addon-card" data-addon="kube-prometheus-stack">
<header class="cluster-addon-card__header">
<h2 class="cluster-addon-card__title">kube-prometheus-stack</h2>
<span class="cluster-addon-card__badge cluster-addon-card__badge--off" role="status">Не установлен</span>
</header>
<p class="muted cluster-addon-card__desc">Prometheus Operator, Alertmanager, Grafana.</p>
<div class="create-form-field">
<label for="addons-grafana-user">Логин администратора Grafana</label>
<input id="addons-grafana-user" type="text" value="admin" maxlength="256" autocomplete="username" />
</div>
<div class="create-form-field">
<label for="addons-grafana-pass">Пароль администратора Grafana</label>
<input id="addons-grafana-pass" type="password" minlength="8" maxlength="256" autocomplete="new-password" placeholder="не менее 8 символов" />
</div>
<div class="create-form-field">
<span class="cluster-addon-card__field-label" id="addons-prom-version-label">Версия чарта</span>
<div class="cluster-addon-version-row" role="group" aria-labelledby="addons-prom-version-label">
<select
id="addons-prom-version-select"
class="cluster-addons-version-select"
aria-labelledby="addons-prom-version-label"
>
<option value="">Последняя (из репозитория)</option>
</select>
<button type="button" class="btn-secondary btn-addon-load-values" data-addon="kube-prometheus-stack">Загрузить values</button>
</div>
</div>
<div id="addons-values-panel-kube-prometheus-stack" class="cluster-addon-card__values-panel hidden" hidden aria-hidden="true">
<details class="cluster-addon-card__values-details">
<summary class="cluster-addon-card__values-summary">Values чарта (YAML)</summary>
<p class="muted cluster-addon-card__values-hint">
Вывод <code>helm show values</code> с подстановкой логина и пароля Grafana из полей выше на момент нажатия «Загрузить values». Пустой textarea при установке — сервер соберёт values сам.
</p>
<label for="addons-values-yaml-kube-prometheus-stack" class="sr-only">Полные YAML values для kube-prometheus-stack</label>
<textarea
id="addons-values-yaml-kube-prometheus-stack"
class="cluster-addon-card__values-textarea mono"
rows="12"
spellcheck="false"
aria-label="Полные YAML values чарта kube-prometheus-stack"
></textarea>
</details>
</div>
<div class="cluster-addon-card__actions row cluster-addon-card__actions--inline">
<button type="button" class="btn-addon-install" data-endpoint="kube-prometheus-stack">Установить</button>
<button type="button" class="btn-secondary btn-addon-remove hidden" data-endpoint="kube-prometheus-stack" hidden>Удалить</button>
</div>
</section>
<section class="card cluster-addon-card" data-addon="metrics-server">
<header class="cluster-addon-card__header">
<h2 class="cluster-addon-card__title">metrics-server</h2>
<span class="cluster-addon-card__badge cluster-addon-card__badge--off" role="status">Не установлен</span>
</header>
<p class="muted cluster-addon-card__desc">Метрики узлов и подов для <code>kubectl top</code>; для kind включён <code>--kubelet-insecure-tls</code>.</p>
<div class="create-form-field">
<span class="cluster-addon-card__field-label" id="addons-ms-version-label">Версия чарта</span>
<div class="cluster-addon-version-row" role="group" aria-labelledby="addons-ms-version-label">
<select
id="addons-ms-version-select"
class="cluster-addons-version-select"
aria-labelledby="addons-ms-version-label"
>
<option value="">Последняя (из репозитория)</option>
</select>
<button type="button" class="btn-secondary btn-addon-load-values" data-addon="metrics-server">Загрузить values</button>
</div>
</div>
<div id="addons-values-panel-metrics-server" class="cluster-addon-card__values-panel hidden" hidden aria-hidden="true">
<details class="cluster-addon-card__values-details">
<summary class="cluster-addon-card__values-summary">Values чарта (YAML)</summary>
<p class="muted cluster-addon-card__values-hint">
<code>helm show values</code> плюс аргументы для kind (<code>--kubelet-insecure-tls</code> и т.д.). Пустое поле при установке — автосборка на сервере.
</p>
<label for="addons-values-yaml-metrics-server" class="sr-only">Полные YAML values для metrics-server</label>
<textarea
id="addons-values-yaml-metrics-server"
class="cluster-addon-card__values-textarea mono"
rows="12"
spellcheck="false"
aria-label="Полные YAML values чарта metrics-server"
></textarea>
</details>
</div>
<div class="cluster-addon-card__actions row cluster-addon-card__actions--inline">
<button type="button" class="btn-addon-install" data-endpoint="metrics-server">Установить</button>
<button type="button" class="btn-secondary btn-addon-remove hidden" data-endpoint="metrics-server" hidden>Удалить</button>
</div>
</section>
<section class="card cluster-addon-card cluster-addon-card--wide" data-addon="istio-kiali">
<header class="cluster-addon-card__header">
<h2 class="cluster-addon-card__title">Istio + Kiali</h2>
<span class="cluster-addon-card__badge cluster-addon-card__badge--off" role="status">Не установлен</span>
</header>
<p class="muted cluster-addon-card__desc">
Чарты <code>istio/base</code>, <code>istio/istiod</code> и <code>kiali-server</code> в <code>istio-system</code>. Kiali по умолчанию —
<strong>anonymous</strong> (без экрана входа; уместно для kind и <code>kubectl port-forward</code>). Для
<strong>token</strong> / <strong>openid</strong> задайте <code>auth.strategy</code> в YAML values kiali-server.
</p>
<div class="create-form-grid cluster-addon-istio-grid">
<div class="create-form-field">
<label for="addons-istio-version-select">Версия чартов Istio (base + istiod)</label>
<select id="addons-istio-version-select" class="cluster-addons-version-select">
<option value="">Последняя (из репозитория)</option>
</select>
</div>
<div class="create-form-field">
<label for="addons-kiali-version-select">Версия чарта Kiali</label>
<select id="addons-kiali-version-select" class="cluster-addons-version-select">
<option value="">Последняя (из репозитория)</option>
</select>
</div>
<div class="create-form-field cluster-addon-istio-load-field">
<span class="cluster-addon-card__field-label" id="addons-istio-values-label">Предпросмотр YAML</span>
<div class="cluster-addon-version-row" role="group" aria-labelledby="addons-istio-values-label">
<button type="button" class="btn-secondary btn-addon-load-values" data-addon="istio-kiali">Загрузить values</button>
</div>
</div>
</div>
<div id="addons-values-panel-istio-kiali" class="cluster-addon-card__values-panel hidden" hidden aria-hidden="true">
<details class="cluster-addon-card__values-details">
<summary class="cluster-addon-card__values-summary">Values чартов Istio и Kiali (YAML)</summary>
<p class="muted cluster-addon-card__values-hint">
Три блока из <code>helm show values</code> для выбранных версий Istio и Kiali. Секрет логина больше не создаётся; при необходимости настройте <code>auth</code> в блоке kiali-server.
</p>
<p class="cluster-addon-card__values-subhead">kiali-server</p>
<label for="addons-values-yaml-istio-kiali" class="sr-only">YAML values kiali-server</label>
<textarea
id="addons-values-yaml-istio-kiali"
class="cluster-addon-card__values-textarea mono"
rows="10"
spellcheck="false"
aria-label="Полные YAML values чарта kiali-server"
></textarea>
<p class="cluster-addon-card__values-subhead">istio/base</p>
<label for="addons-values-yaml-istio-base" class="sr-only">YAML values istio-base</label>
<textarea
id="addons-values-yaml-istio-base"
class="cluster-addon-card__values-textarea mono"
rows="10"
spellcheck="false"
aria-label="Полные YAML values чарта istio/base"
></textarea>
<p class="cluster-addon-card__values-subhead">istio/istiod</p>
<label for="addons-values-yaml-istio-istiod" class="sr-only">YAML values istiod</label>
<textarea
id="addons-values-yaml-istio-istiod"
class="cluster-addon-card__values-textarea mono"
rows="10"
spellcheck="false"
aria-label="Полные YAML values чарта istio/istiod"
></textarea>
</details>
</div>
<div class="cluster-addon-card__actions row cluster-addon-card__actions--inline">
<button type="button" class="btn-addon-install" data-endpoint="istio-kiali">Установить</button>
<button type="button" class="btn-secondary btn-addon-remove hidden" data-endpoint="istio-kiali" hidden>Удалить</button>
</div>
</section>
</div>
</div>
{# Ход Helm: секция в dock; при установке/удалении переносится внутрь карточки аддона (cluster_addons.js). #}
<div id="addons-helm-progress-dock" class="cluster-addons-helm-dock" aria-hidden="true">
<section
id="addons-helm-progress-wrap"
class="card create-progress-wrap cluster-addons-helm-progress hidden"
aria-hidden="true"
aria-labelledby="addons-helm-progress-title"
>
<h2 class="create-cluster-card__title" id="addons-helm-progress-title">Ход операции Helm</h2>
<p class="create-progress-hint muted" id="addons-helm-progress-hint">
Выполняется команда в контейнере веб-приложения; полный вывод появится по завершении.
</p>
<div
class="progress-track"
role="progressbar"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="0"
aria-labelledby="addons-helm-progress-label"
id="addons-helm-progress-track"
>
<div class="progress-bar" id="addons-helm-progress-bar" style="width: 0%"></div>
</div>
<p class="progress-label" id="addons-helm-progress-label"></p>
<div class="job-log-panel-wrap">
<label for="addons-helm-log-panel" class="job-log-label muted">Журнал установки / удаления</label>
<pre
id="addons-helm-log-panel"
class="mono job-log-panel"
role="log"
aria-live="polite"
aria-relevant="additions"
></pre>
</div>
</section>
</div>
{# Если внешний cluster_addons.js не выполнился (404, ошибка синтаксиса), оверлей снимается через 50 с. #}
<script>
(function () {
var ms = 50000;
setTimeout(function () {
var el = document.getElementById("addons-page-loading-overlay");
if (!el || el.classList.contains("hidden")) return;
el.classList.add("hidden");
el.setAttribute("aria-busy", "false");
el.setAttribute("aria-hidden", "true");
document.body.classList.remove("cluster-addons-page-loading");
}, ms);
})();
</script>
{% include "partials/dashboard_modals.html" %}
{% endblock %}
{% block scripts %}
<script src="/static/js/cluster_addons.js" defer></script>
{% endblock %}