Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/states/instance_object_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func (os *ResourceInstanceObjectSrc) Decode(schema providers.Schema) (*ResourceI
var identity cty.Value
if os.decodeIdentityCache != cty.NilVal {
identity = os.decodeIdentityCache
} else if os.IdentityJSON != nil {
} else if os.IdentityJSON != nil && schema.Identity != nil {
identity, err = ctyjson.Unmarshal(os.IdentityJSON, schema.Identity.ImpliedType())
if err != nil {
return nil, fmt.Errorf("failed to decode identity: %s. This is most likely a bug in the Provider, providers must not change the identity schema without updating the identity schema version", err.Error())
Expand Down
15 changes: 6 additions & 9 deletions internal/states/instance_object_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,22 @@ func TestResourceInstanceObject_encode(t *testing.T) {

// multiple instances may have been assigned the same deps slice
objs := []*ResourceInstanceObject{
&ResourceInstanceObject{
{
Value: value,
Status: ObjectPlanned,
Dependencies: depsOne,
},
&ResourceInstanceObject{
{
Value: value,
Status: ObjectPlanned,
Dependencies: depsTwo,
},
&ResourceInstanceObject{
{
Value: value,
Status: ObjectPlanned,
Dependencies: depsOne,
},
&ResourceInstanceObject{
{
Value: value,
Status: ObjectPlanned,
Dependencies: depsOne,
Expand All @@ -91,18 +91,15 @@ func TestResourceInstanceObject_encode(t *testing.T) {
var mu sync.Mutex

for _, obj := range objs {
obj := obj
wg.Add(1)
go func() {
defer wg.Done()
wg.Go(func() {
rios, err := obj.Encode(schema)
if err != nil {
t.Errorf("unexpected error: %s", err)
}
mu.Lock()
encoded = append(encoded, rios)
mu.Unlock()
}()
})
}
wg.Wait()

Expand Down
70 changes: 70 additions & 0 deletions internal/terraform/context_plan_identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,76 @@ func TestContext2Plan_resource_identity_refresh(t *testing.T) {
}
}

func TestContext2Plan_resource_identity_refresh_downgrade(t *testing.T) {
p := testProvider("aws")
m := testModule(t, "refresh-basic")
p.GetProviderSchemaResponse = getProviderSchemaResponseFromProviderSchema(&providerSchema{
ResourceTypes: map[string]*configschema.Block{
"aws_instance": {
Attributes: map[string]*configschema.Attribute{
"id": {
Type: cty.String,
Computed: true,
},
"foo": {
Type: cty.String,
Optional: true,
Computed: true,
},
},
},
},
})

state := states.NewState()
root := state.EnsureModule(addrs.RootModuleInstance)

root.SetResourceInstanceCurrent(
mustResourceInstanceAddr("aws_instance.web").Resource,
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
AttrsJSON: []byte(`{"id":"foo","foo":"bar"}`),
IdentitySchemaVersion: 0,
IdentityJSON: []byte(`{"id": "foo"}`),
},
mustProviderConfig(`provider["registry.terraform.io/hashicorp/aws"]`),
)

ctx := testContext2(t, &ContextOpts{
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p),
},
})

schema := p.GetProviderSchemaResponse.ResourceTypes["aws_instance"]

p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
return providers.ReadResourceResponse{
NewState: req.PriorState,
}
}

s, diags := ctx.Plan(m, state, &PlanOpts{Mode: plans.RefreshOnlyMode})

if diags.HasErrors() {
t.Fatal(diags.Err())
}

if !p.ReadResourceCalled {
t.Fatal("ReadResource should be called")
}

mod := s.PriorState.RootModule()
fromState, err := mod.Resources["aws_instance.web"].Instances[addrs.NoKey].Current.Decode(schema)
if err != nil {
t.Fatal(err)
}

if !fromState.Identity.IsNull() {
t.Fatalf("wrong identity\nwant: null\ngot: %s", fromState.Identity.GoString())
}
}

// This test validates if a resource identity that is deposed and will be destroyed
// can be refreshed with an identity during the plan.
func TestContext2Plan_resource_identity_refresh_destroy_deposed(t *testing.T) {
Expand Down
Loading