a plan with no diff should return proposed state
PlanResourceChange isn't returning the diff, but rather it is returning the destired state. If the propsed state results in a nil diff, then, the propsed state is what should be returned. Make sure Meta fields are not nil, as the schema package expects those to be initialised.
This commit is contained in:
parent
795161f615
commit
0b8c38207a
|
@ -146,7 +146,7 @@ func (s *GRPCProviderServer) UpgradeResourceState(_ context.Context, req *proto.
|
|||
var err error
|
||||
|
||||
// if there's a JSON state, we need to decode it.
|
||||
if req.RawState.Json != nil {
|
||||
if len(req.RawState.Json) > 0 {
|
||||
err = json.Unmarshal(req.RawState.Json, &jsonMap)
|
||||
if err != nil {
|
||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||
|
@ -390,6 +390,14 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl
|
|||
}
|
||||
|
||||
priorState := schema.InstanceStateFromStateValue(priorStateVal, res.SchemaVersion)
|
||||
priorPrivate := make(map[string]interface{})
|
||||
if len(req.PriorPrivate) > 0 {
|
||||
if err := json.Unmarshal(req.PriorPrivate, &priorPrivate); err != nil {
|
||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
priorState.Meta = priorPrivate
|
||||
|
||||
// turn the propsed state into a legacy configuration
|
||||
config := terraform.NewResourceConfigShimmed(proposedNewStateVal, block)
|
||||
|
@ -403,9 +411,9 @@ func (s *GRPCProviderServer) PlanResourceChange(_ context.Context, req *proto.Pl
|
|||
if diff == nil {
|
||||
// schema.Provider.Diff returns nil if it ends up making a diff with
|
||||
// no changes, but our new interface wants us to return an actual
|
||||
// change description that _shows_ there are no changes, so we need
|
||||
// to synthesize one here.
|
||||
resp.PlannedState = req.PriorState
|
||||
// change description that _shows_ there are no changes, so we return
|
||||
// the proposed change that produces no diff.
|
||||
resp.PlannedState = req.ProposedNewState
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
|
@ -480,10 +488,12 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
|
|||
|
||||
priorState := schema.InstanceStateFromStateValue(priorStateVal, res.SchemaVersion)
|
||||
|
||||
var private map[string]interface{}
|
||||
if err := json.Unmarshal(req.PlannedPrivate, &private); err != nil {
|
||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||
return resp, nil
|
||||
private := make(map[string]interface{})
|
||||
if len(req.PlannedPrivate) > 0 {
|
||||
if err := json.Unmarshal(req.PlannedPrivate, &private); err != nil {
|
||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||
return resp, nil
|
||||
}
|
||||
}
|
||||
|
||||
diff, err := schema.DiffFromValues(priorStateVal, plannedStateVal, res)
|
||||
|
@ -492,6 +502,7 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
|
|||
return resp, nil
|
||||
}
|
||||
|
||||
diff.Meta = private
|
||||
newInstanceState, err := s.provider.Apply(info, priorState, diff)
|
||||
if err != nil {
|
||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package plugin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
|
@ -293,3 +294,66 @@ func TestUpgradeState_flatmapState(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanResourceChange(t *testing.T) {
|
||||
r := &schema.Resource{
|
||||
SchemaVersion: 4,
|
||||
Schema: map[string]*schema.Schema{
|
||||
"foo": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
server := &GRPCProviderServer{
|
||||
provider: &schema.Provider{
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"test": r,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
schema := r.CoreConfigSchema()
|
||||
priorState, err := msgpack.Marshal(cty.NullVal(schema.ImpliedType()), schema.ImpliedType())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// A propsed state with only the ID unknown will produce a nil diff, and
|
||||
// should return the propsed state value.
|
||||
proposedVal, err := schema.CoerceValue(cty.ObjectVal(map[string]cty.Value{
|
||||
"id": cty.UnknownVal(cty.String),
|
||||
}))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
proposedState, err := msgpack.Marshal(proposedVal, schema.ImpliedType())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
testReq := &proto.PlanResourceChange_Request{
|
||||
TypeName: "test",
|
||||
PriorState: &proto.DynamicValue{
|
||||
Msgpack: priorState,
|
||||
},
|
||||
ProposedNewState: &proto.DynamicValue{
|
||||
Msgpack: proposedState,
|
||||
},
|
||||
}
|
||||
|
||||
resp, err := server.PlanResourceChange(context.Background(), testReq)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
plannedStateVal, err := msgpack.Unmarshal(resp.PlannedState.Msgpack, schema.ImpliedType())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if !cmp.Equal(proposedVal, plannedStateVal, valueComparer) {
|
||||
t.Fatal(cmp.Diff(proposedVal, plannedStateVal, valueComparer))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue