Skip to content

Commit

Permalink
Merge pull request #214 from articulate/feature/validate-env-vars-pro…
Browse files Browse the repository at this point in the history
…ducts

feat(validate): add products field to dependencies
  • Loading branch information
mloberg authored May 17, 2024
2 parents c312e21 + 4c0b399 commit 5947339
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 10 deletions.
9 changes: 9 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,30 @@ import (
"fmt"
"log/slog"
"os"
"path/filepath"
"strconv"
)

type Config struct {
Service string
Environment string
Product string
Region string
ServiceDefinition string
SkipValidation bool
Program string
}

// NewFromEnv creates a new Config from environment variables and defaults
func NewFromEnv() *Config {
cfg := &Config{
Service: os.Getenv("SERVICE_NAME"),
Environment: os.Getenv("SERVICE_ENV"),
Product: os.Getenv("SERVICE_PRODUCT"),
Region: os.Getenv("AWS_REGION"),
ServiceDefinition: os.Getenv("SERVICE_DEFINITION"),
SkipValidation: false,
Program: "docker-bootstrap",
}

if s, err := strconv.ParseBool(os.Getenv("BOOTSTRAP_SKIP_VALIDATION")); err == nil {
Expand All @@ -46,6 +51,10 @@ func NewFromEnv() *Config {
cfg.ServiceDefinition = "service.json"
}

if ex, err := os.Executable(); err == nil {
cfg.Program = filepath.Base(ex)
}

return cfg
}

Expand Down
8 changes: 7 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ func main() {
}

cfg := NewFromEnv()
logger = logger.With("env", cfg.Environment, "service", cfg.Service, "region", cfg.Region)
logger = logger.With(
slog.String("env", cfg.Environment),
slog.String("service", cfg.Service),
slog.String("product", cfg.Product),
slog.String("region", cfg.Region),
slog.String("program", cfg.Program),
)
slog.SetDefault(logger)

if len(os.Args) < 2 {
Expand Down
11 changes: 6 additions & 5 deletions validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,17 @@ type (
Partial bool `json:"-"`
}
dependencyInner struct {
Key string `json:"key"`
Regions []string `json:"regions"`
Key string `json:"key"`
Regions []string `json:"regions"`
Products []string `json:"products"`
}
)

var ErrMissingEnvVars = errors.New("missing required environment variables")

// Required returns true if the dependency is required for the given region
func (d *dependency) Required(region string) bool {
return d.Regions == nil || lo.Contains(d.Regions, region)
func (d *dependency) Required(product, region string) bool {
return (d.Products == nil || lo.Contains(d.Products, product)) && (d.Regions == nil || lo.Contains(d.Regions, region))
}

// UnmarshalJSON handles the dependency being a string or an object
Expand Down Expand Up @@ -91,7 +92,7 @@ func validate(ctx context.Context, c *Config, e *EnvMap, l *slog.Logger) error {
func missing(deps []dependency, c *Config, e *EnvMap) []string {
res := []string{}
for _, d := range deps {
if !d.Required(c.Region) {
if !d.Required(c.Product, c.Region) {
continue
}

Expand Down
37 changes: 33 additions & 4 deletions validate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,30 @@ func TestDependency_Required(t *testing.T) {
Regions: []string{"us-east-1"},
},
}
assert.True(t, d.Required("us-east-1"))
assert.False(t, d.Required("us-west-2"))
assert.True(t, d.Required("test", "us-east-1"))
assert.False(t, d.Required("test", "us-west-2"))

d = dependency{}
assert.True(t, d.Required("us-east-1"))
assert.True(t, d.Required("us-west-2"))
assert.True(t, d.Required("test", "us-east-1"))
assert.True(t, d.Required("test", "us-west-2"))

d = dependency{
dependencyInner: dependencyInner{
Products: []string{"test"},
},
}
assert.True(t, d.Required("test", "us-east-1"))
assert.False(t, d.Required("prod", "us-east-1"))

d = dependency{
dependencyInner: dependencyInner{
Regions: []string{"us-east-1"},
Products: []string{"test"},
},
}
assert.False(t, d.Required("prod", "us-east-1"))
assert.False(t, d.Required("test", "us-west-2"))
assert.True(t, d.Required("test", "us-east-1"))
}

func TestValidate(t *testing.T) { //nolint:funlen
Expand All @@ -37,6 +55,10 @@ func TestValidate(t *testing.T) { //nolint:funlen
},
{
"key":"BAZ"
},
{
"key": "FIZZ",
"products": ["test"]
}
],
"optional": [
Expand Down Expand Up @@ -107,4 +129,11 @@ func TestValidate(t *testing.T) { //nolint:funlen
require.NoError(t, err)
assert.NotContains(t, log.String(), "Missing required environment variables")
assert.NotContains(t, log.String(), "Missing optional environment variables")

// Missing required env vars for product
log.Reset()
c.Product = "test"
err = validate(context.TODO(), c, e, l)
require.ErrorIs(t, err, ErrMissingEnvVars)
assert.Contains(t, log.String(), `Missing required environment variables","env_vars":["FIZZ"]`)
}

0 comments on commit 5947339

Please sign in to comment.