feat(config): загрузка env-конфига (DSN, ENC-ключ, listen)

This commit is contained in:
2026-07-03 13:35:47 +07:00
parent 50aec973ff
commit fc10451340
4 changed files with 290 additions and 0 deletions
+36
View File
@@ -0,0 +1,36 @@
package config
import (
"encoding/base64"
"fmt"
"os"
)
type Config struct {
DBDSN string
EncKey []byte
ListenAddr string
}
func Load() (*Config, error) {
dsn := os.Getenv("DNS_AR_DB_DSN")
if dsn == "" {
return nil, fmt.Errorf("config: DNS_AR_DB_DSN is required")
}
rawKey := os.Getenv("DNS_AR_ENC_KEY")
if rawKey == "" {
return nil, fmt.Errorf("config: DNS_AR_ENC_KEY is required")
}
key, err := base64.StdEncoding.DecodeString(rawKey)
if err != nil {
return nil, fmt.Errorf("config: DNS_AR_ENC_KEY must be base64: %w", err)
}
if len(key) != 32 {
return nil, fmt.Errorf("config: DNS_AR_ENC_KEY must decode to 32 bytes, got %d", len(key))
}
listen := os.Getenv("DNS_AR_LISTEN")
if listen == "" {
listen = ":8080"
}
return &Config{DBDSN: dsn, EncKey: key, ListenAddr: listen}, nil
}
+46
View File
@@ -0,0 +1,46 @@
package config
import (
"encoding/base64"
"testing"
)
func setEnv(t *testing.T, k, v string) {
t.Helper()
t.Setenv(k, v)
}
func TestLoadValid(t *testing.T) {
key := make([]byte, 32)
for i := range key {
key[i] = byte(i)
}
setEnv(t, "DNS_AR_DB_DSN", "postgres://u:p@localhost:5432/db")
setEnv(t, "DNS_AR_ENC_KEY", base64.StdEncoding.EncodeToString(key))
// DNS_AR_LISTEN не задан — дефолт
cfg, err := Load()
if err != nil {
t.Fatal(err)
}
if cfg.DBDSN == "" || len(cfg.EncKey) != 32 || cfg.ListenAddr != ":8080" {
t.Fatalf("unexpected cfg: %+v", cfg)
}
}
func TestLoadRejectsShortKey(t *testing.T) {
setEnv(t, "DNS_AR_DB_DSN", "postgres://x")
setEnv(t, "DNS_AR_ENC_KEY", base64.StdEncoding.EncodeToString([]byte("short")))
if _, err := Load(); err == nil {
t.Fatal("expected error for non-32-byte key")
}
}
func TestLoadRejectsMissingDSN(t *testing.T) {
key := make([]byte, 32)
setEnv(t, "DNS_AR_DB_DSN", "")
setEnv(t, "DNS_AR_ENC_KEY", base64.StdEncoding.EncodeToString(key))
if _, err := Load(); err == nil {
t.Fatal("expected error for missing DSN")
}
}