89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
|
)
|
|
|
|
var envVarNamePattern = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
|
|
|
|
type secretsLoadStats struct {
|
|
Dir string
|
|
Loaded int
|
|
PreservedExisting int
|
|
Skipped int
|
|
}
|
|
|
|
func loadSecretsFromConfig(cfg *config.Config, logger *slog.Logger) (*secretsLoadStats, error) {
|
|
if cfg == nil || cfg.Pipeline == nil || cfg.Pipeline.Secrets == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
rawDir := strings.TrimSpace(cfg.Pipeline.Secrets.EnvDir)
|
|
if rawDir == "" {
|
|
return nil, nil
|
|
}
|
|
|
|
resolvedDir := rawDir
|
|
if !filepath.IsAbs(resolvedDir) {
|
|
cwd, err := os.Getwd()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("resolve secrets env_dir %q from current working directory: %w", rawDir, err)
|
|
}
|
|
resolvedDir = filepath.Join(cwd, resolvedDir)
|
|
}
|
|
resolvedDir = filepath.Clean(resolvedDir)
|
|
|
|
entries, err := os.ReadDir(resolvedDir)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read secrets env_dir %q: %w", resolvedDir, err)
|
|
}
|
|
|
|
stats := &secretsLoadStats{Dir: resolvedDir}
|
|
for _, entry := range entries {
|
|
name := entry.Name()
|
|
if !envVarNamePattern.MatchString(name) {
|
|
stats.Skipped++
|
|
continue
|
|
}
|
|
if entry.IsDir() {
|
|
stats.Skipped++
|
|
continue
|
|
}
|
|
|
|
secretPath := filepath.Join(resolvedDir, name)
|
|
bytes, err := os.ReadFile(secretPath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read secret file %q: %w", secretPath, err)
|
|
}
|
|
value := strings.TrimRight(string(bytes), "\r\n")
|
|
|
|
if _, exists := os.LookupEnv(name); exists {
|
|
stats.PreservedExisting++
|
|
continue
|
|
}
|
|
if err := os.Setenv(name, value); err != nil {
|
|
return nil, fmt.Errorf("set environment variable %q from %q: %w", name, secretPath, err)
|
|
}
|
|
stats.Loaded++
|
|
}
|
|
|
|
if logger != nil {
|
|
logger.Info(
|
|
"loaded secret environment variables from filesystem",
|
|
"secrets_env_dir", stats.Dir,
|
|
"loaded", stats.Loaded,
|
|
"preserved_existing", stats.PreservedExisting,
|
|
"skipped", stats.Skipped,
|
|
)
|
|
}
|
|
|
|
return stats, nil
|
|
}
|