Implements import with specified provider
This allows the import with a specified provider. So far it was not possible to get resources imported from a different provider than the default.
This commit is contained in:
parent
b335418d0d
commit
804a5bd3c5
|
@ -32,6 +32,7 @@ func (c *ImportCommand) Run(args []string) int {
|
|||
cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path")
|
||||
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
||||
cmdFlags.StringVar(&configPath, "config", pwd, "path")
|
||||
cmdFlags.StringVar(&c.Meta.provider, "provider", "", "provider")
|
||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||
if err := cmdFlags.Parse(args); err != nil {
|
||||
return 1
|
||||
|
@ -62,8 +63,9 @@ func (c *ImportCommand) Run(args []string) int {
|
|||
newState, err := ctx.Import(&terraform.ImportOpts{
|
||||
Targets: []*terraform.ImportTarget{
|
||||
&terraform.ImportTarget{
|
||||
Addr: args[0],
|
||||
ID: args[1],
|
||||
Addr: args[0],
|
||||
ID: args[1],
|
||||
Provider: c.Meta.provider,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -138,6 +140,8 @@ Options:
|
|||
-state-out=path Path to write updated state file. By default, the
|
||||
"-state" path will be used.
|
||||
|
||||
-provider=provider Provider used for import. Defaults to: ""
|
||||
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
|
|
@ -844,8 +844,53 @@ func TestRefresh_displaysOutputs(t *testing.T) {
|
|||
}
|
||||
*/
|
||||
|
||||
func TestImport_customProvider(t *testing.T) {
|
||||
statePath := testTempFile(t)
|
||||
|
||||
p := testProvider()
|
||||
ui := new(cli.MockUi)
|
||||
c := &ImportCommand{
|
||||
Meta: Meta{
|
||||
ContextOpts: testCtxConfig(p),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
|
||||
p.ImportStateFn = nil
|
||||
p.ImportStateReturn = []*terraform.InstanceState{
|
||||
&terraform.InstanceState{
|
||||
ID: "yay",
|
||||
Ephemeral: terraform.EphemeralState{
|
||||
Type: "test_instance",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-provider", "test.alias",
|
||||
"-state", statePath,
|
||||
"test_instance.foo",
|
||||
"bar",
|
||||
}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
if !p.ImportStateCalled {
|
||||
t.Fatal("ImportState should be called")
|
||||
}
|
||||
|
||||
testStateOutput(t, statePath, testImportCustomProviderStr)
|
||||
}
|
||||
|
||||
const testImportStr = `
|
||||
test_instance.foo:
|
||||
ID = yay
|
||||
provider = test
|
||||
`
|
||||
|
||||
const testImportCustomProviderStr = `
|
||||
test_instance.foo:
|
||||
ID = yay
|
||||
provider = test.alias
|
||||
`
|
||||
|
|
|
@ -72,11 +72,14 @@ type Meta struct {
|
|||
// allowed when walking the graph
|
||||
//
|
||||
// shadow is used to enable/disable the shadow graph
|
||||
//
|
||||
// provider is to specify specific resource providers
|
||||
statePath string
|
||||
stateOutPath string
|
||||
backupPath string
|
||||
parallelism int
|
||||
shadow bool
|
||||
provider string
|
||||
}
|
||||
|
||||
// initStatePaths is used to initialize the default values for
|
||||
|
|
|
@ -23,6 +23,9 @@ type ImportTarget struct {
|
|||
|
||||
// ID is the ID of the resource to import. This is resource-specific.
|
||||
ID string
|
||||
|
||||
// Provider string
|
||||
Provider string
|
||||
}
|
||||
|
||||
// Import takes already-created external resources and brings them
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
// TODO
|
||||
package terraform
|
||||
|
||||
import (
|
||||
|
@ -32,7 +33,6 @@ func TestContextImport_basic(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(state.String())
|
||||
expected := strings.TrimSpace(testImportStr)
|
||||
if actual != expected {
|
||||
|
@ -621,6 +621,41 @@ func TestContextImport_multiStateSame(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestContextImport_customProvider(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"},
|
||||
},
|
||||
}
|
||||
|
||||
state, err := ctx.Import(&ImportOpts{
|
||||
Targets: []*ImportTarget{
|
||||
&ImportTarget{
|
||||
Addr: "aws_instance.foo",
|
||||
ID: "bar",
|
||||
Provider: "aws.alias",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
|
||||
actual := strings.TrimSpace(state.String())
|
||||
expected := strings.TrimSpace(testImportCustomProviderStr)
|
||||
if actual != expected {
|
||||
t.Fatalf("bad: \n%s", actual)
|
||||
}
|
||||
}
|
||||
|
||||
const testImportStr = `
|
||||
aws_instance.foo:
|
||||
ID = foo
|
||||
|
@ -700,3 +735,9 @@ aws_instance.foo:
|
|||
provider = aws
|
||||
foo = bar
|
||||
`
|
||||
|
||||
const testImportCustomProviderStr = `
|
||||
aws_instance.foo:
|
||||
ID = foo
|
||||
provider = aws.alias
|
||||
`
|
||||
|
|
|
@ -21,8 +21,9 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
|||
}
|
||||
|
||||
nodes = append(nodes, &graphNodeImportState{
|
||||
Addr: addr,
|
||||
ID: target.ID,
|
||||
Addr: addr,
|
||||
ID: target.ID,
|
||||
Provider: target.Provider,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -35,8 +36,9 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
|||
}
|
||||
|
||||
type graphNodeImportState struct {
|
||||
Addr *ResourceAddress // Addr is the resource address to import to
|
||||
ID string // ID is the ID to import as
|
||||
Addr *ResourceAddress // Addr is the resource address to import to
|
||||
ID string // ID is the ID to import as
|
||||
Provider string // Provider string
|
||||
|
||||
states []*InstanceState
|
||||
}
|
||||
|
@ -46,7 +48,7 @@ func (n *graphNodeImportState) Name() string {
|
|||
}
|
||||
|
||||
func (n *graphNodeImportState) ProvidedBy() []string {
|
||||
return []string{resourceProvider(n.Addr.Type, "")}
|
||||
return []string{resourceProvider(n.Addr.Type, n.Provider)}
|
||||
}
|
||||
|
||||
// GraphNodeSubPath
|
||||
|
@ -147,9 +149,10 @@ func (n *graphNodeImportState) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
|||
// is safe.
|
||||
for i, state := range n.states {
|
||||
g.Add(&graphNodeImportStateSub{
|
||||
Target: addrs[i],
|
||||
Path_: n.Path(),
|
||||
State: state,
|
||||
Target: addrs[i],
|
||||
Path_: n.Path(),
|
||||
State: state,
|
||||
Provider: n.Provider,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -167,9 +170,10 @@ func (n *graphNodeImportState) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
|||
// and is part of the subgraph. This node is responsible for refreshing
|
||||
// and adding a resource to the state once it is imported.
|
||||
type graphNodeImportStateSub struct {
|
||||
Target *ResourceAddress
|
||||
State *InstanceState
|
||||
Path_ []string
|
||||
Target *ResourceAddress
|
||||
State *InstanceState
|
||||
Path_ []string
|
||||
Provider string
|
||||
}
|
||||
|
||||
func (n *graphNodeImportStateSub) Name() string {
|
||||
|
@ -212,7 +216,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode {
|
|||
return &EvalSequence{
|
||||
Nodes: []EvalNode{
|
||||
&EvalGetProvider{
|
||||
Name: resourceProvider(info.Type, ""),
|
||||
Name: resourceProvider(info.Type, n.Provider),
|
||||
Output: &provider,
|
||||
},
|
||||
&EvalRefresh{
|
||||
|
@ -229,7 +233,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode {
|
|||
&EvalWriteState{
|
||||
Name: key.String(),
|
||||
ResourceType: info.Type,
|
||||
Provider: resourceProvider(info.Type, ""),
|
||||
Provider: resourceProvider(info.Type, n.Provider),
|
||||
State: &state,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -49,6 +49,9 @@ The command-line flags are all optional. The list of available flags are:
|
|||
the state path. Ignored when [remote state](/docs/state/remote/index.html) is
|
||||
used.
|
||||
|
||||
* `-provider=provider` - Provider used for import. Defaults to the default
|
||||
provider of the resource to import.
|
||||
|
||||
## Provider Configuration
|
||||
|
||||
Terraform will attempt to load configuration files that configure the
|
||||
|
|
Loading…
Reference in New Issue