From 133a28e363e7a02ae63ef1c309976b0d14cb0ae1 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Mon, 29 Sep 2014 10:36:49 -0700 Subject: [PATCH] terraform: prefix the Id for configuring providers --- terraform/context.go | 8 ++++- terraform/context_test.go | 50 +++++++++++++++++++++++++++++++ terraform/ui_input_prefix.go | 17 +++++++++++ terraform/ui_input_prefix_test.go | 26 ++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 terraform/ui_input_prefix.go create mode 100644 terraform/ui_input_prefix_test.go diff --git a/terraform/context.go b/terraform/context.go index ab3a008d8..f43dfbfb2 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -569,11 +569,17 @@ func (c *walkContext) inputWalkFn() depgraph.WalkFunc { } rc := NewResourceConfig(raw) + // Wrap the input into a namespace + input := &PrefixUIInput{ + IdPrefix: fmt.Sprintf("provider.%s", rn.ID), + UIInput: c.Context.uiInput, + } + // Go through each provider and capture the input necessary // to satisfy it. configs := make(map[string]map[string]interface{}) for k, p := range sharedProvider.Providers { - newc, err := p.Input(c.Context.uiInput, rc) + newc, err := p.Input(input, rc) if err != nil { return fmt.Errorf( "Error configuring %s: %s", k, err) diff --git a/terraform/context_test.go b/terraform/context_test.go index 95ca3dd0f..222b54ec4 100644 --- a/terraform/context_test.go +++ b/terraform/context_test.go @@ -499,6 +499,56 @@ func TestContextInput_provider(t *testing.T) { } } +func TestContextInput_providerId(t *testing.T) { + input := new(MockUIInput) + m := testModule(t, "input-provider") + p := testProvider("aws") + p.ApplyFn = testApplyFn + p.DiffFn = testDiffFn + ctx := testContext(t, &ContextOpts{ + Module: m, + Providers: map[string]ResourceProviderFactory{ + "aws": testProviderFuncFixed(p), + }, + UIInput: input, + }) + + var actual interface{} + p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) { + v, err := i.Input(&InputOpts{Id: "foo"}) + if err != nil { + return nil, err + } + + c.Raw["foo"] = v + return c, nil + } + p.ConfigureFn = func(c *ResourceConfig) error { + actual = c.Raw["foo"] + return nil + } + + input.InputReturnMap = map[string]string{ + "provider.aws.foo": "bar", + } + + if err := ctx.Input(); err != nil { + t.Fatalf("err: %s", err) + } + + if _, err := ctx.Plan(nil); err != nil { + t.Fatalf("err: %s", err) + } + + if _, err := ctx.Apply(); err != nil { + t.Fatalf("err: %s", err) + } + + if !reflect.DeepEqual(actual, "bar") { + t.Fatalf("bad: %#v", actual) + } +} + func TestContextApply(t *testing.T) { m := testModule(t, "apply-good") p := testProvider("aws") diff --git a/terraform/ui_input_prefix.go b/terraform/ui_input_prefix.go new file mode 100644 index 000000000..0ba40debe --- /dev/null +++ b/terraform/ui_input_prefix.go @@ -0,0 +1,17 @@ +package terraform + +import ( + "fmt" +) + +// PrefixUIInput is an implementation of UIInput that prefixes the ID +// with a string, allowing queries to be namespaced. +type PrefixUIInput struct { + IdPrefix string + UIInput UIInput +} + +func (i *PrefixUIInput) Input(opts *InputOpts) (string, error) { + opts.Id = fmt.Sprintf("%s.%s", i.IdPrefix, opts.Id) + return i.UIInput.Input(opts) +} diff --git a/terraform/ui_input_prefix_test.go b/terraform/ui_input_prefix_test.go new file mode 100644 index 000000000..39e552156 --- /dev/null +++ b/terraform/ui_input_prefix_test.go @@ -0,0 +1,26 @@ +package terraform + +import ( + "testing" +) + +func TestPrefixUIInput_impl(t *testing.T) { + var _ UIInput = new(PrefixUIInput) +} + +func testPrefixUIInput(t *testing.T) { + input := new(MockUIInput) + prefix := &PrefixUIInput{ + IdPrefix: "foo", + UIInput: input, + } + + _, err := prefix.Input(&InputOpts{Id: "bar"}) + if err != nil { + t.Fatalf("err: %s", err) + } + + if input.InputOpts.Id != "foo.bar" { + t.Fatalf("bad: %#v", input.InputOpts) + } +}