Skip to content

Commit

Permalink
Implementing private state management for ModifyAttribute and ModifyR…
Browse files Browse the repository at this point in the history
…esource (#399)

Reference: #399
  • Loading branch information
bendbennett committed Aug 9, 2022
1 parent 1e187b8 commit 91cf4cb
Show file tree
Hide file tree
Showing 18 changed files with 1,238 additions and 47 deletions.
11 changes: 9 additions & 2 deletions internal/fromproto5/planresourcechange.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package fromproto5
import (
"context"

"github.com/hashicorp/terraform-plugin-go/tfprotov5"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/internal/privatestate"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
)

// PlanResourceChangeRequest returns the *fwserver.PlanResourceChangeRequest
Expand All @@ -34,7 +36,6 @@ func PlanResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.PlanResour
}

fw := &fwserver.PlanResourceChangeRequest{
PriorPrivate: proto5.PriorPrivate,
ResourceSchema: resourceSchema,
ResourceType: resourceType,
}
Expand Down Expand Up @@ -63,5 +64,11 @@ func PlanResourceChangeRequest(ctx context.Context, proto5 *tfprotov5.PlanResour

fw.ProviderMeta = providerMeta

privateData, privateDataDiags := privatestate.NewData(ctx, proto5.PriorPrivate)

diags.Append(privateDataDiags...)

fw.PriorPrivate = privateData

return fw, diags
}
29 changes: 24 additions & 5 deletions internal/fromproto5/planresourcechange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-go/tftypes"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto5"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/internal/privatestate"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov5"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

func TestPlanResourceChangeRequest(t *testing.T) {
Expand Down Expand Up @@ -44,6 +46,15 @@ func TestPlanResourceChangeRequest(t *testing.T) {
},
}

testProviderKeyValue := marshalToJson(map[string][]byte{
"providerKeyOne": []byte(`{"pKeyOne": {"k0": "zero", "k1": 1}}`),
})

testProviderData, diags := privatestate.NewProviderData(context.Background(), testProviderKeyValue)
if diags.HasError() {
panic("error creating new provider data")
}

testCases := map[string]struct {
input *tfprotov5.PlanResourceChangeRequest
resourceSchema fwschema.Schema
Expand Down Expand Up @@ -99,11 +110,19 @@ func TestPlanResourceChangeRequest(t *testing.T) {
},
"priorprivate": {
input: &tfprotov5.PlanResourceChangeRequest{
PriorPrivate: []byte("{}"),
PriorPrivate: marshalToJson(map[string][]byte{
".frameworkKey": []byte(`{"fKeyOne": {"k0": "zero", "k1": 1}}`),
"providerKeyOne": []byte(`{"pKeyOne": {"k0": "zero", "k1": 1}}`),
}),
},
resourceSchema: testFwSchema,
expected: &fwserver.PlanResourceChangeRequest{
PriorPrivate: []byte("{}"),
PriorPrivate: &privatestate.Data{
Framework: map[string][]byte{
".frameworkKey": []byte(`{"fKeyOne": {"k0": "zero", "k1": 1}}`),
},
Provider: testProviderData,
},
ResourceSchema: testFwSchema,
},
},
Expand Down Expand Up @@ -209,7 +228,7 @@ func TestPlanResourceChangeRequest(t *testing.T) {

got, diags := fromproto5.PlanResourceChangeRequest(context.Background(), testCase.input, testCase.resourceType, testCase.resourceSchema, testCase.providerMetaSchema)

if diff := cmp.Diff(got, testCase.expected); diff != "" {
if diff := cmp.Diff(got, testCase.expected, cmp.AllowUnexported(privatestate.ProviderData{})); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}

Expand Down
11 changes: 9 additions & 2 deletions internal/fromproto6/planresourcechange.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package fromproto6
import (
"context"

"github.com/hashicorp/terraform-plugin-go/tfprotov6"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/internal/privatestate"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
)

// PlanResourceChangeRequest returns the *fwserver.PlanResourceChangeRequest
Expand All @@ -34,7 +36,6 @@ func PlanResourceChangeRequest(ctx context.Context, proto6 *tfprotov6.PlanResour
}

fw := &fwserver.PlanResourceChangeRequest{
PriorPrivate: proto6.PriorPrivate,
ResourceSchema: resourceSchema,
ResourceType: resourceType,
}
Expand Down Expand Up @@ -63,5 +64,11 @@ func PlanResourceChangeRequest(ctx context.Context, proto6 *tfprotov6.PlanResour

fw.ProviderMeta = providerMeta

privateData, privateDataDiags := privatestate.NewData(ctx, proto6.PriorPrivate)

diags.Append(privateDataDiags...)

fw.PriorPrivate = privateData

return fw, diags
}
29 changes: 24 additions & 5 deletions internal/fromproto6/planresourcechange_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tftypes"

"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/internal/fromproto6"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwserver"
"github.com/hashicorp/terraform-plugin-framework/internal/privatestate"
"github.com/hashicorp/terraform-plugin-framework/provider"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-go/tfprotov6"
"github.com/hashicorp/terraform-plugin-go/tftypes"
)

func TestPlanResourceChangeRequest(t *testing.T) {
Expand Down Expand Up @@ -44,6 +46,15 @@ func TestPlanResourceChangeRequest(t *testing.T) {
},
}

testProviderKeyValue := marshalToJson(map[string][]byte{
"providerKeyOne": []byte(`{"pKeyOne": {"k0": "zero", "k1": 1}}`),
})

testProviderData, diags := privatestate.NewProviderData(context.Background(), testProviderKeyValue)
if diags.HasError() {
panic("error creating new provider data")
}

testCases := map[string]struct {
input *tfprotov6.PlanResourceChangeRequest
resourceSchema fwschema.Schema
Expand Down Expand Up @@ -99,11 +110,19 @@ func TestPlanResourceChangeRequest(t *testing.T) {
},
"priorprivate": {
input: &tfprotov6.PlanResourceChangeRequest{
PriorPrivate: []byte("{}"),
PriorPrivate: marshalToJson(map[string][]byte{
".frameworkKey": []byte(`{"fKeyOne": {"k0": "zero", "k1": 1}}`),
"providerKeyOne": []byte(`{"pKeyOne": {"k0": "zero", "k1": 1}}`),
}),
},
resourceSchema: testFwSchema,
expected: &fwserver.PlanResourceChangeRequest{
PriorPrivate: []byte("{}"),
PriorPrivate: &privatestate.Data{
Framework: map[string][]byte{
".frameworkKey": []byte(`{"fKeyOne": {"k0": "zero", "k1": 1}}`),
},
Provider: testProviderData,
},
ResourceSchema: testFwSchema,
},
},
Expand Down Expand Up @@ -209,7 +228,7 @@ func TestPlanResourceChangeRequest(t *testing.T) {

got, diags := fromproto6.PlanResourceChangeRequest(context.Background(), testCase.input, testCase.resourceType, testCase.resourceSchema, testCase.providerMetaSchema)

if diff := cmp.Diff(got, testCase.expected); diff != "" {
if diff := cmp.Diff(got, testCase.expected, cmp.AllowUnexported(privatestate.ProviderData{})); diff != "" {
t.Errorf("unexpected difference: %s", diff)
}

Expand Down
19 changes: 19 additions & 0 deletions internal/fwserver/attribute_plan_modification.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema"
"github.com/hashicorp/terraform-plugin-framework/internal/fwschema/fwxschema"
"github.com/hashicorp/terraform-plugin-framework/internal/logging"
"github.com/hashicorp/terraform-plugin-framework/internal/privatestate"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
)
Expand Down Expand Up @@ -49,11 +50,24 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo

var requiresReplace bool

privateProviderData, diags := privatestate.NewProviderData(ctx, nil)

resp.Diagnostics.Append(diags...)

if diags.HasError() {
return
}

if req.Private != nil {
privateProviderData = req.Private
}

if attributeWithPlanModifiers, ok := a.(fwxschema.AttributeWithPlanModifiers); ok {
for _, planModifier := range attributeWithPlanModifiers.GetPlanModifiers() {
modifyResp := &tfsdk.ModifyAttributePlanResponse{
AttributePlan: req.AttributePlan,
RequiresReplace: requiresReplace,
Private: privateProviderData,
}

logging.FrameworkDebug(
Expand All @@ -75,6 +89,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
req.AttributePlan = modifyResp.AttributePlan
resp.Diagnostics.Append(modifyResp.Diagnostics...)
requiresReplace = modifyResp.RequiresReplace
resp.Private = modifyResp.Private

// Only on new errors.
if modifyResp.Diagnostics.HasError() {
Expand Down Expand Up @@ -122,6 +137,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
Plan: resp.Plan,
ProviderMeta: req.ProviderMeta,
State: req.State,
Private: privateProviderData,
}

AttributeModifyPlan(ctx, attr, attrReq, resp)
Expand Down Expand Up @@ -149,6 +165,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
Plan: resp.Plan,
ProviderMeta: req.ProviderMeta,
State: req.State,
Private: privateProviderData,
}

AttributeModifyPlan(ctx, attr, attrReq, resp)
Expand Down Expand Up @@ -176,6 +193,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
Plan: resp.Plan,
ProviderMeta: req.ProviderMeta,
State: req.State,
Private: privateProviderData,
}

AttributeModifyPlan(ctx, attr, attrReq, resp)
Expand Down Expand Up @@ -206,6 +224,7 @@ func AttributeModifyPlan(ctx context.Context, a fwschema.Attribute, req tfsdk.Mo
Plan: resp.Plan,
ProviderMeta: req.ProviderMeta,
State: req.State,
Private: privateProviderData,
}

AttributeModifyPlan(ctx, attr, attrReq, resp)
Expand Down
Loading

0 comments on commit 91cf4cb

Please sign in to comment.