terraform: ImportTransformer, EvalImportState

This commit is contained in:
Mitchell Hashimoto 2016-04-28 11:46:46 +02:00
parent 1685054a9a
commit aca26fd784
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
4 changed files with 124 additions and 23 deletions

View File

@ -1,19 +1,8 @@
package terraform
/*
import (
"bytes"
"fmt"
"os"
"reflect"
"sort"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
"github.com/hashicorp/terraform/config/module"
)
func TestContextImport(t *testing.T) {
@ -24,24 +13,23 @@ func TestContextImport(t *testing.T) {
},
})
if _, err := ctx.Plan(); err != nil {
t.Fatalf("err: %s", err)
}
state, err := ctx.Apply()
state, err := ctx.Import(&ImportOpts{
Targets: []*ImportTarget{
&ImportTarget{
Addr: "aws_instance.foo",
ID: "bar",
},
},
})
if err != nil {
t.Fatalf("err: %s", err)
}
mod := state.RootModule()
if len(mod.Resources) < 2 {
t.Fatalf("bad: %#v", mod.Resources)
}
actual := strings.TrimSpace(state.String())
expected := strings.TrimSpace(testTerraformApplyStr)
expected := strings.TrimSpace(testImportStr)
if actual != expected {
t.Fatalf("bad: \n%s", actual)
}
}
*/
const testImportStr = ``

View File

@ -0,0 +1,32 @@
package terraform
import (
"fmt"
)
// EvalImportState is an EvalNode implementation that performs an
// ImportState operation on a provider. This will return the imported
// states but won't modify any actual state.
type EvalImportState struct {
Provider *ResourceProvider
Info *InstanceInfo
Output *[]*InstanceState
}
// TODO: test
func (n *EvalImportState) Eval(ctx EvalContext) (interface{}, error) {
provider := *n.Provider
// Refresh!
state, err := provider.ImportState(n.Info)
if err != nil {
return nil, fmt.Errorf(
"import %s (id: %s): %s", n.Info.Type, n.Info.Id, err)
}
if n.Output != nil {
*n.Output = state
}
return nil, nil
}

View File

@ -23,6 +23,9 @@ func (b *ImportGraphBuilder) Build(path []string) (*Graph, error) {
// to build a complete graph.
func (b *ImportGraphBuilder) Steps() []GraphTransformer {
steps := []GraphTransformer{
// Add the import steps
&ImportStateTransformer{Targets: b.ImportTargets},
// Provider-related transformations
&MissingProviderTransformer{Providers: b.Providers},
&ProviderTransformer{},

View File

@ -0,0 +1,78 @@
package terraform
import (
"fmt"
)
// ImportStateTransformer is a GraphTransformer that adds nodes to the
// graph to represent the imports we want to do for resources.
type ImportStateTransformer struct {
Targets []*ImportTarget
}
func (t *ImportStateTransformer) Transform(g *Graph) error {
nodes := make([]*graphNodeImportState, 0, len(t.Targets))
for _, target := range t.Targets {
addr, err := ParseResourceAddress(target.Addr)
if err != nil {
return fmt.Errorf(
"failed to parse resource address '%s': %s",
target.Addr, err)
}
nodes = append(nodes, &graphNodeImportState{
Addr: addr,
ID: target.ID,
})
}
// Build the graph vertices
for _, n := range nodes {
g.Add(n)
}
return nil
}
type graphNodeImportState struct {
Addr *ResourceAddress // Addr is the resource address to import to
ID string // ID is the ID to import as
}
func (n *graphNodeImportState) Name() string {
return fmt.Sprintf("import %s (id: %s)", n.Addr, n.ID)
}
func (n *graphNodeImportState) ProvidedBy() []string {
return []string{resourceProvider(n.Addr.Type, "")}
}
// GraphNodeSubPath
func (n *graphNodeImportState) Path() []string {
return n.Addr.Path
}
// GraphNodeEvalable impl.
func (n *graphNodeImportState) EvalTree() EvalNode {
var provider ResourceProvider
var states []*InstanceState
info := &InstanceInfo{
Id: n.ID,
ModulePath: n.Addr.Path,
Type: n.Addr.Type,
}
return &EvalSequence{
Nodes: []EvalNode{
&EvalGetProvider{
Name: n.ProvidedBy()[0],
Output: &provider,
},
&EvalImportState{
Provider: &provider,
Info: info,
Output: &states,
},
},
}
}