64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var secretNamePattern = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`)
|
|
|
|
func loadSecrets(cfg SecretsConfig) error {
|
|
if cfg.Directory == "" {
|
|
return nil
|
|
}
|
|
|
|
entries, err := os.ReadDir(cfg.Directory)
|
|
if err != nil {
|
|
return fmt.Errorf("read secrets directory %q: %w", cfg.Directory, err)
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
name := entry.Name()
|
|
if name == "" {
|
|
return fmt.Errorf("secrets directory %q contains an empty filename", cfg.Directory)
|
|
}
|
|
if !secretNamePattern.MatchString(name) {
|
|
return fmt.Errorf("secret file %q has invalid environment variable name", name)
|
|
}
|
|
if entry.Type()&os.ModeSymlink != 0 {
|
|
return fmt.Errorf("secret file %q must be a regular file, not a symlink", name)
|
|
}
|
|
if entry.IsDir() {
|
|
return fmt.Errorf("secret file %q must be a regular file, not a directory", name)
|
|
}
|
|
|
|
info, err := entry.Info()
|
|
if err != nil {
|
|
return fmt.Errorf("inspect secret file %q: %w", name, err)
|
|
}
|
|
if !info.Mode().IsRegular() {
|
|
return fmt.Errorf("secret file %q must be a regular file", name)
|
|
}
|
|
|
|
path := filepath.Join(cfg.Directory, name)
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return fmt.Errorf("read secret file %q: %w", name, err)
|
|
}
|
|
value := string(data)
|
|
if strings.HasSuffix(value, "\r\n") {
|
|
value = strings.TrimSuffix(value, "\r\n")
|
|
} else {
|
|
value = strings.TrimSuffix(value, "\n")
|
|
}
|
|
if err := os.Setenv(name, value); err != nil {
|
|
return fmt.Errorf("set environment variable from secret file %q: %w", name, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|