terraform: handle multiple same named states

This commit is contained in:
Mitchell Hashimoto 2016-04-30 17:29:03 -05:00
parent cfa58a25a6
commit c814d36333
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
2 changed files with 82 additions and 2 deletions

View File

@ -319,6 +319,48 @@ func TestContextImport_multiState(t *testing.T) {
}
}
func TestContextImport_multiStateSame(t *testing.T) {
p := testProvider("aws")
ctx := testContext2(t, &ContextOpts{
Providers: map[string]ResourceProviderFactory{
"aws": testProviderFuncFixed(p),
},
})
p.ImportStateReturn = []*InstanceState{
&InstanceState{
ID: "foo",
Ephemeral: EphemeralState{Type: "aws_instance"},
},
&InstanceState{
ID: "bar",
Ephemeral: EphemeralState{Type: "aws_instance_thing"},
},
&InstanceState{
ID: "qux",
Ephemeral: EphemeralState{Type: "aws_instance_thing"},
},
}
state, err := ctx.Import(&ImportOpts{
Targets: []*ImportTarget{
&ImportTarget{
Addr: "aws_instance.foo",
ID: "bar",
},
},
})
if err != nil {
t.Fatalf("err: %s", err)
}
actual := strings.TrimSpace(state.String())
expected := strings.TrimSpace(testImportMultiSameStr)
if actual != expected {
t.Fatalf("bad: \n%s", actual)
}
}
const testImportStr = `
aws_instance.foo:
ID = foo
@ -369,6 +411,18 @@ aws_instance_thing.foo:
provider = aws
`
const testImportMultiSameStr = `
aws_instance.foo:
ID = foo
provider = aws
aws_instance_thing.foo:
ID = bar
provider = aws
aws_instance_thing.foo-1:
ID = qux
provider = aws
`
const testImportRefreshStr = `
aws_instance.foo:
ID = foo

View File

@ -91,13 +91,39 @@ func (n *graphNodeImportState) EvalTree() EvalNode {
func (n *graphNodeImportState) DynamicExpand(ctx EvalContext) (*Graph, error) {
g := &Graph{Path: ctx.Path()}
// nameCounter is used to de-dup names in the state.
nameCounter := make(map[string]int)
// Compile the list of addresses that we'll be inserting into the state.
// We do this ahead of time so we can verify that we aren't importing
// something that already exists.
addrs := make([]*ResourceAddress, len(n.states))
for i, state := range n.states {
addr := *n.Addr
if t := state.Ephemeral.Type; t != "" {
addr.Type = t
}
// Determine if we need to suffix the name to de-dup
key := addr.String()
count, ok := nameCounter[key]
if ok {
count++
addr.Name += fmt.Sprintf("-%d", count)
}
nameCounter[key] = count
// Add it to our list
addrs[i] = &addr
}
// For each of the states, we add a node to handle the refresh/add to state.
// "n.states" is populated by our own EvalTree with the result of
// ImportState. Since DynamicExpand is always called after EvalTree, this
// is safe.
for _, state := range n.states {
for i, state := range n.states {
g.Add(&graphNodeImportStateSub{
Target: n.Addr,
Target: addrs[i],
Path_: n.Path(),
State: state,
})