Компоненты: - 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 адаптированы.
68 lines
2.7 KiB
Go
68 lines
2.7 KiB
Go
// Создано: 2026-04-12
|
|
// router.go — регистрация IoT REST-маршрутов.
|
|
// Перенесено из sless — только IoT-специфичные маршруты.
|
|
// CORS для https://iot.kube5s.ru, JWT auth через middleware.Auth.
|
|
|
|
package api
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"gitea.services.ngcloud.ru/Nail/IoT/internal/api/handler"
|
|
"gitea.services.ngcloud.ru/Nail/IoT/internal/api/middleware"
|
|
)
|
|
|
|
// corsMiddleware добавляет CORS-заголовки для IoT Консоли на https://iot.kube5s.ru.
|
|
func corsMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Access-Control-Allow-Origin", "https://iot.kube5s.ru")
|
|
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
|
|
w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type")
|
|
w.Header().Set("Access-Control-Max-Age", "600")
|
|
if r.Method == http.MethodOptions {
|
|
w.WriteHeader(http.StatusNoContent)
|
|
return
|
|
}
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
// NewRouter собирает gorilla/mux роутер со всеми IoT маршрутами.
|
|
func NewRouter(h *handler.Handler, log *slog.Logger) http.Handler {
|
|
r := mux.NewRouter()
|
|
|
|
// IoT Консоль — публичный HTML
|
|
r.HandleFunc("/console", ServeIoTConsole).Methods(http.MethodGet)
|
|
|
|
// IoT Admin — страница администратора
|
|
r.HandleFunc("/iot-admin", ServeIoTAdmin).Methods(http.MethodGet)
|
|
r.HandleFunc("/iot-admin/stats", h.AdminStats).Methods(http.MethodGet)
|
|
|
|
// /v1 — API маршруты, защищены JWT
|
|
v1 := r.PathPrefix("/v1").Subrouter()
|
|
|
|
// IoT Devices CRUD
|
|
v1.HandleFunc("/namespaces/{namespace}/iot/devices", h.ListIoTDevices).Methods(http.MethodGet)
|
|
v1.HandleFunc("/namespaces/{namespace}/iot/devices", h.CreateIoTDevice).Methods(http.MethodPost)
|
|
v1.HandleFunc("/namespaces/{namespace}/iot/devices/{name}", h.GetIoTDevice).Methods(http.MethodGet)
|
|
v1.HandleFunc("/namespaces/{namespace}/iot/devices/{name}", h.DeleteIoTDevice).Methods(http.MethodDelete)
|
|
v1.HandleFunc("/namespaces/{namespace}/iot/devices/{name}", h.UpdateIoTDevice).Methods(http.MethodPatch)
|
|
|
|
// IoT Telemetry
|
|
v1.HandleFunc("/namespaces/{namespace}/iot/telemetry", h.ListIoTTelemetry).Methods(http.MethodGet)
|
|
|
|
// MQTT Auth — без JWT, вызывается EMQX из кластера
|
|
r.HandleFunc("/internal/mqtt/auth", h.MQTTAuth).Methods(http.MethodPost)
|
|
r.HandleFunc("/internal/mqtt/acl", h.MQTTAcl).Methods(http.MethodPost)
|
|
|
|
// JWT auth middleware для /v1/
|
|
v1.Use(func(next http.Handler) http.Handler {
|
|
return middleware.Auth(log, next)
|
|
})
|
|
|
|
return corsMiddleware(middleware.Logging(log, r))
|
|
}
|