return error for invalid resource import
Most legacy provider resources do not implement any import functionality other than returning an empty object with the given ID, relying on core to later read that resource and obtain the complete state. Because of this, we need to check the response from ReadResource for a null value, and use that as an indication the import id was invalid.
This commit is contained in:
parent
332045a4e4
commit
99d0266585
|
@ -282,6 +282,25 @@ func (n *graphNodeImportStateSub) Execute(ctx EvalContext, op walkOperation) (di
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify the existance of the imported resource
|
||||||
|
if state.Value.IsNull() {
|
||||||
|
var diags tfdiags.Diagnostics
|
||||||
|
diags = diags.Append(tfdiags.Sourceless(
|
||||||
|
tfdiags.Error,
|
||||||
|
"Cannot import non-existent remote object",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"While attempting to import an existing object to %q, "+
|
||||||
|
"the provider detected that no object exists with the given id. "+
|
||||||
|
"Only pre-existing objects can be imported; check that the id "+
|
||||||
|
"is correct and that it is associated with the provider's "+
|
||||||
|
"configured region or endpoint, or use \"terraform apply\" to "+
|
||||||
|
"create a new remote object for this resource.",
|
||||||
|
n.TargetAddr,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
return diags
|
||||||
|
}
|
||||||
|
|
||||||
diags = diags.Append(riNode.writeResourceInstanceState(ctx, state, workingState))
|
diags = diags.Append(riNode.writeResourceInstanceState(ctx, state, workingState))
|
||||||
return diags
|
return diags
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package terraform
|
package terraform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
@ -112,3 +113,55 @@ func TestGraphNodeImportStateSubExecute(t *testing.T) {
|
||||||
t.Fatalf("bad state after import: \n%s", actual)
|
t.Fatalf("bad state after import: \n%s", actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGraphNodeImportStateSubExecuteNull(t *testing.T) {
|
||||||
|
state := states.NewState()
|
||||||
|
provider := testProvider("aws")
|
||||||
|
provider.ReadResourceFn = func(req providers.ReadResourceRequest) (resp providers.ReadResourceResponse) {
|
||||||
|
// return null indicating that the requested resource does not exist
|
||||||
|
resp.NewState = cty.NullVal(cty.Object(map[string]cty.Type{
|
||||||
|
"id": cty.String,
|
||||||
|
}))
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := &MockEvalContext{
|
||||||
|
StateState: state.SyncWrapper(),
|
||||||
|
ProviderProvider: provider,
|
||||||
|
ProviderSchemaSchema: &ProviderSchema{
|
||||||
|
ResourceTypes: map[string]*configschema.Block{
|
||||||
|
"aws_instance": {
|
||||||
|
Attributes: map[string]*configschema.Attribute{
|
||||||
|
"id": {
|
||||||
|
Type: cty.String,
|
||||||
|
Computed: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
importedResource := providers.ImportedResource{
|
||||||
|
TypeName: "aws_instance",
|
||||||
|
State: cty.ObjectVal(map[string]cty.Value{"id": cty.StringVal("bar")}),
|
||||||
|
}
|
||||||
|
|
||||||
|
node := graphNodeImportStateSub{
|
||||||
|
TargetAddr: addrs.Resource{
|
||||||
|
Mode: addrs.ManagedResourceMode,
|
||||||
|
Type: "aws_instance",
|
||||||
|
Name: "foo",
|
||||||
|
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
|
||||||
|
State: importedResource,
|
||||||
|
ResolvedProvider: addrs.AbsProviderConfig{
|
||||||
|
Provider: addrs.NewDefaultProvider("aws"),
|
||||||
|
Module: addrs.RootModule,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
diags := node.Execute(ctx, walkImport)
|
||||||
|
if !diags.HasErrors() {
|
||||||
|
t.Fatal("expected error for non-existent resource")
|
||||||
|
}
|
||||||
|
fmt.Println(diags.ErrWithWarnings())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue