Этап 2+4: internal/api/handler/iot_device_handler.go
- MQTTAuth: POST /internal/mqtt/auth (без JWT, для EMQX)
- CreateIoTDevice, ListIoTDevices, GetIoTDevice (c password), DeleteIoTDevice, UpdateIoTDevice
- crypto/subtle.ConstantTimeCompare против timing attacks
Этап 4: internal/api/router.go
- /v1/namespaces/{ns}/iot/devices CRUD
- /internal/mqtt/auth (без JWT middleware)
Этап 3: deployments/k8s/emqx.yaml
- EMQX 5.5.1, emqx.conf (HOCON) с HTTP auth backend
- Сервис exposure: 1883 (MQTT), 8083 (WS), 18083 (Dashboard)
Этап 3: iot/cmd/mqtt-bridge/main.go
- paho.mqtt.golang: подписка на +/telemetry/+
- amqp091-go: publish в iot.{namespace}.telemetry
- deployments/k8s/iot-mqtt-bridge.yaml
Этап 7: examples/IOT/ — E2E demo (main.tf, handler.py, README.md)
go.mod: добавлен github.com/eclipse/paho.mqtt.golang v1.5.1
go build ./... — ошибок нет
84 lines
2.6 KiB
Markdown
84 lines
2.6 KiB
Markdown
# IoT MVP — E2E Demo
|
|
|
|
## Что делает этот пример
|
|
|
|
Показывает полную цепочку:
|
|
|
|
```
|
|
IoT Device (mosquitto_pub)
|
|
→ MQTT PUBLISH → EMQX (HTTP auth → sless-operator)
|
|
→ [iot-mqtt-bridge подписан на "+/telemetry/+"]
|
|
→ RabbitMQ queue "iot.{namespace}.telemetry"
|
|
→ event-dispatcher
|
|
→ POST → serverless function (handler.py)
|
|
```
|
|
|
|
## Предусловия
|
|
|
|
1. EMQX запущен: `kubectl apply -f deployments/k8s/emqx.yaml`
|
|
2. iot-mqtt-bridge запущен: `kubectl apply -f deployments/k8s/iot-mqtt-bridge.yaml`
|
|
3. event-dispatcher запущен (уже должен работать)
|
|
|
|
## Запуск
|
|
|
|
```bash
|
|
# Установить переменные
|
|
export API_TOKEN="your-jwt-token"
|
|
export NAMESPACE="sless-abc123def456" # твой namespace
|
|
|
|
# Инициализировать
|
|
terraform init
|
|
terraform apply \
|
|
-var="namespace=${NAMESPACE}" \
|
|
-var="api_token=${API_TOKEN}"
|
|
|
|
# Получить credentials
|
|
MQTT_USER=$(terraform output -raw mqtt_username)
|
|
MQTT_PASS=$(terraform output -raw mqtt_password)
|
|
MQTT_TOPIC=$(terraform output -raw mqtt_topic)
|
|
|
|
echo "MQTT user: ${MQTT_USER}"
|
|
echo "MQTT topic: ${MQTT_TOPIC}"
|
|
```
|
|
|
|
## Отправить тестовое сообщение
|
|
|
|
```bash
|
|
# Через mosquitto_pub (из пода внутри кластера)
|
|
kubectl run mqtt-test --rm -i --image=eclipse-mosquitto --restart=Never -- \
|
|
mosquitto_pub \
|
|
-h emqx.sless.svc \
|
|
-p 1883 \
|
|
-u "${MQTT_USER}" \
|
|
-P "${MQTT_PASS}" \
|
|
-t "${MQTT_TOPIC}" \
|
|
-m '{"temperature": 22.5, "humidity": 65, "unit": "celsius"}'
|
|
```
|
|
|
|
## Проверить что функция вызвалась
|
|
|
|
```bash
|
|
# Логи event-dispatcher
|
|
kubectl logs -n sless deployment/event-dispatcher -f
|
|
|
|
# Логи функции (через invocations API)
|
|
curl -H "Authorization: Bearer ${API_TOKEN}" \
|
|
https://sless.kube5s.ru/v1/namespaces/${NAMESPACE}/functions/iot-telemetry-handler/invocations
|
|
```
|
|
|
|
## Структура файлов
|
|
|
|
```
|
|
examples/IOT/
|
|
main.tf # Terraform: function + trigger + iot_device
|
|
handler.py # Python обработчик телеметрии
|
|
README.md # Этот файл
|
|
```
|
|
|
|
## Известные ограничения MVP
|
|
|
|
- `sless_iot_device` Terraform ресурс требует реализации в terraform-provider-sless (Этап 6)
|
|
- EMQX TLS отключён — включить для prod (настроить cert-manager secret)
|
|
- iot-mqtt-bridge credentials создаются вручную (автоматизировать в будущем)
|
|
- Нет обратного канала: Cloud → Device команды (Device Shadow — вне MVP)
|