From c88614c585dd8d4d4b954ab4679896e8ebb8b517 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 24 Sep 2014 21:38:23 -0700 Subject: [PATCH] terraform: providers inherit properly for validation --- terraform/context.go | 31 +++++++++++++++++++ terraform/context_test.go | 23 ++++++++++++++ terraform/resource_provider_mock.go | 4 +++ .../validate-module-pc-inherit/child/main.tf | 3 ++ .../validate-module-pc-inherit/main.tf | 9 ++++++ 5 files changed, 70 insertions(+) create mode 100644 terraform/test-fixtures/validate-module-pc-inherit/child/main.tf create mode 100644 terraform/test-fixtures/validate-module-pc-inherit/main.tf diff --git a/terraform/context.go b/terraform/context.go index 213a6b79d..8eb637f77 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -837,6 +837,37 @@ func (c *walkContext) validateWalkFn() depgraph.WalkFunc { raw = sharedProvider.Config.RawConfig } + // If we have a parent, then merge in the parent configurations + // properly so we "inherit" the configurations. + if sharedProvider.Parent != nil { + var rawMap map[string]interface{} + if raw != nil { + rawMap = raw.Raw + } + + parent := sharedProvider.Parent + for parent != nil { + if parent.Config != nil { + if rawMap == nil { + rawMap = parent.Config.RawConfig.Raw + } + + for k, v := range parent.Config.RawConfig.Raw { + rawMap[k] = v + } + } + + parent = parent.Parent + } + + // Update our configuration to be the merged result + var err error + raw, err = config.NewRawConfig(rawMap) + if err != nil { + return fmt.Errorf("Error merging configurations: %s", err) + } + } + rc := NewResourceConfig(raw) for k, p := range sharedProvider.Providers { diff --git a/terraform/context_test.go b/terraform/context_test.go index b1e28b4db..e3b22dea5 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -128,6 +128,29 @@ func TestContextValidate_moduleBadResource(t *testing.T) { } } +func TestContextValidate_moduleProviderInherit(t *testing.T) { + m := testModule(t, "validate-module-pc-inherit") + p := testProvider("aws") + c := testContext(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + }) + + p.ValidateFn = func(c *ResourceConfig) ([]string, []error) { + return nil, c.CheckSet([]string{"set"}) + } + + w, e := c.Validate() + if len(w) > 0 { + t.Fatalf("bad: %#v", w) + } + if len(e) > 0 { + t.Fatalf("bad: %#v", e) + } +} + func TestContextValidate_orphans(t *testing.T) { p := testProvider("aws") m := testModule(t, "validate-good") diff --git a/terraform/resource_provider_mock.go b/terraform/resource_provider_mock.go index 2cd9e9ac4..060fef33b 100644 --- a/terraform/resource_provider_mock.go +++ b/terraform/resource_provider_mock.go @@ -40,6 +40,7 @@ type MockResourceProvider struct { ResourcesReturn []ResourceType ValidateCalled bool ValidateConfig *ResourceConfig + ValidateFn func(*ResourceConfig) ([]string, []error) ValidateReturnWarns []string ValidateReturnErrors []error ValidateResourceFn func(string, *ResourceConfig) ([]string, []error) @@ -56,6 +57,9 @@ func (p *MockResourceProvider) Validate(c *ResourceConfig) ([]string, []error) { p.ValidateCalled = true p.ValidateConfig = c + if p.ValidateFn != nil { + return p.ValidateFn(c) + } return p.ValidateReturnWarns, p.ValidateReturnErrors } diff --git a/terraform/test-fixtures/validate-module-pc-inherit/child/main.tf b/terraform/test-fixtures/validate-module-pc-inherit/child/main.tf new file mode 100644 index 000000000..37189c1ff --- /dev/null +++ b/terraform/test-fixtures/validate-module-pc-inherit/child/main.tf @@ -0,0 +1,3 @@ +provider "aws" {} + +resource "aws_instance" "foo" {} diff --git a/terraform/test-fixtures/validate-module-pc-inherit/main.tf b/terraform/test-fixtures/validate-module-pc-inherit/main.tf new file mode 100644 index 000000000..8976f4aa9 --- /dev/null +++ b/terraform/test-fixtures/validate-module-pc-inherit/main.tf @@ -0,0 +1,9 @@ +module "child" { + source = "./child" +} + +provider "aws" { + set = true +} + +resource "aws_instance" "foo" {}