Files
sless/internal/config/config.go
T
“Naeel” 43e7d0ea48 feat: REST API (gorilla/mux + slog) + trigger controller + main.go wiring
- controllers/trigger_controller.go: полная реализация, HTTP->Ingress+Service, Cron->CronJob
- internal/config: добавлены IngressHost, APIToken
- internal/api/router.go: gorilla/mux роутер /v1/namespaces/{ns}/...
- internal/api/handler/: functions, triggers, invocations, base handler с slog
- internal/api/middleware/: auth (Bearer token) + logging (slog)
- main.go: запуск operator + HTTP сервера параллельно
- go.sum: добавлен gorilla/mux v1.8.1
2026-03-07 08:46:10 +04:00

123 lines
4.1 KiB
Go

// Изменено: 2026-03-07
// Конфигурация сервиса — читается из env переменных при старте.
// Все компоненты (API, builder, runner) получают конфиг через эту структуру.
// Используем env а не файлы конфигурации — стандарт для k8s (ConfigMap/Secret → env).
package config
import (
"fmt"
"os"
"strconv"
)
// Config — централизованная конфигурация всего сервиса.
type Config struct {
// APIPort — порт на котором слушает REST API сервер (default: 8080)
APIPort int
// PostgreSQL — параметры подключения к БД для хранения логов вызовов
PostgresDSN string
// S3 — параметры подключения к Ceph S3 для хранения кода функций
S3Endpoint string
S3AccessKey string
S3SecretKey string
S3Bucket string
S3UseSSL bool
// Registry — адрес внутреннего Docker registry куда пушим собранные образы
RegistryHost string
// FunctionNamespace — префикс namespace для функций пользователей.
// Итоговый namespace: FunctionNamespacePrefix + "-" + functionName
FunctionNamespacePrefix string
// BuilderImage — образ для сборки функций (kaniko или buildah)
BuilderImage string
// IngressHost — базовый домен для HTTP триггеров, например: fn.kube5s.ru
// URL функции будет: https://{funcName}-{namespace}.{IngressHost}
IngressHost string
// APIToken — статический Bearer-токен для v1 REST API аутентификации.
// В prod заменить на вызов auth-сервиса.
APIToken string
}
// Load читает конфиг из env переменных.
// Возвращает ошибку если обязательные переменные не заданы.
func Load() (*Config, error) {
cfg := &Config{
APIPort: 8080,
S3UseSSL: false,
FunctionNamespacePrefix: "sless-fn",
BuilderImage: "gcr.io/kaniko-project/executor:latest",
}
// Опциональный порт API
if v := os.Getenv("API_PORT"); v != "" {
port, err := strconv.Atoi(v)
if err != nil {
return nil, fmt.Errorf("API_PORT must be a number: %w", err)
}
cfg.APIPort = port
}
// Обязательные параметры PostgreSQL
cfg.PostgresDSN = os.Getenv("POSTGRES_DSN")
if cfg.PostgresDSN == "" {
return nil, fmt.Errorf("POSTGRES_DSN is required")
}
// Обязательные параметры S3
cfg.S3Endpoint = os.Getenv("S3_ENDPOINT")
if cfg.S3Endpoint == "" {
return nil, fmt.Errorf("S3_ENDPOINT is required")
}
cfg.S3AccessKey = os.Getenv("S3_ACCESS_KEY")
if cfg.S3AccessKey == "" {
return nil, fmt.Errorf("S3_ACCESS_KEY is required")
}
cfg.S3SecretKey = os.Getenv("S3_SECRET_KEY")
if cfg.S3SecretKey == "" {
return nil, fmt.Errorf("S3_SECRET_KEY is required")
}
cfg.S3Bucket = os.Getenv("S3_BUCKET")
if cfg.S3Bucket == "" {
// Используем дефолтный бакет если не задан
cfg.S3Bucket = "sless-functions"
}
if v := os.Getenv("S3_USE_SSL"); v == "true" {
cfg.S3UseSSL = true
}
// Обязательный адрес registry
cfg.RegistryHost = os.Getenv("REGISTRY_HOST")
if cfg.RegistryHost == "" {
return nil, fmt.Errorf("REGISTRY_HOST is required")
}
// Опциональные параметры с дефолтами
if v := os.Getenv("FUNCTION_NAMESPACE_PREFIX"); v != "" {
cfg.FunctionNamespacePrefix = v
}
if v := os.Getenv("BUILDER_IMAGE"); v != "" {
cfg.BuilderImage = v
}
// IngressHost — базовый домен для HTTP триггеров
cfg.IngressHost = os.Getenv("INGRESS_HOST")
if cfg.IngressHost == "" {
cfg.IngressHost = "fn.kube5s.ru"
}
// APIToken — обязательный токен для REST API
cfg.APIToken = os.Getenv("SLESS_API_TOKEN")
if cfg.APIToken == "" {
return nil, fmt.Errorf("SLESS_API_TOKEN is required")
}
return cfg, nil
}