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.stateOutPath, "state-out", "", "path")
|
||||||
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path")
|
||||||
cmdFlags.StringVar(&configPath, "config", pwd, "path")
|
cmdFlags.StringVar(&configPath, "config", pwd, "path")
|
||||||
|
cmdFlags.StringVar(&c.Meta.provider, "provider", "", "provider")
|
||||||
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
cmdFlags.Usage = func() { c.Ui.Error(c.Help()) }
|
||||||
if err := cmdFlags.Parse(args); err != nil {
|
if err := cmdFlags.Parse(args); err != nil {
|
||||||
return 1
|
return 1
|
||||||
|
@ -64,6 +65,7 @@ func (c *ImportCommand) Run(args []string) int {
|
||||||
&terraform.ImportTarget{
|
&terraform.ImportTarget{
|
||||||
Addr: args[0],
|
Addr: args[0],
|
||||||
ID: args[1],
|
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-out=path Path to write updated state file. By default, the
|
||||||
"-state" path will be used.
|
"-state" path will be used.
|
||||||
|
|
||||||
|
-provider=provider Provider used for import. Defaults to: ""
|
||||||
|
|
||||||
`
|
`
|
||||||
return strings.TrimSpace(helpText)
|
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 = `
|
const testImportStr = `
|
||||||
test_instance.foo:
|
test_instance.foo:
|
||||||
ID = yay
|
ID = yay
|
||||||
provider = test
|
provider = test
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const testImportCustomProviderStr = `
|
||||||
|
test_instance.foo:
|
||||||
|
ID = yay
|
||||||
|
provider = test.alias
|
||||||
|
`
|
||||||
|
|
|
@ -72,11 +72,14 @@ type Meta struct {
|
||||||
// allowed when walking the graph
|
// allowed when walking the graph
|
||||||
//
|
//
|
||||||
// shadow is used to enable/disable the shadow graph
|
// shadow is used to enable/disable the shadow graph
|
||||||
|
//
|
||||||
|
// provider is to specify specific resource providers
|
||||||
statePath string
|
statePath string
|
||||||
stateOutPath string
|
stateOutPath string
|
||||||
backupPath string
|
backupPath string
|
||||||
parallelism int
|
parallelism int
|
||||||
shadow bool
|
shadow bool
|
||||||
|
provider string
|
||||||
}
|
}
|
||||||
|
|
||||||
// initStatePaths is used to initialize the default values for
|
// 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 is the ID of the resource to import. This is resource-specific.
|
||||||
ID string
|
ID string
|
||||||
|
|
||||||
|
// Provider string
|
||||||
|
Provider string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import takes already-created external resources and brings them
|
// Import takes already-created external resources and brings them
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// TODO
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -32,7 +33,6 @@ func TestContextImport_basic(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("err: %s", err)
|
t.Fatalf("err: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
actual := strings.TrimSpace(state.String())
|
actual := strings.TrimSpace(state.String())
|
||||||
expected := strings.TrimSpace(testImportStr)
|
expected := strings.TrimSpace(testImportStr)
|
||||||
if actual != expected {
|
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 = `
|
const testImportStr = `
|
||||||
aws_instance.foo:
|
aws_instance.foo:
|
||||||
ID = foo
|
ID = foo
|
||||||
|
@ -700,3 +735,9 @@ aws_instance.foo:
|
||||||
provider = aws
|
provider = aws
|
||||||
foo = bar
|
foo = bar
|
||||||
`
|
`
|
||||||
|
|
||||||
|
const testImportCustomProviderStr = `
|
||||||
|
aws_instance.foo:
|
||||||
|
ID = foo
|
||||||
|
provider = aws.alias
|
||||||
|
`
|
||||||
|
|
|
@ -23,6 +23,7 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
||||||
nodes = append(nodes, &graphNodeImportState{
|
nodes = append(nodes, &graphNodeImportState{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
ID: target.ID,
|
ID: target.ID,
|
||||||
|
Provider: target.Provider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ func (t *ImportStateTransformer) Transform(g *Graph) error {
|
||||||
type graphNodeImportState struct {
|
type graphNodeImportState struct {
|
||||||
Addr *ResourceAddress // Addr is the resource address to import to
|
Addr *ResourceAddress // Addr is the resource address to import to
|
||||||
ID string // ID is the ID to import as
|
ID string // ID is the ID to import as
|
||||||
|
Provider string // Provider string
|
||||||
|
|
||||||
states []*InstanceState
|
states []*InstanceState
|
||||||
}
|
}
|
||||||
|
@ -46,7 +48,7 @@ func (n *graphNodeImportState) Name() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeImportState) ProvidedBy() []string {
|
func (n *graphNodeImportState) ProvidedBy() []string {
|
||||||
return []string{resourceProvider(n.Addr.Type, "")}
|
return []string{resourceProvider(n.Addr.Type, n.Provider)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphNodeSubPath
|
// GraphNodeSubPath
|
||||||
|
@ -150,6 +152,7 @@ func (n *graphNodeImportState) DynamicExpand(ctx EvalContext) (*Graph, error) {
|
||||||
Target: addrs[i],
|
Target: addrs[i],
|
||||||
Path_: n.Path(),
|
Path_: n.Path(),
|
||||||
State: state,
|
State: state,
|
||||||
|
Provider: n.Provider,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +173,7 @@ type graphNodeImportStateSub struct {
|
||||||
Target *ResourceAddress
|
Target *ResourceAddress
|
||||||
State *InstanceState
|
State *InstanceState
|
||||||
Path_ []string
|
Path_ []string
|
||||||
|
Provider string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *graphNodeImportStateSub) Name() string {
|
func (n *graphNodeImportStateSub) Name() string {
|
||||||
|
@ -212,7 +216,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode {
|
||||||
return &EvalSequence{
|
return &EvalSequence{
|
||||||
Nodes: []EvalNode{
|
Nodes: []EvalNode{
|
||||||
&EvalGetProvider{
|
&EvalGetProvider{
|
||||||
Name: resourceProvider(info.Type, ""),
|
Name: resourceProvider(info.Type, n.Provider),
|
||||||
Output: &provider,
|
Output: &provider,
|
||||||
},
|
},
|
||||||
&EvalRefresh{
|
&EvalRefresh{
|
||||||
|
@ -229,7 +233,7 @@ func (n *graphNodeImportStateSub) EvalTree() EvalNode {
|
||||||
&EvalWriteState{
|
&EvalWriteState{
|
||||||
Name: key.String(),
|
Name: key.String(),
|
||||||
ResourceType: info.Type,
|
ResourceType: info.Type,
|
||||||
Provider: resourceProvider(info.Type, ""),
|
Provider: resourceProvider(info.Type, n.Provider),
|
||||||
State: &state,
|
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
|
the state path. Ignored when [remote state](/docs/state/remote/index.html) is
|
||||||
used.
|
used.
|
||||||
|
|
||||||
|
* `-provider=provider` - Provider used for import. Defaults to the default
|
||||||
|
provider of the resource to import.
|
||||||
|
|
||||||
## Provider Configuration
|
## Provider Configuration
|
||||||
|
|
||||||
Terraform will attempt to load configuration files that configure the
|
Terraform will attempt to load configuration files that configure the
|
||||||
|
|
Loading…
Reference in New Issue