chore(iot): убрать старое (Kafka/K8s) из живого админ-UI и .gitignore

- iot-admin.html: секции Kafka/Pods заменены на Очередь shared-SQS и Рантайм
  (бэкенд admin.go давно отдаёт sqs/runtime, а фронт рисовал мёртвые секции);
  удалены CSS .pod-*/.badge-*/.dot-*/.lag-bar*, исправлен заголовок.
- .gitignore: удалены сталые пути бинарников старого IoT (/iot-operator,
  /mqtt-bridge, /kafka-consumer, /sqs-consumer).
This commit is contained in:
Repinoid
2026-10-10 18:15:13 +03:00
parent b205f886b6
commit a510522660
2 changed files with 43 additions and 105 deletions
-4
View File
@@ -1,8 +1,4 @@
# Бинарники (только в корне проекта, не директории cmd/)
/iot-operator
/mqtt-bridge
/kafka-consumer
/sqs-consumer
bin/
ws-probe/ws-probe
/iot-service
+43 -101
View File
@@ -1,9 +1,9 @@
<!DOCTYPE html>
<!-- Создано: 2026-04-06
iot-admin.html — страница администратора IoT pipeline.
Показывает: PostgreSQL stats per tenant, Kafka consumer lag, K8s pod statuses.
Показывает: PostgreSQL stats per tenant, очередь shared-SQS, рантайм процесса.
Auth: ADMIN_STATS_TOKEN вводится вручную и хранится в sessionStorage.
Раздаётся по GET /iot-admin (go:embed в бинарнике оператора).
Раздаётся по GET /iot-admin (go:embed в бинарнике iot-service).
НЕ для конечных пользователей — только для администратора платформы. -->
<html lang="ru">
<head>
@@ -95,23 +95,6 @@
.card-ok { color: #34d399; }
.card-err { color: #f87171; }
/* Pod status card */
.pod-card {
background: #001929; border: 1px solid #0b2d50; border-radius: 10px;
padding: 20px; display: flex; flex-direction: column; gap: 8px;
}
.pod-name { font-size: 13px; font-weight: 600; color: #7fc8f8; font-family: monospace; }
.pod-row { display: flex; justify-content: space-between; font-size: 12px; }
.pod-label { color: #6b8eaa; }
.pod-val { color: #e2ecf6; }
.badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 11px; font-weight: 700;
}
.badge-ok { background: #052e16; color: #34d399; border: 1px solid #064e3b; }
.badge-warn { background: #2d1c00; color: #f59e0b; border: 1px solid #4d3000; }
.badge-err { background: #300; color: #f87171; border: 1px solid #500; }
/* Tenant table */
.tenant-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.tenant-table th {
@@ -142,18 +125,6 @@
/* Last updated */
.last-updated { font-size: 12px; color: #2d5070; text-align: center; margin-top: 16px; }
/* Status dot */
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
.dot-ok { background: #34d399; }
.dot-warn { background: #f59e0b; }
.dot-err { background: #f87171; }
/* Kafka lag bar */
.lag-bar-wrap { background: #001120; border-radius: 4px; height: 6px; margin-top: 8px; overflow: hidden; }
.lag-bar { height: 100%; border-radius: 4px; transition: width 0.5s; min-width: 2px; }
.lag-bar-ok { background: #34d399; }
.lag-bar-warn { background: #f59e0b; }
/* Spinner */
.spinner {
border: 3px solid #0b2d50; border-top-color: #1a7fd4;
@@ -223,26 +194,26 @@
<!-- Данные -->
<div id="dataContent" style="display:none">
<!-- Kafka -->
<!-- shared-SQS: очередь телеметрии -->
<div class="section">
<div class="section-header">
<svg class="section-icon" viewBox="0 0 24 24" fill="none" stroke="#7fc8f8" stroke-width="2">
<path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/>
</svg>
<span class="section-title">Kafka</span>
<span class="section-title">Очередь shared-SQS</span>
</div>
<div class="cards" id="kafkaCards"></div>
<div class="cards" id="sqsCards"></div>
</div>
<!-- K8s Pods -->
<!-- Рантайм процесса -->
<div class="section">
<div class="section-header">
<svg class="section-icon" viewBox="0 0 24 24" fill="none" stroke="#7fc8f8" stroke-width="2">
<rect x="2" y="3" width="20" height="14" rx="2"/><path d="M8 21h8M12 17v4"/>
</svg>
<span class="section-title">Pods</span>
<span class="section-title">Рантайм</span>
</div>
<div class="cards" id="podCards"></div>
<div class="cards" id="runtimeCards"></div>
</div>
<!-- PostgreSQL per tenant -->
@@ -388,83 +359,54 @@ function resetRefreshTimer() {
// ── Render ─────────────────────────────────────────────────────────────────
function renderAll(data) {
renderKafka(data.kafka || {});
renderPods(data.pods || {});
renderSQS(data.sqs || {});
renderRuntime(data.runtime || {});
renderPostgres(data.postgres || {});
}
// Kafka section
function renderKafka(kafka) {
const el = document.getElementById('kafkaCards');
if (kafka.error) {
// Очередь shared-SQS
function renderSQS(sqs) {
const el = document.getElementById('sqsCards');
if (sqs.error) {
el.innerHTML = `<div class="card"><div class="card-title">Ошибка</div>
<div class="card-value card-err" style="font-size:14px">${esc(kafka.error)}</div></div>`;
<div class="card-value card-err" style="font-size:14px">${esc(sqs.error)}</div></div>`;
return;
}
const lag = kafka.consumer_lag || 0;
const latest = kafka.latest_offset || 0;
const committed = kafka.committed_offset || 0;
const lagClass = lag === 0 ? 'card-ok' : lag < 100 ? 'card-warn' : 'card-err';
const barClass = lag === 0 ? 'lag-bar-ok' : 'lag-bar-warn';
const barWidth = latest > 0 ? Math.max(2, Math.round((committed / latest) * 100)) : 100;
const pending = sqs.approximate_messages || 0;
const inFlight = sqs.approximate_messages_not_visible || 0;
const pendingClass = pending === 0 ? 'card-ok' : pending < 100 ? 'card-warn' : 'card-err';
el.innerHTML = `
<div class="card">
<div class="card-title">Consumer Lag</div>
<div class="card-value ${lagClass}">${lag}</div>
<div class="card-sub">iot-pg-consumer / iot.telemetry</div>
<div class="lag-bar-wrap"><div class="lag-bar ${barClass}" style="width:${barWidth}%"></div></div>
<div class="card-title">Ожидают обработки</div>
<div class="card-value ${pendingClass}">${pending.toLocaleString()}</div>
<div class="card-sub">ApproximateNumberOfMessages</div>
</div>
<div class="card">
<div class="card-title">Latest Offset (всего прошло)</div>
<div class="card-value card-accent">${latest.toLocaleString()}</div>
<div class="card-sub">Kafka log end offset</div>
</div>
<div class="card">
<div class="card-title">Committed Offset</div>
<div class="card-value">${committed.toLocaleString()}</div>
<div class="card-sub">Consumer обработал</div>
<div class="card-title">В обработке</div>
<div class="card-value card-accent">${inFlight.toLocaleString()}</div>
<div class="card-sub">ApproximateNumberOfMessagesNotVisible</div>
</div>`;
}
// Pods section
function renderPods(pods) {
const el = document.getElementById('podCards');
el.innerHTML = '';
const labels = {
'iot-mqtt-bridge': 'MQTT Bridge',
'iot-kafka-consumer': 'Kafka Consumer'
};
for (const [key, pod] of Object.entries(pods)) {
const title = labels[key] || key;
if (pod.error || pod.status === 'not found') {
el.innerHTML += `
<div class="pod-card">
<div class="pod-name">${esc(title)}</div>
<div style="color:#f87171;font-size:12px">${esc(pod.error || 'Pod not found')}</div>
</div>`;
continue;
}
const readyBadge = pod.ready
? '<span class="badge badge-ok">Ready</span>'
: '<span class="badge badge-warn">Not Ready</span>';
const restartColor = pod.restarts > 5 ? 'card-err' : pod.restarts > 0 ? 'card-warn' : 'card-ok';
el.innerHTML += `
<div class="pod-card">
<div class="pod-name">
<span class="dot dot-${pod.ready ? 'ok' : 'warn'}"></span>${esc(title)}
</div>
<div class="pod-row"><span class="pod-label">Pod</span><span class="pod-val" style="font-family:monospace;font-size:11px">${esc(pod.name)}</span></div>
<div class="pod-row"><span class="pod-label">Phase</span><span class="pod-val">${esc(pod.phase)} ${readyBadge}</span></div>
<div class="pod-row"><span class="pod-label">Restarts</span><span class="pod-val ${restartColor}">${pod.restarts}</span></div>
<div class="pod-row"><span class="pod-label">Age</span><span class="pod-val">${esc(pod.age)}</span></div>
</div>`;
}
// Рантайм процесса
function renderRuntime(rt) {
const el = document.getElementById('runtimeCards');
const uptime = rt.uptime_sec || 0;
const h = Math.floor(uptime / 3600);
const m = Math.floor((uptime % 3600) / 60);
const s = uptime % 60;
const uptimeStr = h > 0 ? `${h}ч ${m}м` : m > 0 ? `${m}м ${s}с` : `${s}с`;
el.innerHTML = `
<div class="card">
<div class="card-title">Версия</div>
<div class="card-value" style="font-size:20px">${esc(rt.version || '—')}</div>
<div class="card-sub">iot-service</div>
</div>
<div class="card">
<div class="card-title">Uptime</div>
<div class="card-value card-accent">${uptimeStr}</div>
<div class="card-sub">с ${esc(rt.started_at || '—')}</div>
</div>`;
}
// Postgres section