feat: перенос IoT managed service из sless в отдельную репу
Компоненты: - iot-operator: controller-manager (IoTDevice CRD) + REST API (порт 9090) - mqtt-bridge: MQTT (EMQX) → Kafka bridge - kafka-consumer: Kafka → Postgres pipeline Модуль: gitea.services.ngcloud.ru/Nail/IoT Все 3 бинарника собираются, import paths адаптированы.
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
// Создано: 2026-04-12
|
||||
// Handler — контейнер зависимостей для IoT REST handlers.
|
||||
// Упрощённая версия из sless — только IoT-специфичные поля.
|
||||
//
|
||||
// Бизнес-логика:
|
||||
// - iot_device_handler.go — CRUD устройств + MQTT auth
|
||||
// - iot_telemetry_handler.go — чтение телеметрии
|
||||
// - iot_admin_stats_handler.go — админ-статистика
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"gitea.services.ngcloud.ru/Nail/IoT/internal/storage/iotpg"
|
||||
)
|
||||
|
||||
// defaultNamespace — fallback namespace для dev/тестов.
|
||||
const defaultNamespace = "default"
|
||||
|
||||
// Handler содержит зависимости для всех IoT REST-обработчиков.
|
||||
type Handler struct {
|
||||
K8s client.Client
|
||||
Scheme *runtime.Scheme
|
||||
// IoTPG — хранилище IoT телеметрии (per-tenant Postgres). nil если IOT_PG_DSN не задан.
|
||||
IoTPG *iotpg.IoTPostgresStore
|
||||
// KafkaBrokers — адреса Kafka брокеров для чтения consumer lag на admin странице.
|
||||
KafkaBrokers string
|
||||
Log *slog.Logger
|
||||
}
|
||||
|
||||
// writeJSON отправляет JSON-ответ с указанным статусом.
|
||||
func writeJSON(w http.ResponseWriter, status int, v any) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(status)
|
||||
_ = json.NewEncoder(w).Encode(v)
|
||||
}
|
||||
|
||||
// errResp возвращает структуру ошибки для JSON.
|
||||
func errResp(msg string) map[string]string {
|
||||
return map[string]string{"error": msg}
|
||||
}
|
||||
|
||||
// pathVar читает переменную пути из gorilla/mux.
|
||||
func pathVar(r *http.Request, key string) string {
|
||||
return mux.Vars(r)[key]
|
||||
}
|
||||
|
||||
// namespace читает {namespace} из пути URL.
|
||||
func namespace(r *http.Request) string {
|
||||
if ns := mux.Vars(r)["namespace"]; ns != "" {
|
||||
return ns
|
||||
}
|
||||
return defaultNamespace
|
||||
}
|
||||
Reference in New Issue
Block a user