Skip to content

Commit 462aa62

Browse files
authored
Merge pull request #1190 from hashicorp/TF-11775-terraform-provider-tfe-gh-issue-1189-provider-error-when-re-creating-tfe-registry-gpg-key-and-using-provider-default-organization
Fix plan modification error when updating tfe_registry_gpg_key
2 parents bbae4b8 + e0e60dd commit 462aa62

File tree

4 files changed

+125
-8
lines changed

4 files changed

+125
-8
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# UNRELEASED
22

33
BUG FIXES:
4-
* Fixed default provider organization usage for `r/tfe_admin_organization_settings`, by @brandonc [1183](https://github.com/hashicorp/terraform-provider-tfe/pull/1183)
4+
* `r/tfe_admin_organization_settings`: Fixed default provider organization usage, by @brandonc [1183](https://github.com/hashicorp/terraform-provider-tfe/pull/1183)
5+
* `r/tfe_registry_gpg_key`: Fixed update plans when using default organization, by @brandonc [1190](https://github.com/hashicorp/terraform-provider-tfe/pull/1190)
56
* `/r/tfe_workspace_settings`: Fix compatibility with older versions of Terraform Enterprise when using agent execution by @brandonc [1193](https://github.com/hashicorp/terraform-provider-tfe/pull/1193)
67

78
# v0.51.0

internal/provider/provider_custom_diffs.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88

99
"github.com/hashicorp/terraform-plugin-framework/path"
1010
"github.com/hashicorp/terraform-plugin-framework/resource"
11+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
1112
"github.com/hashicorp/terraform-plugin-framework/types"
1213
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1314
)
@@ -28,18 +29,18 @@ func customizeDiffIfProviderDefaultOrganizationChanged(c context.Context, diff *
2829
return nil
2930
}
3031

31-
func modifyPlanForDefaultOrganizationChange(ctx context.Context, providerDefaultOrg string, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
32-
if req.State.Raw.IsNull() {
32+
func modifyPlanForDefaultOrganizationChange(ctx context.Context, providerDefaultOrg string, state tfsdk.State, configAttributes, planAttributes AttrGettable, resp *resource.ModifyPlanResponse) {
33+
if state.Raw.IsNull() {
3334
return
3435
}
3536

3637
orgPath := path.Root("organization")
3738

38-
var configOrg, plannedOrg *string
39-
resp.Diagnostics.Append(req.Config.GetAttribute(ctx, orgPath, &configOrg)...)
40-
resp.Diagnostics.Append(req.Plan.GetAttribute(ctx, orgPath, &plannedOrg)...)
39+
var configOrg, plannedOrg types.String
40+
resp.Diagnostics.Append(configAttributes.GetAttribute(ctx, orgPath, &configOrg)...)
41+
resp.Diagnostics.Append(planAttributes.GetAttribute(ctx, orgPath, &plannedOrg)...)
4142

42-
if configOrg == nil && plannedOrg != nil && providerDefaultOrg != *plannedOrg {
43+
if configOrg.IsNull() && !plannedOrg.IsNull() && providerDefaultOrg != plannedOrg.ValueString() {
4344
// There is no organization configured on the resource, yet the provider org is different from
4445
// the planned organization value. We must conclude that the provider default organization changed.
4546
resp.Plan.SetAttribute(ctx, orgPath, types.StringValue(providerDefaultOrg))
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
8+
"github.com/hashicorp/terraform-plugin-framework/diag"
9+
"github.com/hashicorp/terraform-plugin-framework/path"
10+
"github.com/hashicorp/terraform-plugin-framework/resource"
11+
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
14+
"github.com/hashicorp/terraform-plugin-go/tftypes"
15+
)
16+
17+
type getter struct {
18+
val types.String
19+
}
20+
21+
func (g *getter) GetAttribute(_ context.Context, _ path.Path, target interface{}) diag.Diagnostics {
22+
*(target.(*basetypes.StringValue)) = g.val
23+
return diag.Diagnostics{}
24+
}
25+
26+
func TestModifyPlanForDefaultOrganizationChange(t *testing.T) {
27+
// if configOrg.IsNull() && !plannedOrg.IsNull() && providerDefaultOrg != plannedOrg.ValueString() {
28+
testCases := map[string]struct {
29+
providerDefaultOrg string
30+
planValue types.String
31+
configValue types.String
32+
expectedPlanValue string
33+
expectedRequiresReplace bool
34+
}{
35+
"No change in provider org": {
36+
providerDefaultOrg: "foo",
37+
planValue: types.StringValue("foo"),
38+
configValue: types.StringNull(),
39+
expectedPlanValue: "foo",
40+
expectedRequiresReplace: false,
41+
},
42+
"Change in provider org": {
43+
providerDefaultOrg: "bar",
44+
planValue: types.StringValue("foo"),
45+
configValue: types.StringNull(),
46+
expectedPlanValue: "bar",
47+
expectedRequiresReplace: true,
48+
},
49+
"Config org changed": {
50+
providerDefaultOrg: "foo",
51+
planValue: types.StringValue("bar"),
52+
configValue: types.StringValue("bar"),
53+
expectedPlanValue: "bar",
54+
},
55+
}
56+
57+
for name, tc := range testCases {
58+
t.Run(name, func(t *testing.T) {
59+
fakeState := tftypes.NewValue(tftypes.Object{}, make(map[string]tftypes.Value))
60+
61+
fakeSchema := schema.Schema{
62+
Attributes: map[string]schema.Attribute{
63+
"organization": schema.StringAttribute{
64+
Computed: true,
65+
Optional: true,
66+
Description: "Test organization",
67+
},
68+
},
69+
}
70+
71+
fakePlan := tftypes.NewValue(
72+
tftypes.Object{
73+
AttributeTypes: map[string]tftypes.Type{
74+
"organization": tftypes.String,
75+
},
76+
},
77+
map[string]tftypes.Value{
78+
"organization": tftypes.NewValue(tftypes.String, tc.planValue.ValueString()),
79+
},
80+
)
81+
82+
fakeResponse := &resource.ModifyPlanResponse{
83+
Plan: tfsdk.Plan{Schema: fakeSchema, Raw: fakePlan},
84+
RequiresReplace: make(path.Paths, 0),
85+
Diagnostics: diag.Diagnostics{},
86+
}
87+
88+
c := context.TODO()
89+
90+
modifyPlanForDefaultOrganizationChange(
91+
c,
92+
tc.providerDefaultOrg,
93+
tfsdk.State{Raw: fakeState},
94+
&getter{val: tc.configValue},
95+
&getter{val: tc.planValue},
96+
fakeResponse,
97+
)
98+
99+
orgPath := path.Root("organization")
100+
var value types.String
101+
fakeResponse.Plan.GetAttribute(c, orgPath, &value)
102+
if fakeResponse.Diagnostics.HasError() {
103+
t.Fatalf("Expected no errors, got %v", fakeResponse.Diagnostics)
104+
}
105+
106+
if value.ValueString() != tc.expectedPlanValue {
107+
t.Fatalf("Expected plan value to be %q, got %q", tc.expectedPlanValue, value.ValueString())
108+
}
109+
110+
if tc.expectedRequiresReplace && len(fakeResponse.RequiresReplace) == 0 {
111+
t.Fatal("Expected RequiresReplace to be set, but it was not")
112+
}
113+
})
114+
}
115+
}

internal/provider/resource_tfe_registry_gpg_key.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func (r *resourceTFERegistryGPGKey) Metadata(ctx context.Context, req resource.M
3939
}
4040

4141
func (r *resourceTFERegistryGPGKey) ModifyPlan(ctx context.Context, req resource.ModifyPlanRequest, resp *resource.ModifyPlanResponse) {
42-
modifyPlanForDefaultOrganizationChange(ctx, r.config.Organization, req, resp)
42+
modifyPlanForDefaultOrganizationChange(ctx, r.config.Organization, req.State, req.Config, req.Plan, resp)
4343
}
4444

4545
func (r *resourceTFERegistryGPGKey) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {

0 commit comments

Comments
 (0)