- handler.go: убраны бизнес-логика и k8s-типы (corev1/k8serrors/metav1)
handler.go теперь только инфраструктура: Handler struct + helpers
- namespace.go: новый файл — EnsureNamespace хендлер живёт здесь
SoC: создание namespace — отдельная ответственность, не смешивается с CRUD
- router.go: добавлен маршрут POST /v1/namespaces/{namespace}/ensure
- client.go: добавлен метод EnsureNamespace(ctx, ns) → POST /ensure
- provider.go: Configure() вызывает c.EnsureNamespace(ctx, namespace) после создания Client
Namespace создаётся ОДИН РАЗ при инициализации провайдера
Resource-хендлеры (Function, Trigger, Job) namespace не трогают
- .gitignore: добавлена директория secrets/ (токены, ключи)
- provider v0.1.13, operator v0.1.21
Operator: naeel/sless-operator:v0.1.21
Provider: terra.k8c.ru/naeel/sless v0.1.13
74 lines
3.0 KiB
Go
74 lines
3.0 KiB
Go
// Изменено: 2026-03-11
|
||
// Handler — общий контейнер зависимостей для всех REST handlers.
|
||
// Все handlers получают доступ к k8s, S3 и Postgres через эту структуру.
|
||
// Логирование через slog, маршрутизация через gorilla/mux.
|
||
//
|
||
// Этот файл — чистая инфраструктура: только Handler struct + вспомогательные функции.
|
||
// Бизнес-логика по доменам — в отдельных файлах:
|
||
// - namespace.go — EnsureNamespace (создание k8s namespace)
|
||
// - functions.go — CRUD функций
|
||
// - triggers.go — CRUD триггеров
|
||
// - jobs.go — CRUD одноразовых запусков
|
||
// - upload.go — загрузка кода, сборка образа
|
||
// - invoke.go — прокси вызова функций
|
||
//
|
||
// Архитектура namespace:
|
||
// - Namespace создаётся ОДИН РАЗ через EnsureNamespace при инициализации провайдера.
|
||
// - Resource-хендлеры namespace не трогают — это не их ответственность.
|
||
// - defaultNamespace используется только как fallback для dev/тестов.
|
||
|
||
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-naeel.giteak8s.services.ngcloud.ru/naeel/sless/internal/storage/postgres"
|
||
"gitea-naeel.giteak8s.services.ngcloud.ru/naeel/sless/internal/storage/s3"
|
||
)
|
||
|
||
// defaultNamespace — fallback namespace для dev/тестов.
|
||
// В production namespace определяется из JWT-токена провайдером.
|
||
// Все обращения к "default" строке идут через эту константу — одно место замены.
|
||
const defaultNamespace = "default"
|
||
|
||
// Handler содержит зависимости для всех REST-обработчиков.
|
||
type Handler struct {
|
||
K8s client.Client
|
||
Scheme *runtime.Scheme
|
||
S3 *s3.Client
|
||
PG *postgres.Store
|
||
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.
|
||
// Fallback — defaultNamespace (используется только в dev/тестах).
|
||
func namespace(r *http.Request) string {
|
||
if ns := mux.Vars(r)["namespace"]; ns != "" {
|
||
return ns
|
||
}
|
||
return defaultNamespace
|
||
}
|