// newValidConfig builds a new environConfig from the provided Config // and returns it. This includes applying the provided defaults // values, if any. The resulting config values are validated. func newValidConfig(cfg *config.Config, defaults map[string]interface{}) (*environConfig, error) { // Any auth credentials handling should happen first... // Ensure that the provided config is valid. if err := config.Validate(cfg, nil); err != nil { return nil, errors.Trace(err) } // Apply the defaults and coerce/validate the custom config attrs. fixedDefaults, unset := adjustDefaults(cfg, defaults) cfg, err := cfg.Remove(unset) if err != nil { return nil, errors.Trace(err) } validated, err := cfg.ValidateUnknownAttrs(configFields, fixedDefaults) if err != nil { return nil, errors.Trace(err) } validCfg, err := cfg.Apply(validated) if err != nil { return nil, errors.Trace(err) } // Build the config. ecfg := newConfig(validCfg) // Update to defaults set via client config. clientCfg, err := ecfg.clientConfig() if err != nil { return nil, errors.Trace(err) } ecfg, err = ecfg.updateForClientConfig(clientCfg) if err != nil { return nil, errors.Trace(err) } // Do final (more complex, provider-specific) validation. if err := ecfg.validate(); err != nil { return nil, errors.Trace(err) } return ecfg, nil }