Merge pull request #1307 from hashicorp/b-provider-config-merge
terraform: merge provider configs before validate [GH-1282]
This commit is contained in:
commit
19c7f8cff4
|
@ -2505,6 +2505,9 @@ func TestContext2Input_provider(t *testing.T) {
|
||||||
actual = c.Config["foo"]
|
actual = c.Config["foo"]
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
|
||||||
|
return nil, c.CheckSet([]string{"foo"})
|
||||||
|
}
|
||||||
|
|
||||||
if err := ctx.Input(InputModeStd); err != nil {
|
if err := ctx.Input(InputModeStd); err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
|
|
|
@ -6,17 +6,18 @@ import (
|
||||||
"github.com/hashicorp/terraform/config"
|
"github.com/hashicorp/terraform/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EvalConfigProvider is an EvalNode implementation that configures
|
// EvalBuildProviderConfig outputs a *ResourceConfig that is properly
|
||||||
// a provider that is already initialized and retrieved.
|
// merged with parents and inputs on top of what is configured in the file.
|
||||||
type EvalConfigProvider struct {
|
type EvalBuildProviderConfig struct {
|
||||||
Provider string
|
Provider string
|
||||||
Config **ResourceConfig
|
Config **ResourceConfig
|
||||||
|
Output **ResourceConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
|
func (n *EvalBuildProviderConfig) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
cfg := *n.Config
|
cfg := *n.Config
|
||||||
|
|
||||||
// If we have a configuration set, then use that
|
// If we have a configuration set, then merge that in
|
||||||
if input := ctx.ProviderInput(n.Provider); input != nil {
|
if input := ctx.ProviderInput(n.Provider); input != nil {
|
||||||
rc, err := config.NewRawConfig(input)
|
rc, err := config.NewRawConfig(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -33,7 +34,19 @@ func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
cfg = NewResourceConfig(merged)
|
cfg = NewResourceConfig(merged)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ctx.ConfigureProvider(n.Provider, cfg)
|
*n.Output = cfg
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EvalConfigProvider is an EvalNode implementation that configures
|
||||||
|
// a provider that is already initialized and retrieved.
|
||||||
|
type EvalConfigProvider struct {
|
||||||
|
Provider string
|
||||||
|
Config **ResourceConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *EvalConfigProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
|
return nil, ctx.ConfigureProvider(n.Provider, *n.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EvalInitProvider is an EvalNode implementation that initializes a provider
|
// EvalInitProvider is an EvalNode implementation that initializes a provider
|
||||||
|
|
|
@ -5,6 +5,71 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestEvalBuildProviderConfig_impl(t *testing.T) {
|
||||||
|
var _ EvalNode = new(EvalBuildProviderConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEvalBuildProviderConfig(t *testing.T) {
|
||||||
|
config := testResourceConfig(t, map[string]interface{}{})
|
||||||
|
provider := "foo"
|
||||||
|
|
||||||
|
n := &EvalBuildProviderConfig{
|
||||||
|
Provider: provider,
|
||||||
|
Config: &config,
|
||||||
|
Output: &config,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := &MockEvalContext{
|
||||||
|
ParentProviderConfigConfig: testResourceConfig(t, map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
}),
|
||||||
|
ProviderInputConfig: map[string]interface{}{
|
||||||
|
"bar": "baz",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if _, err := n.Eval(ctx); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
"bar": "baz",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(config.Raw, expected) {
|
||||||
|
t.Fatalf("bad: %#v", config.Raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEvalBuildProviderConfig_parentPriority(t *testing.T) {
|
||||||
|
config := testResourceConfig(t, map[string]interface{}{})
|
||||||
|
provider := "foo"
|
||||||
|
|
||||||
|
n := &EvalBuildProviderConfig{
|
||||||
|
Provider: provider,
|
||||||
|
Config: &config,
|
||||||
|
Output: &config,
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := &MockEvalContext{
|
||||||
|
ParentProviderConfigConfig: testResourceConfig(t, map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
}),
|
||||||
|
ProviderInputConfig: map[string]interface{}{
|
||||||
|
"foo": "baz",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if _, err := n.Eval(ctx); err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expected := map[string]interface{}{
|
||||||
|
"foo": "bar",
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(config.Raw, expected) {
|
||||||
|
t.Fatalf("bad: %#v", config.Raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestEvalConfigProvider_impl(t *testing.T) {
|
func TestEvalConfigProvider_impl(t *testing.T) {
|
||||||
var _ EvalNode = new(EvalConfigProvider)
|
var _ EvalNode = new(EvalConfigProvider)
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,21 +57,14 @@ RETURN:
|
||||||
// EvalValidateProvider is an EvalNode implementation that validates
|
// EvalValidateProvider is an EvalNode implementation that validates
|
||||||
// the configuration of a resource.
|
// the configuration of a resource.
|
||||||
type EvalValidateProvider struct {
|
type EvalValidateProvider struct {
|
||||||
ProviderName string
|
Provider *ResourceProvider
|
||||||
Provider *ResourceProvider
|
Config **ResourceConfig
|
||||||
Config **ResourceConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) {
|
func (n *EvalValidateProvider) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
provider := *n.Provider
|
provider := *n.Provider
|
||||||
config := *n.Config
|
config := *n.Config
|
||||||
|
|
||||||
// Get the parent configuration if there is one
|
|
||||||
if parent := ctx.ParentProviderConfig(n.ProviderName); parent != nil {
|
|
||||||
merged := parent.raw.Merge(config.raw)
|
|
||||||
config = NewResourceConfig(merged)
|
|
||||||
}
|
|
||||||
|
|
||||||
warns, errs := provider.Validate(config)
|
warns, errs := provider.Validate(config)
|
||||||
if len(warns) == 0 && len(errs) == 0 {
|
if len(warns) == 0 && len(errs) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
|
|
@ -44,10 +44,14 @@ func ProviderEvalTree(n string, config *config.RawConfig) EvalNode {
|
||||||
Config: config,
|
Config: config,
|
||||||
Output: &resourceConfig,
|
Output: &resourceConfig,
|
||||||
},
|
},
|
||||||
|
&EvalBuildProviderConfig{
|
||||||
|
Provider: n,
|
||||||
|
Config: &resourceConfig,
|
||||||
|
Output: &resourceConfig,
|
||||||
|
},
|
||||||
&EvalValidateProvider{
|
&EvalValidateProvider{
|
||||||
ProviderName: n,
|
Provider: &provider,
|
||||||
Provider: &provider,
|
Config: &resourceConfig,
|
||||||
Config: &resourceConfig,
|
|
||||||
},
|
},
|
||||||
&EvalConfigProvider{
|
&EvalConfigProvider{
|
||||||
Provider: n,
|
Provider: n,
|
||||||
|
|
Loading…
Reference in New Issue