mirror of
https://github.com/warmbly/warmbly.git
synced 2026-08-19 16:01:16 +00:00
174 lines
5.4 KiB
Go
174 lines
5.4 KiB
Go
package config
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
|
|
awsconfig "github.com/aws/aws-sdk-go-v2/config"
|
|
"github.com/warmbly/warmbly/internal/infrastructure/secrets"
|
|
"github.com/warmbly/warmbly/internal/infrastructure/ssm"
|
|
)
|
|
|
|
type Config struct {
|
|
Env string // "dev" or "prod"
|
|
AWSConfigEnabled bool
|
|
params *ssm.SSMParameterStore
|
|
secrets *secrets.SecretsManagerClient
|
|
}
|
|
|
|
// NewConfig creates a new config instance with env-first loading and optional AWS fallback.
|
|
// AWS clients are only initialized if AWS_CONFIG_ENABLED=true.
|
|
func NewConfig(ctx context.Context) (*Config, error) {
|
|
env := getEnvOrDefault("APP_ENV", "dev")
|
|
awsEnabled := getEnvOrDefault("AWS_CONFIG_ENABLED", "false") == "true"
|
|
|
|
cfg := &Config{
|
|
Env: env,
|
|
AWSConfigEnabled: awsEnabled,
|
|
}
|
|
|
|
if awsEnabled {
|
|
awsCfg, err := awsconfig.LoadDefaultConfig(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load AWS config: %w", err)
|
|
}
|
|
|
|
params, err := ssm.NewSSMParameterStore(ctx, awsCfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create SSM client: %w", err)
|
|
}
|
|
cfg.params = params
|
|
|
|
secretsClient, err := secrets.NewSecretsManagerClient(ctx, awsCfg)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to create Secrets Manager client: %w", err)
|
|
}
|
|
cfg.secrets = secretsClient
|
|
}
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
// Load creates a Config with pre-initialized AWS clients (legacy compatibility).
|
|
// Deprecated: Use NewConfig for new code.
|
|
func Load(params *ssm.SSMParameterStore, secrets *secrets.SecretsManagerClient) *Config {
|
|
env := getEnvOrDefault("APP_ENV", "dev")
|
|
|
|
return &Config{
|
|
Env: env,
|
|
AWSConfigEnabled: true, // Legacy mode always has AWS enabled
|
|
params: params,
|
|
secrets: secrets,
|
|
}
|
|
}
|
|
|
|
// GetKeyID returns the full AWS parameter/secret path with environment prefix.
|
|
func (c *Config) GetKeyID(s string) string {
|
|
return "/warmbly/" + c.Env + "/" + s
|
|
}
|
|
|
|
// getEnvOrDefault returns the environment variable value or a default if not set.
|
|
func getEnvOrDefault(key, defaultVal string) string {
|
|
if val := os.Getenv(key); val != "" {
|
|
return val
|
|
}
|
|
return defaultVal
|
|
}
|
|
|
|
// GetString retrieves a configuration value, checking env var first, then AWS SSM if enabled.
|
|
func (c *Config) GetString(ctx context.Context, envKey, awsKey string) (string, error) {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val, nil
|
|
}
|
|
if c.AWSConfigEnabled && c.params != nil {
|
|
return c.params.Get(ctx, c.GetKeyID(awsKey))
|
|
}
|
|
return "", fmt.Errorf("config %s not found (env: %s, aws: %s)", envKey, envKey, awsKey)
|
|
}
|
|
|
|
// GetStringRaw retrieves a configuration value from AWS SSM using the raw key (no environment prefix).
|
|
func (c *Config) GetStringRaw(ctx context.Context, envKey, awsKey string) (string, error) {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val, nil
|
|
}
|
|
if c.AWSConfigEnabled && c.params != nil {
|
|
return c.params.Get(ctx, awsKey)
|
|
}
|
|
return "", fmt.Errorf("config %s not found (env: %s, aws: %s)", envKey, envKey, awsKey)
|
|
}
|
|
|
|
// GetSecret retrieves a secret value, checking env var first, then AWS Secrets Manager if enabled.
|
|
func (c *Config) GetSecret(ctx context.Context, envKey, awsKey string) (string, error) {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val, nil
|
|
}
|
|
if c.AWSConfigEnabled && c.secrets != nil {
|
|
return c.secrets.Get(ctx, c.GetKeyID(awsKey))
|
|
}
|
|
return "", fmt.Errorf("secret %s not found (env: %s, aws: %s)", envKey, envKey, awsKey)
|
|
}
|
|
|
|
// GetSecretRaw retrieves a secret value from AWS Secrets Manager using the raw key (no environment prefix).
|
|
func (c *Config) GetSecretRaw(ctx context.Context, envKey, awsKey string) (string, error) {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val, nil
|
|
}
|
|
if c.AWSConfigEnabled && c.secrets != nil {
|
|
return c.secrets.Get(ctx, awsKey)
|
|
}
|
|
return "", fmt.Errorf("secret %s not found (env: %s, aws: %s)", envKey, envKey, awsKey)
|
|
}
|
|
|
|
// GetStringOptional retrieves an optional configuration value with a default fallback.
|
|
func (c *Config) GetStringOptional(ctx context.Context, envKey, awsKey, defaultVal string) string {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val
|
|
}
|
|
if c.AWSConfigEnabled && c.params != nil {
|
|
if val, err := c.params.Get(ctx, c.GetKeyID(awsKey)); err == nil && val != "" {
|
|
return val
|
|
}
|
|
}
|
|
return defaultVal
|
|
}
|
|
|
|
// GetStringOptionalRaw retrieves an optional configuration value using raw AWS key.
|
|
func (c *Config) GetStringOptionalRaw(ctx context.Context, envKey, awsKey, defaultVal string) string {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val
|
|
}
|
|
if c.AWSConfigEnabled && c.params != nil {
|
|
if val, err := c.params.Get(ctx, awsKey); err == nil && val != "" {
|
|
return val
|
|
}
|
|
}
|
|
return defaultVal
|
|
}
|
|
|
|
// GetSecretOptional retrieves an optional secret value with a default fallback.
|
|
func (c *Config) GetSecretOptional(ctx context.Context, envKey, awsKey, defaultVal string) string {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val
|
|
}
|
|
if c.AWSConfigEnabled && c.secrets != nil {
|
|
if val, err := c.secrets.Get(ctx, c.GetKeyID(awsKey)); err == nil && val != "" {
|
|
return val
|
|
}
|
|
}
|
|
return defaultVal
|
|
}
|
|
|
|
// GetSecretOptionalRaw retrieves an optional secret value using raw AWS key.
|
|
func (c *Config) GetSecretOptionalRaw(ctx context.Context, envKey, awsKey, defaultVal string) string {
|
|
if val := os.Getenv(envKey); val != "" {
|
|
return val
|
|
}
|
|
if c.AWSConfigEnabled && c.secrets != nil {
|
|
if val, err := c.secrets.Get(ctx, awsKey); err == nil && val != "" {
|
|
return val
|
|
}
|
|
}
|
|
return defaultVal
|
|
}
|