116 lines
4.3 KiB
Go
116 lines
4.3 KiB
Go
package config
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type Config struct {
|
|
Addr string
|
|
JWTSecret []byte // OMNEX_JWT_SECRET (min 32 octets) — signe les tokens
|
|
SessionTTL time.Duration // durée de vie JWT + session Redis
|
|
AllowedOrigins []string // CORS (vitrine + back-office)
|
|
Env string // "dev" | "prod"
|
|
DatabaseURL string // OMNEX_DATABASE_URL (DSN PostgreSQL GORM)
|
|
RedisURL string // OMNEX_REDIS_URL (sessions), ex. redis://:pass@host:6379/0
|
|
DemoDomain string // domaine des démos
|
|
DemoHTTPSPort string // port HTTPS public à afficher dans l'URL des démos (443 = omis, sinon ex. NodePort)
|
|
Kubeconfig string
|
|
FrontendImage string
|
|
BackendImage string
|
|
LBTelegramImage string
|
|
AppDownloadsDir string // OMNEX_APP_DOWNLOADS_DIR : répertoire des .apk téléchargeables (voir internal/downloads)
|
|
// DockerHubUsername/Password : compte Docker Hub authentifié (droits
|
|
// lecture seule) injecté dans chaque namespace de démo (voir
|
|
// deploy/chart-gestion/registry-credentials) pour passer le rate-limit
|
|
// de pull anonyme (100/6h par IP) à 200/6h. "" = pull anonyme (défaut).
|
|
DockerHubUsername string
|
|
DockerHubPassword string
|
|
|
|
// Projets vitrine (abonnements de 1 à 12 mois, voir internal/projects).
|
|
VitrineDomain string // OMNEX_VITRINE_DOMAIN : les projets sont servis sur <namespace>.<domaine>
|
|
VitrineChartsDir string // OMNEX_VITRINE_CHARTS_DIR : charts backend/frontend/postgresql/redis/ingressroute du projet vitrine
|
|
VitrineBackendImage string // VITRINE_BACKEND_IMAGE, ex. registry/vitrine-backend:1.0.0
|
|
VitrineFrontendImage string // VITRINE_FRONTEND_IMAGE
|
|
// VitrineGraceDays : jours pendant lesquels un projet dont l'abonnement
|
|
// a expiré reste suspendu (données et sauvegardes conservées) avant sa
|
|
// suppression définitive. Un renouvellement pendant ce délai le relance.
|
|
VitrineGraceDays int
|
|
}
|
|
|
|
// Load lit la config. Fail-secure : secret JWT obligatoire ; en prod base + Redis aussi.
|
|
func Load() (Config, error) {
|
|
secret := os.Getenv("OMNEX_JWT_SECRET")
|
|
if len(secret) < 32 {
|
|
return Config{}, errors.New("OMNEX_JWT_SECRET manquant ou < 32 octets")
|
|
}
|
|
|
|
cfg := Config{
|
|
Addr: getenv("OMNEX_ADDR", ":8080"),
|
|
JWTSecret: []byte(secret),
|
|
SessionTTL: 24 * time.Hour,
|
|
AllowedOrigins: splitCSV(getenv("OMNEX_ALLOWED_ORIGINS", "http://localhost:5173")),
|
|
Env: getenv("OMNEX_ENV", "dev"),
|
|
DatabaseURL: os.Getenv("OMNEX_DATABASE_URL"),
|
|
RedisURL: os.Getenv("OMNEX_REDIS_URL"),
|
|
DemoDomain: getenv("OMNEX_DEMO_DOMAIN", "demo.omnex.app"),
|
|
DemoHTTPSPort: getenv("OMNEX_DEMO_HTTPS_PORT", "443"),
|
|
Kubeconfig: os.Getenv("KUBECONFIG"),
|
|
FrontendImage: os.Getenv("FRONTEND_IMAGE_APP"),
|
|
BackendImage: os.Getenv("BACKEND_IMAGE_APP"),
|
|
LBTelegramImage: os.Getenv("LBTELEGRAM_IMAGE_APP"),
|
|
AppDownloadsDir: getenv("OMNEX_APP_DOWNLOADS_DIR", "/app-downloads"),
|
|
DockerHubUsername: os.Getenv("OMNEX_DOCKERHUB_USERNAME"),
|
|
DockerHubPassword: os.Getenv("OMNEX_DOCKERHUB_PASSWORD"),
|
|
|
|
VitrineDomain: getenv("OMNEX_VITRINE_DOMAIN", "vitrine-omnex.club"),
|
|
VitrineChartsDir: getenv("OMNEX_VITRINE_CHARTS_DIR", "/charts-vitrine"),
|
|
VitrineBackendImage: os.Getenv("VITRINE_BACKEND_IMAGE"),
|
|
VitrineFrontendImage: os.Getenv("VITRINE_FRONTEND_IMAGE"),
|
|
VitrineGraceDays: 7,
|
|
}
|
|
if v := os.Getenv("OMNEX_VITRINE_GRACE_DAYS"); v != "" {
|
|
days, err := strconv.Atoi(v)
|
|
if err != nil || days < 0 || days > 365 {
|
|
return Config{}, errors.New("OMNEX_VITRINE_GRACE_DAYS doit être un entier entre 0 et 365")
|
|
}
|
|
cfg.VitrineGraceDays = days
|
|
}
|
|
|
|
if cfg.Env == "prod" {
|
|
if cfg.DatabaseURL == "" {
|
|
return Config{}, errors.New("OMNEX_DATABASE_URL requis en prod")
|
|
}
|
|
if cfg.RedisURL == "" {
|
|
return Config{}, errors.New("OMNEX_REDIS_URL requis en prod (sessions)")
|
|
}
|
|
}
|
|
return cfg, nil
|
|
}
|
|
|
|
// Secure indique si les cookies doivent porter l'attribut Secure (HTTPS).
|
|
func (c Config) Secure() bool { return c.Env == "prod" }
|
|
|
|
func getenv(k, def string) string {
|
|
if v := os.Getenv(k); v != "" {
|
|
return v
|
|
}
|
|
return def
|
|
}
|
|
|
|
func splitCSV(s string) []string {
|
|
var out []string
|
|
start := 0
|
|
for i := 0; i <= len(s); i++ {
|
|
if i == len(s) || s[i] == ',' {
|
|
if seg := s[start:i]; seg != "" {
|
|
out = append(out, seg)
|
|
}
|
|
start = i + 1
|
|
}
|
|
}
|
|
return out
|
|
}
|