diff --git a/config/v2/resolvers.go b/config/v2/resolvers.go index 508718f57..fbc339319 100644 --- a/config/v2/resolvers.go +++ b/config/v2/resolvers.go @@ -81,6 +81,7 @@ func ResolveStringMap(getter func(Common) map[string]string, commons ...Common) // config objects passed in. Otherwise it will return nil. func ResolveAWSProvider(commons ...Common) *AWSProvider { + // we may in the future want invert this implementation and walk the structs first profile := lastNonNil(AWSProviderProfileGetter, commons...) region := lastNonNil(AWSProviderRegionGetter, commons...) @@ -209,12 +210,14 @@ func SnowflakeProviderAccountGetter(comm Common) *string { } return nil } + func SnowflakeProviderRoleGetter(comm Common) *string { if comm.Providers != nil && comm.Providers.Snowflake != nil { return comm.Providers.Snowflake.Role } return nil } + func SnowflakeProviderRegionGetter(comm Common) *string { if comm.Providers != nil && comm.Providers.Snowflake != nil { return comm.Providers.Snowflake.Region diff --git a/config/v2/validation.go b/config/v2/validation.go index 60449cd44..07e452bd4 100644 --- a/config/v2/validation.go +++ b/config/v2/validation.go @@ -129,7 +129,9 @@ func (c *Config) WalkComponents(f func(component string, commons ...Common)) { for componentName, component := range env.Components { f(fmt.Sprintf("%s/%s", envName, componentName), c.Defaults.Common, env.Common, component.Common) } + return errs } + } // validateInheritedStringField will walk all accounts and components and ensure that a given field is valid at at least @@ -139,37 +141,38 @@ func (c *Config) validateInheritedStringField(fieldName string, getter func(Comm var err *multierror.Error // For each account, we need the field to be valid in either the defaults or account - for acctName, acct := range c.Accounts { - v := lastNonNil(getter, c.Defaults.Common, acct.Common) + for name, acct := range c.Accounts { + v := ResolveAWSProvider(c.Defaults.Common, acct.Common) if v == nil { - err = multierror.Append(err, fmt.Errorf("account %s must have field %s at either the account or defaults level", acctName, fieldName)) - } else if !validator(*v) { - err = multierror.Append(err, fmt.Errorf("account %s must have a valid %s set at either the account or defaults level", acctName, fieldName)) + // nothing to validate + } else if e := validate(*v, fmt.Sprintf("accounts/%s", name)); e != nil { + errs = multierror.Append(errs, e) } } // global - v := lastNonNil(getter, c.Defaults.Common, c.Global.Common) + v := ResolveAWSProvider(c.Defaults.Common, c.Global.Common) if v == nil { - err = multierror.Append(err, fmt.Errorf("global must have a %s set at either the global or defaults level", fieldName)) - } else if !validator(*v) { - err = multierror.Append(err, fmt.Errorf("global must have a valid %s set at either the global or defaults level", fieldName)) + //nothing to do + } else if e := validate(*v, "global"); e != nil { + errs = multierror.Append(errs, e) } // For each component, we need the field to be valid at one of defaults, env or component for envName, env := range c.Envs { for componentName, component := range env.Components { - v := lastNonNil(getter, c.Defaults.Common, env.Common, component.Common) + v := ResolveAWSProvider(c.Defaults.Common, env.Common, component.Common) if v == nil { - err = multierror.Append(err, fmt.Errorf("componnent %s/%s must have a %s", envName, componentName, fieldName)) - } else if !validator(*v) { - err = multierror.Append(err, fmt.Errorf("componnent %s/%s must have a valid %s", envName, componentName, fieldName)) + // nothing to validate + } else if e := validate(*v, fmt.Sprintf("%s/%s", envName, componentName)); e != nil { + errs = multierror.Append(errs, e) } } } - return err + return errs.ErrorOrNil() + } // validateExtraVars make sure users don't specify reserved variables