terraform: Module option to Import to add module to graph

This commit is contained in:
Mitchell Hashimoto 2016-05-10 09:15:19 -07:00
parent ec02c8c0e2
commit 27452f0043
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
5 changed files with 94 additions and 1 deletions

View File

@ -35,7 +35,16 @@ func NewTree(name string, c *config.Config) *Tree {
// NewEmptyTree returns a new tree that is empty (contains no configuration). // NewEmptyTree returns a new tree that is empty (contains no configuration).
func NewEmptyTree() *Tree { func NewEmptyTree() *Tree {
return &Tree{config: &config.Config{}} t := &Tree{config: &config.Config{}}
// We do this dummy load so that the tree is marked as "loaded". It
// should never fail because this is just about a no-op. If it does fail
// we panic so we can know its a bug.
if err := t.Load(nil, GetModeGet); err != nil {
panic(err)
}
return t
} }
// NewTreeModule is like NewTree except it parses the configuration in // NewTreeModule is like NewTree except it parses the configuration in

View File

@ -1,8 +1,18 @@
package terraform package terraform
import (
"github.com/hashicorp/terraform/config/module"
)
// ImportOpts are used as the configuration for Import. // ImportOpts are used as the configuration for Import.
type ImportOpts struct { type ImportOpts struct {
// Targets are the targets to import
Targets []*ImportTarget Targets []*ImportTarget
// Module is optional, and specifies a config module that is loaded
// into the graph and evaluated. The use case for this is to provide
// provider configuration.
Module *module.Tree
} }
// ImportTarget is a single resource to import. // ImportTarget is a single resource to import.
@ -42,6 +52,7 @@ func (c *Context) Import(opts *ImportOpts) (*State, error) {
// Initialize our graph builder // Initialize our graph builder
builder := &ImportGraphBuilder{ builder := &ImportGraphBuilder{
ImportTargets: opts.Targets, ImportTargets: opts.Targets,
Module: opts.Module,
Providers: providers, Providers: providers,
} }

View File

@ -1,6 +1,7 @@
package terraform package terraform
import ( import (
"fmt"
"strings" "strings"
"testing" "testing"
) )
@ -122,6 +123,58 @@ func TestContextImport_missingType(t *testing.T) {
} }
} }
func TestContextImport_moduleProvider(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"},
},
}
configured := false
p.ConfigureFn = func(c *ResourceConfig) error {
configured = true
if v, ok := c.Get("foo"); !ok || v.(string) != "bar" {
return fmt.Errorf("bad")
}
return nil
}
m := testModule(t, "import-provider")
state, err := ctx.Import(&ImportOpts{
Module: m,
Targets: []*ImportTarget{
&ImportTarget{
Addr: "aws_instance.foo",
ID: "bar",
},
},
})
if err != nil {
t.Fatalf("err: %s", err)
}
if !configured {
t.Fatal("didn't configure provider")
}
actual := strings.TrimSpace(state.String())
expected := strings.TrimSpace(testImportStr)
if actual != expected {
t.Fatalf("bad: \n%s", actual)
}
}
func TestContextImport_refresh(t *testing.T) { func TestContextImport_refresh(t *testing.T) {
p := testProvider("aws") p := testProvider("aws")
ctx := testContext2(t, &ContextOpts{ ctx := testContext2(t, &ContextOpts{

View File

@ -1,5 +1,9 @@
package terraform package terraform
import (
"github.com/hashicorp/terraform/config/module"
)
// ImportGraphBuilder implements GraphBuilder and is responsible for building // ImportGraphBuilder implements GraphBuilder and is responsible for building
// a graph for importing resources into Terraform. This is a much, much // a graph for importing resources into Terraform. This is a much, much
// simpler graph than a normal configuration graph. // simpler graph than a normal configuration graph.
@ -7,6 +11,9 @@ type ImportGraphBuilder struct {
// ImportTargets are the list of resources to import. // ImportTargets are the list of resources to import.
ImportTargets []*ImportTarget ImportTargets []*ImportTarget
// Module is the module to add to the graph. See ImportOpts.Module.
Module *module.Tree
// Providers is the list of providers supported. // Providers is the list of providers supported.
Providers []string Providers []string
} }
@ -22,7 +29,17 @@ func (b *ImportGraphBuilder) Build(path []string) (*Graph, error) {
// Steps returns the ordered list of GraphTransformers that must be executed // Steps returns the ordered list of GraphTransformers that must be executed
// to build a complete graph. // to build a complete graph.
func (b *ImportGraphBuilder) Steps() []GraphTransformer { func (b *ImportGraphBuilder) Steps() []GraphTransformer {
// Get the module. If we don't have one, we just use an empty tree
// so that the transform still works but does nothing.
mod := b.Module
if mod == nil {
mod = module.NewEmptyTree()
}
steps := []GraphTransformer{ steps := []GraphTransformer{
// Create all our resources from the configuration and state
&ConfigTransformer{Module: mod},
// Add the import steps // Add the import steps
&ImportStateTransformer{Targets: b.ImportTargets}, &ImportStateTransformer{Targets: b.ImportTargets},

View File

@ -0,0 +1,3 @@
provider "aws" {
foo = "bar"
}