docs: полная документация v0.2.3 — архитектура, API, деплой, тестирование
Новые файлы: - doc/architecture/current-v0.2.3.md — актуальная архитектура - doc/api/endpoints-v0.2.3.md — полная документация REST API - doc/deployment-v0.2.3.md — инструкция деплоя v0.2.3 - doc/run-and-test.md — руководство по запуску и E2E тесту Обновлено: - doc/progress.md — секция документации - doc/thinking/2026-04-12.md — лог мышления
This commit is contained in:
@@ -0,0 +1,256 @@
|
||||
# IoT Managed Service — Актуальная архитектура (v0.2.3)
|
||||
|
||||
> Дата: 2026-04-12
|
||||
> Образ: naeel/iot-operator:v0.2.3
|
||||
> Кластер: iot-naeel, namespace: sless
|
||||
|
||||
---
|
||||
|
||||
## Путь данных (data flow)
|
||||
|
||||
```
|
||||
IoT Device (MQTT CONNECT)
|
||||
| username="{ns}_{deviceId}", password=hex(64)
|
||||
v
|
||||
EMQX 5.5.1 (Pod emqx, namespace sless)
|
||||
| 1. POST /internal/mqtt/auth -> iot-operator:9090
|
||||
| - Bridge auth: username=iot-bridge-internal -> allow
|
||||
| - Device auth: username={ns}_{deviceId} -> Secret -> compare
|
||||
| 2. POST /internal/mqtt/acl -> iot-operator:9090
|
||||
| - Device: pub/sub только {ns}/telemetry/{deviceId}
|
||||
| - Bridge: sub на +/telemetry/+ (wildcard)
|
||||
v
|
||||
| MQTT PUBLISH -> topic: "{ns}/telemetry/{deviceId}"
|
||||
v
|
||||
iot-mqtt-bridge (Pod, namespace sless)
|
||||
| paho.mqtt.golang, подписка на "+/telemetry/+"
|
||||
| Парсит topic -> namespace (segment 0), deviceId (segment 2)
|
||||
| AWS SDK SQS SendMessage -> shared-SQS
|
||||
v
|
||||
shared-SQS (namespace shared-sqs)
|
||||
| Endpoint: https://qu.kube5s.ru
|
||||
| Tenant: iot-service (ID: t-96afe7e9f781f6ca)
|
||||
| Queue: iot-telemetry
|
||||
v
|
||||
iot-sqs-consumer (Pod, namespace sless)
|
||||
| ReceiveMessage (WaitTimeSeconds=20, long polling)
|
||||
| Парсит envelope -> namespace, device_id, payload
|
||||
| EnsureTenantDB(namespace) -> CREATE DATABASE tenant_{ns}
|
||||
| INSERT INTO iot_telemetry
|
||||
| DeleteMessage (at-least-once)
|
||||
v
|
||||
Managed PostgreSQL 17
|
||||
| Host: postgresqlk8s-master.dc5db45d-....svc.cluster.local
|
||||
| Per-tenant: DATABASE tenant_{namespace}
|
||||
| Таблица: iot_telemetry (id, device_id, payload JSONB, received_at, created_at)
|
||||
v
|
||||
REST API (iot-operator:9090)
|
||||
| GET /v1/namespaces/{ns}/iot/telemetry?device=X&limit=N
|
||||
v
|
||||
Пользователь
|
||||
| IoT Console: https://iot.kube5s.ru/console
|
||||
| WebSocket MQTT: wss://iot.kube5s.ru/mqtt
|
||||
| Terraform: sless_iot_device resource
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Компоненты
|
||||
|
||||
### iot-operator (cmd/iot-operator)
|
||||
|
||||
Единый бинарник: controller-manager + REST API сервер.
|
||||
|
||||
| Функция | Описание |
|
||||
|---------|----------|
|
||||
| IoTDevice Controller | Reconcile: создание Secret с MQTT credentials, OwnerReference |
|
||||
| REST API :9090 | CRUD устройств, телеметрия, MQTT auth/acl, admin stats, UI |
|
||||
| Health :8081 | /healthz, /readyz для k8s probes |
|
||||
|
||||
### iot-mqtt-bridge (cmd/mqtt-bridge)
|
||||
|
||||
MQTT subscriber -> SQS producer. Stateless.
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| MQTT broker | tcp://emqx.sless.svc:1883 |
|
||||
| MQTT username | iot-bridge-internal (Secret iot-bridge-credentials) |
|
||||
| MQTT subscription | +/telemetry/+ |
|
||||
| SQS endpoint | https://qu.kube5s.ru |
|
||||
| SQS queue | iot-telemetry |
|
||||
|
||||
Bridge auth (v0.2.3): operator проверяет BridgeUsername/BridgePassword ДО парсинга namespace_deviceId.
|
||||
|
||||
### iot-sqs-consumer (cmd/sqs-consumer)
|
||||
|
||||
SQS consumer -> Postgres writer. Stateless.
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| SQS endpoint | https://qu.kube5s.ru |
|
||||
| SQS queue | iot-telemetry |
|
||||
| Long polling | WaitTimeSeconds=20 |
|
||||
| Postgres | IOT_PG_DSN из Secret |
|
||||
| Семантика | at-least-once (DeleteMessage после INSERT) |
|
||||
|
||||
### EMQX 5.5.1
|
||||
|
||||
MQTT-брокер с HTTP auth backend.
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| Образ | emqx/emqx:5.5.1 |
|
||||
| Порты | 1883 (MQTT), 8083 (WebSocket), 18083 (Dashboard) |
|
||||
| Auth | HTTP POST -> iot-operator:9090/internal/mqtt/auth |
|
||||
| ACL | HTTP POST -> iot-operator:9090/internal/mqtt/acl |
|
||||
| Конфиг | HOCON emqx.conf через ConfigMap |
|
||||
|
||||
---
|
||||
|
||||
## CRD: IoTDevice (iot.kube5s.ru/v1alpha1)
|
||||
|
||||
### Spec
|
||||
|
||||
| Поле | Тип | Обязательное | Описание |
|
||||
|------|-----|-------------|----------|
|
||||
| deviceId | string | да | Pattern: ^[a-z0-9][a-z0-9-]*[a-z0-9]$ |
|
||||
| enabled | bool | нет | default: true |
|
||||
| metadata | map[string]string | нет | Произвольные метаданные |
|
||||
|
||||
### Status
|
||||
|
||||
| Поле | Описание |
|
||||
|------|----------|
|
||||
| phase | Active / Disabled / Pending / Error |
|
||||
| mqttUsername | {namespace}_{deviceId} |
|
||||
| secretName | iot-{deviceId} |
|
||||
| topicPrefix | {namespace}/ |
|
||||
| message | Сообщение об ошибке |
|
||||
|
||||
### Reconcile logic
|
||||
|
||||
1. Добавить finalizer iot.kube5s.ru/device-cleanup
|
||||
2. Если Secret iot-{deviceId} не существует:
|
||||
- crypto/rand 32 bytes -> hex (64 символа) = пароль
|
||||
- Создать Secret с OwnerReference -> каскадное удаление
|
||||
- Keys: mqtt-username, mqtt-password, device-id
|
||||
3. Status: phase=Active, mqttUsername={ns}_{deviceId}
|
||||
4. Если enabled=false -> phase=Disabled (Secret НЕ удаляется)
|
||||
5. DELETE: finalizer cleanup -> Secret удаляется каскадно
|
||||
|
||||
---
|
||||
|
||||
## Аутентификация
|
||||
|
||||
### REST API (/v1/)
|
||||
|
||||
- Middleware: Bearer JWT token
|
||||
- authTestMode = true (текущий): любой непустой Bearer token принимается
|
||||
- authTestMode = false (prod): JWT decode -> sub -> SHA256 -> namespace mapping
|
||||
|
||||
### MQTT Auth (/internal/mqtt/auth)
|
||||
|
||||
1. Если username == BridgeUsername -> проверить BridgePassword -> allow/deny
|
||||
2. Иначе: парсить username по первому "_" -> namespace + deviceId
|
||||
3. Найти Secret iot-{deviceId} в namespace
|
||||
4. crypto/subtle.ConstantTimeCompare(password, secret.mqtt-password)
|
||||
5. Всегда HTTP 200, body: {"result": "allow"} или {"result": "deny"}
|
||||
|
||||
### MQTT ACL (/internal/mqtt/acl)
|
||||
|
||||
- Bridge (clientid=sless-iot-bridge): allow subscribe +/telemetry/+
|
||||
- Device: allow pub/sub только {namespace}/telemetry/{deviceId}
|
||||
- Всё остальное: deny
|
||||
|
||||
---
|
||||
|
||||
## Хранение данных
|
||||
|
||||
### PostgreSQL (managed)
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| Версия | PG 17 |
|
||||
| Host | postgresqlk8s-master.dc5db45d-f8b4-4fd0-ad33-ec4dd017f2d5.svc.cluster.local |
|
||||
| User | super |
|
||||
| Master DB | sqsdb |
|
||||
|
||||
Per-tenant изоляция: отдельная DATABASE tenant_{namespace}.
|
||||
|
||||
Таблица iot_telemetry:
|
||||
- id SERIAL PRIMARY KEY
|
||||
- device_id TEXT NOT NULL
|
||||
- payload JSONB NOT NULL
|
||||
- received_at TIMESTAMPTZ
|
||||
- created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
|
||||
### shared-SQS
|
||||
|
||||
| Параметр | Значение |
|
||||
|----------|----------|
|
||||
| Endpoint | https://qu.kube5s.ru |
|
||||
| Tenant | iot-service (t-96afe7e9f781f6ca) |
|
||||
| Queue | iot-telemetry |
|
||||
| Протокол | AWS SQS API compatible |
|
||||
|
||||
---
|
||||
|
||||
## Docker образ
|
||||
|
||||
- Registry: Docker Hub naeel/iot-operator
|
||||
- Базовый: gcr.io/distroless/static:nonroot
|
||||
- Содержит 3 бинарника: /iot-operator, /mqtt-bridge, /sqs-consumer
|
||||
- Выбор бинарника через command в Deployment YAML
|
||||
|
||||
---
|
||||
|
||||
## Сетевая схема
|
||||
|
||||
```
|
||||
Internet
|
||||
|
|
||||
v
|
||||
nginx-ingress (namespace ingress)
|
||||
| iot.kube5s.ru/mqtt -> emqx-ws:8083 (WebSocket)
|
||||
| iot.kube5s.ru/console -> iot-operator:9090 (UI)
|
||||
| iot.kube5s.ru/iot-admin -> iot-operator:9090 (Admin UI)
|
||||
v
|
||||
namespace sless:
|
||||
emqx:1883 <-> iot-mqtt-bridge (MQTT)
|
||||
emqx:1883 <- IoT devices (MQTT)
|
||||
iot-operator:9090 <- emqx (auth/acl HTTP)
|
||||
iot-operator:9090 <- users (REST API)
|
||||
iot-mqtt-bridge -> shared-sqs (HTTPS, SQS API)
|
||||
iot-sqs-consumer <- shared-sqs (HTTPS, SQS API)
|
||||
iot-sqs-consumer -> managed-postgres (TCP 5432)
|
||||
iot-operator -> managed-postgres (TCP 5432, telemetry GET)
|
||||
iot-operator -> k8s API (CRD watch, Secret CRUD)
|
||||
|
||||
namespace shared-sqs:
|
||||
shared-sqs:9324 (SQS API)
|
||||
Ingress: qu.kube5s.ru -> shared-sqs
|
||||
|
||||
namespace dc5db45d-...:
|
||||
postgresqlk8s-0 (PG 17 managed)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Секреты (namespace sless)
|
||||
|
||||
| Secret | Ключи | Используется |
|
||||
|--------|-------|-------------|
|
||||
| iot-bridge-credentials | MQTT_USERNAME, MQTT_PASSWORD | iot-operator, iot-mqtt-bridge |
|
||||
| iot-sqs-credentials | SQS_ENDPOINT, SQS_ACCESS_KEY, SQS_SECRET_KEY | iot-mqtt-bridge, iot-sqs-consumer |
|
||||
| iot-postgres-secret | IOT_PG_DSN | iot-sqs-consumer |
|
||||
|
||||
---
|
||||
|
||||
## Эволюция архитектуры
|
||||
|
||||
| Версия | Дата | Message bus | Postgres | Кластер |
|
||||
|--------|------|------------|----------|---------|
|
||||
| v0.1.50 | 2026-04-04 | RabbitMQ (AMQP) | emptyDir PVC | sless (общий) |
|
||||
| v0.1.68 | 2026-04-06 | Kafka (segmentio/kafka-go) | emptyDir PVC | sless (общий) |
|
||||
| v0.2.0 | 2026-04-12 | shared-SQS (AWS SDK) | Managed PG 17 | iot-naeel (новый) |
|
||||
| v0.2.3 | 2026-04-12 | shared-SQS (AWS SDK) | Managed PG 17 | iot-naeel |
|
||||
@@ -85,3 +85,23 @@
|
||||
- [ ] Нагрузочный тест
|
||||
- [ ] Мерж ветки в master
|
||||
- [ ] Убрать IoT-код из sless (опционально)
|
||||
|
||||
---
|
||||
|
||||
## 2026-04-12: Документация v0.2.3
|
||||
|
||||
### Выполнено
|
||||
- [x] Аудит документации из репозитория sless (thinking 04-04/05/06/09, decisions, progress, api, examples)
|
||||
- [x] Аудит документации в IoT репозитории (deployment.md, overview.md, endpoints.md, mvp-plan.md)
|
||||
- [x] Анализ расхождений — определены устаревшие секции (Kafka, RabbitMQ)
|
||||
- [x] Решение: старые документы НЕ удалять, новые создавать отдельно
|
||||
- [x] Создан doc/deployment-v0.2.3.md (295 строк) — актуальная инструкция деплоя
|
||||
- [x] Создан doc/architecture/current-v0.2.3.md (256 строк) — полная архитектура v0.2.3
|
||||
- [x] Создан doc/api/endpoints-v0.2.3.md (~300 строк) — полная документация REST API
|
||||
- [x] Создан doc/run-and-test.md (~180 строк) — руководство по запуску и E2E тесту
|
||||
- [x] Обновлён doc/progress.md
|
||||
- [x] Дописан doc/thinking/2026-04-12.md — лог мышления сессии
|
||||
|
||||
### Баг-фиксы v0.2.1—v0.2.3
|
||||
- v0.2.1: mqtt-bridge — bridge auth fix (BridgeUsername/BridgePassword проверяется ДО парсинга username)
|
||||
- v0.2.3: финальный образ со всеми фиксами
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
# IoT — Руководство по запуску и тестированию (v0.2.3)
|
||||
|
||||
> Дата: 2026-04-12
|
||||
> Кластер: iot-naeel, namespace: sless
|
||||
> Образ: naeel/iot-operator:v0.2.3
|
||||
|
||||
---
|
||||
|
||||
## Содержание
|
||||
|
||||
1. [Предварительные требования](#предварительные-требования)
|
||||
2. [Сборка и публикация образа](#сборка-и-публикация-образа)
|
||||
3. [Деплой в кластер](#деплой-в-кластер)
|
||||
4. [E2E тест: полный путь данных](#e2e-тест-полный-путь-данных)
|
||||
5. [Проверка компонентов](#проверка-компонентов)
|
||||
6. [Отладка](#отладка)
|
||||
|
||||
---
|
||||
|
||||
## Предварительные требования
|
||||
|
||||
- kubectl с kubeconfig для кластера iot-naeel (185.247.187.149:6443)
|
||||
- Docker для сборки образа
|
||||
- mosquitto-clients для MQTT тестов (apt install mosquitto-clients)
|
||||
- curl для REST API
|
||||
|
||||
---
|
||||
|
||||
## Сборка и публикация образа
|
||||
|
||||
```bash
|
||||
cd /home/naeel/terra/IoT
|
||||
|
||||
# Сборка multi-binary Docker образа
|
||||
docker build -t naeel/iot-operator:v0.2.3 .
|
||||
|
||||
# Push на Docker Hub
|
||||
docker push naeel/iot-operator:v0.2.3
|
||||
```
|
||||
|
||||
Dockerfile собирает 3 бинарника: /iot-operator, /mqtt-bridge, /sqs-consumer.
|
||||
|
||||
---
|
||||
|
||||
## Деплой в кластер
|
||||
|
||||
```bash
|
||||
# Применить CRD
|
||||
kubectl apply -f config/crd/bases/iot.kube5s.ru_iotdevices.yaml
|
||||
|
||||
# Деплой всех компонентов
|
||||
kubectl apply -f deployments/k8s/emqx.yaml
|
||||
kubectl apply -f deployments/k8s/iot-operator.yaml
|
||||
kubectl apply -f deployments/k8s/iot-mqtt-bridge.yaml
|
||||
kubectl apply -f deployments/k8s/iot-sqs-consumer.yaml
|
||||
kubectl apply -f deployments/k8s/iot-postgres.yaml
|
||||
|
||||
# Проверка
|
||||
kubectl get pods -n sless
|
||||
# Ожидаем: emqx, iot-operator, iot-mqtt-bridge, iot-sqs-consumer — все Running
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## E2E тест: полный путь данных
|
||||
|
||||
Полный тест проверяет цепочку: REST API → CRD → Secret → MQTT → SQS → Postgres → Telemetry API.
|
||||
|
||||
### Шаг 1: Создать устройство через API
|
||||
|
||||
```bash
|
||||
curl -X POST https://iot.kube5s.ru/v1/namespaces/sless/iot/devices \
|
||||
-H "Authorization: Bearer test-token" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name":"e2e-test-01","device_id":"e2e-test-01","enabled":true}'
|
||||
```
|
||||
|
||||
Ответ: 201 Created с данными устройства.
|
||||
|
||||
### Шаг 2: Получить MQTT credentials
|
||||
|
||||
```bash
|
||||
curl -s https://iot.kube5s.ru/v1/namespaces/sless/iot/devices/e2e-test-01 \
|
||||
-H "Authorization: Bearer test-token" \
|
||||
| jq '{mqtt_username, mqtt_password, phase}'
|
||||
```
|
||||
|
||||
Ожидаем: phase=Active, mqtt_username="sless_e2e-test-01", mqtt_password=hex(64).
|
||||
|
||||
> Если phase=Pending — подождать 1-2 секунды, контроллер ещё создаёт Secret.
|
||||
|
||||
### Шаг 3: Отправить телеметрию через MQTT
|
||||
|
||||
```bash
|
||||
# Вставить реальный пароль из Шага 2
|
||||
MQTT_USER="sless_e2e-test-01"
|
||||
MQTT_PASS="<mqtt_password из шага 2>"
|
||||
|
||||
# Через WebSocket (через Ingress)
|
||||
mosquitto_pub \
|
||||
-h iot.kube5s.ru \
|
||||
-p 443 \
|
||||
--capath /etc/ssl/certs \
|
||||
-u "$MQTT_USER" \
|
||||
-P "$MQTT_PASS" \
|
||||
-t "sless/telemetry/e2e-test-01" \
|
||||
-m '{"temperature": 22.5, "humidity": 65}' \
|
||||
--protocol-version mqttv5
|
||||
|
||||
# ИЛИ через kubectl port-forward (MQTT напрямую)
|
||||
kubectl port-forward svc/emqx -n sless 1883:1883 &
|
||||
mosquitto_pub \
|
||||
-h localhost \
|
||||
-p 1883 \
|
||||
-u "$MQTT_USER" \
|
||||
-P "$MQTT_PASS" \
|
||||
-t "sless/telemetry/e2e-test-01" \
|
||||
-m '{"temperature": 22.5, "humidity": 65}'
|
||||
```
|
||||
|
||||
### Шаг 4: Проверить что телеметрия дошла до Postgres
|
||||
|
||||
Подождать 5-10 секунд (SQS long polling + обработка).
|
||||
|
||||
```bash
|
||||
curl -s "https://iot.kube5s.ru/v1/namespaces/sless/iot/telemetry?device=e2e-test-01&limit=10" \
|
||||
-H "Authorization: Bearer test-token" \
|
||||
| jq '.'
|
||||
```
|
||||
|
||||
Ожидаем: count >= 1, items содержит запись с payload {"temperature": 22.5, "humidity": 65}.
|
||||
|
||||
### Шаг 5: Очистка
|
||||
|
||||
```bash
|
||||
curl -X DELETE https://iot.kube5s.ru/v1/namespaces/sless/iot/devices/e2e-test-01 \
|
||||
-H "Authorization: Bearer test-token"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Проверка компонентов
|
||||
|
||||
### Поды
|
||||
|
||||
```bash
|
||||
kubectl get pods -n sless -l 'app in (iot-operator,iot-mqtt-bridge,iot-sqs-consumer,emqx)'
|
||||
```
|
||||
|
||||
### Логи
|
||||
|
||||
```bash
|
||||
# Operator (controller + API)
|
||||
kubectl logs -n sless deployment/iot-operator --tail=50
|
||||
|
||||
# MQTT Bridge
|
||||
kubectl logs -n sless deployment/iot-mqtt-bridge --tail=50
|
||||
|
||||
# SQS Consumer
|
||||
kubectl logs -n sless deployment/iot-sqs-consumer --tail=50
|
||||
|
||||
# EMQX
|
||||
kubectl logs -n sless deployment/emqx --tail=50
|
||||
```
|
||||
|
||||
### CRD ресурсы
|
||||
|
||||
```bash
|
||||
# Список IoTDevice
|
||||
kubectl get iotdevices -n sless
|
||||
|
||||
# Детали
|
||||
kubectl describe iotdevice e2e-test-01 -n sless
|
||||
|
||||
# Секреты
|
||||
kubectl get secret -n sless -l app.kubernetes.io/managed-by=iot-operator
|
||||
```
|
||||
|
||||
### EMQX Dashboard (отладка)
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/emqx -n sless 18083:18083
|
||||
# Открыть http://localhost:18083
|
||||
# Default: admin / public
|
||||
```
|
||||
|
||||
### SQS очередь
|
||||
|
||||
```bash
|
||||
# Через admin stats endpoint
|
||||
curl -s https://iot.kube5s.ru/iot-admin/stats \
|
||||
-H "Authorization: Bearer <ADMIN_STATS_TOKEN>" \
|
||||
| jq '.sqs'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Отладка
|
||||
|
||||
### Устройство не подключается по MQTT
|
||||
|
||||
1. Проверить phase: `kubectl get iotdevice {name} -n {ns} -o jsonpath='{.status.phase}'`
|
||||
— Должно быть `Active`
|
||||
2. Проверить Secret: `kubectl get secret iot-{deviceId} -n {ns}`
|
||||
3. Проверить EMQX logs: `kubectl logs -n sless deployment/emqx | grep "auth"`
|
||||
4. Ручная проверка auth:
|
||||
```bash
|
||||
kubectl port-forward svc/iot-operator -n sless 9090:9090
|
||||
curl -X POST http://localhost:9090/internal/mqtt/auth \
|
||||
-d '{"username":"sless_sensor-01","password":"...","clientid":"test"}'
|
||||
```
|
||||
|
||||
### Телеметрия не появляется в API
|
||||
|
||||
1. Bridge подключён? `kubectl logs -n sless deployment/iot-mqtt-bridge | tail -20`
|
||||
2. SQS получает? `curl /iot-admin/stats` → sqs.approximate_messages
|
||||
3. Consumer обрабатывает? `kubectl logs -n sless deployment/iot-sqs-consumer | tail -20`
|
||||
4. Postgres доступен? Проверить логи consumer на ошибки подключения
|
||||
|
||||
### Bridge не подключается к MQTT
|
||||
|
||||
1. Проверить Secret iot-bridge-credentials:
|
||||
`kubectl get secret iot-bridge-credentials -n sless -o jsonpath='{.data.MQTT_USERNAME}' | base64 -d`
|
||||
2. Проверить env в Bridge pod:
|
||||
`kubectl exec -n sless deployment/iot-mqtt-bridge -- env | grep MQTT`
|
||||
|
||||
---
|
||||
|
||||
## IoT Console (Web UI)
|
||||
|
||||
Открыть `https://iot.kube5s.ru/console` в браузере.
|
||||
|
||||
Функции:
|
||||
- CRUD устройств через REST API
|
||||
- Встроенный MQTT WebSocket клиент (wss://iot.kube5s.ru/mqtt)
|
||||
- Real-time отображение входящей телеметрии
|
||||
- Просмотр истории из Postgres
|
||||
|
||||
---
|
||||
|
||||
## IoT Admin Panel
|
||||
|
||||
Открыть `https://iot.kube5s.ru/iot-admin` в браузере.
|
||||
|
||||
Функции:
|
||||
- Статистика по PostgreSQL (количество записей по тенантам)
|
||||
- SQS: approximate message count
|
||||
- Статус подов bridge и consumer
|
||||
- Автообновление каждые 30 секунд
|
||||
@@ -169,3 +169,39 @@ TLS сертификат для `iot.kube5s.ru` выпускается cert-mana
|
||||
|
||||
### Следующий шаг
|
||||
E2E тест: создать устройство → MQTT publish → проверить SQS → Postgres → API.
|
||||
|
||||
---
|
||||
|
||||
## Сессия: Документация v0.2.3 (продолжение)
|
||||
|
||||
Агент: GitHub Copilot (Claude Opus 4.6)
|
||||
|
||||
### Что сделано
|
||||
|
||||
1. **architecture/current-v0.2.3.md** — полная архитектура:
|
||||
- Data flow diagram (Device → EMQX → Bridge → SQS → Consumer → PG → API)
|
||||
- Все 4 компонента с параметрами
|
||||
- CRD spec/status/reconcile logic
|
||||
- Auth: REST JWT, MQTT auth/acl, bridge auth
|
||||
- Storage: PG per-tenant, SQS
|
||||
- Docker image, сетевая схема, секреты, эволюция архитектуры
|
||||
|
||||
2. **api/endpoints-v0.2.3.md** — документация API:
|
||||
- Изучил router.go, handler.go, iot_device_handler.go, iot_telemetry_handler.go, iot_admin_stats_handler.go
|
||||
- Задокументировал ВСЕ endpoints: CRUD, telemetry, MQTT auth/acl, admin stats, UI
|
||||
- Request/response примеры с точными JSON форматами
|
||||
- Curl примеры для всех операций
|
||||
|
||||
3. **run-and-test.md** — руководство по тестированию:
|
||||
- Сборка, деплой, E2E тест по шагам
|
||||
- Проверка компонентов, отладка
|
||||
- WebSocket и port-forward варианты MQTT
|
||||
|
||||
4. **progress.md** — дополнена секция документации
|
||||
|
||||
### Проблемы
|
||||
- Скрипт /tmp/write_arch.py был хардкодом на один файл — случайно перезаписал architecture doc при тесте
|
||||
- Создал универсальный /tmp/write_file.py с аргументом пути — больше проблем нет
|
||||
|
||||
### Осталось
|
||||
- git commit + push
|
||||
|
||||
Reference in New Issue
Block a user