Skip to content

Commit 60000ad

Browse files
authored
support solution update (#364)
1 parent 2b320f4 commit 60000ad

File tree

3 files changed

+148
-9
lines changed

3 files changed

+148
-9
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
package powerplatform_modifiers
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/hashicorp/terraform-plugin-framework/path"
11+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
14+
powerplatform_helpers "github.com/microsoft/terraform-provider-power-platform/internal/powerplatform/helpers"
15+
)
16+
17+
func SetBoolValueToUnknownIfChecksumsChangeModifier(firstAttributePair, secondAttributePair []string) planmodifier.Bool {
18+
return &setBoolValueToUnknownIfChecksumsChangeModifier{
19+
firstAttributePair: firstAttributePair,
20+
secondAttributePair: secondAttributePair,
21+
}
22+
}
23+
24+
type setBoolValueToUnknownIfChecksumsChangeModifier struct {
25+
firstAttributePair []string
26+
secondAttributePair []string
27+
}
28+
29+
func (d *setBoolValueToUnknownIfChecksumsChangeModifier) Description(ctx context.Context) string {
30+
return "Ensures that the attribute value is set to unknown if the checksums change."
31+
}
32+
33+
func (d *setBoolValueToUnknownIfChecksumsChangeModifier) MarkdownDescription(ctx context.Context) string {
34+
return d.Description(ctx)
35+
}
36+
37+
func (d *setBoolValueToUnknownIfChecksumsChangeModifier) PlanModifyBool(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse) {
38+
39+
firstAttributeHasChanged := d.hasChecksumChanged(ctx, req, resp, d.firstAttributePair[0], d.firstAttributePair[1])
40+
if resp.Diagnostics.HasError() {
41+
return
42+
}
43+
44+
secondAttributeHasChanged := d.hasChecksumChanged(ctx, req, resp, d.secondAttributePair[0], d.secondAttributePair[1])
45+
if resp.Diagnostics.HasError() {
46+
return
47+
}
48+
49+
if firstAttributeHasChanged || secondAttributeHasChanged {
50+
resp.PlanValue = types.BoolUnknown()
51+
}
52+
}
53+
54+
func (d *setBoolValueToUnknownIfChecksumsChangeModifier) hasChecksumChanged(ctx context.Context, req planmodifier.BoolRequest, resp *planmodifier.BoolResponse, attributeName, checksumAttributeName string) bool {
55+
var attribute types.String
56+
diags := req.Plan.GetAttribute(ctx, path.Root(attributeName), &attribute)
57+
resp.Diagnostics.Append(diags...)
58+
59+
var attributeChecksum types.String
60+
diags = req.State.GetAttribute(ctx, path.Root(checksumAttributeName), &attributeChecksum)
61+
resp.Diagnostics.Append(diags...)
62+
63+
value, err := powerplatform_helpers.CalculateMd5(attribute.ValueString())
64+
if err != nil {
65+
resp.Diagnostics.AddError(fmt.Sprintf("Error calculating MD5 checksum for %s", attribute), err.Error())
66+
}
67+
68+
return value != attributeChecksum.ValueString()
69+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT license.
3+
4+
package powerplatform_modifiers
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/hashicorp/terraform-plugin-framework/path"
11+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
12+
"github.com/hashicorp/terraform-plugin-framework/types"
13+
14+
powerplatform_helpers "github.com/microsoft/terraform-provider-power-platform/internal/powerplatform/helpers"
15+
)
16+
17+
func SetStringValueToUnknownIfChecksumsChangeModifier(firstAttributePair, secondAttributePair []string) planmodifier.String {
18+
return &setStringValueToUnknownIfChecksumsChangeModifier{
19+
firstAttributePair: firstAttributePair,
20+
secondAttributePair: secondAttributePair,
21+
}
22+
}
23+
24+
type setStringValueToUnknownIfChecksumsChangeModifier struct {
25+
firstAttributePair []string
26+
secondAttributePair []string
27+
}
28+
29+
func (d *setStringValueToUnknownIfChecksumsChangeModifier) Description(ctx context.Context) string {
30+
return "Ensures that the attribute value is set to unknown if the checksums change."
31+
}
32+
33+
func (d *setStringValueToUnknownIfChecksumsChangeModifier) MarkdownDescription(ctx context.Context) string {
34+
return d.Description(ctx)
35+
}
36+
37+
func (d *setStringValueToUnknownIfChecksumsChangeModifier) PlanModifyString(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse) {
38+
39+
firstAttributeHasChanged := d.hasChecksumChanged(ctx, req, resp, d.firstAttributePair[0], d.firstAttributePair[1])
40+
if resp.Diagnostics.HasError() {
41+
return
42+
}
43+
44+
secondAttributeHasChanged := d.hasChecksumChanged(ctx, req, resp, d.secondAttributePair[0], d.secondAttributePair[1])
45+
if resp.Diagnostics.HasError() {
46+
return
47+
}
48+
49+
if firstAttributeHasChanged || secondAttributeHasChanged {
50+
resp.PlanValue = types.StringUnknown()
51+
}
52+
}
53+
54+
func (d *setStringValueToUnknownIfChecksumsChangeModifier) hasChecksumChanged(ctx context.Context, req planmodifier.StringRequest, resp *planmodifier.StringResponse, attributeName, checksumAttributeName string) bool {
55+
var attribute types.String
56+
diags := req.Plan.GetAttribute(ctx, path.Root(attributeName), &attribute)
57+
resp.Diagnostics.Append(diags...)
58+
59+
var attributeChecksum types.String
60+
diags = req.State.GetAttribute(ctx, path.Root(checksumAttributeName), &attributeChecksum)
61+
resp.Diagnostics.Append(diags...)
62+
63+
value, err := powerplatform_helpers.CalculateMd5(attribute.ValueString())
64+
if err != nil {
65+
resp.Diagnostics.AddError(fmt.Sprintf("Error calculating MD5 checksum for %s", attribute), err.Error())
66+
}
67+
68+
return value != attributeChecksum.ValueString()
69+
}

internal/powerplatform/services/solution/resource_solution.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/hashicorp/terraform-plugin-framework/path"
1313
"github.com/hashicorp/terraform-plugin-framework/resource"
1414
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
15-
"github.com/hashicorp/terraform-plugin-framework/resource/schema/boolplanmodifier"
1615
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
1716
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
1817
"github.com/hashicorp/terraform-plugin-framework/types"
@@ -114,22 +113,24 @@ func (r *SolutionResource) Schema(ctx context.Context, req resource.SchemaReques
114113
MarkdownDescription: "Display name of the solution",
115114
Description: "Display name of the solution",
116115
Computed: true,
116+
PlanModifiers: []planmodifier.String{
117+
powerplatform_modifiers.SetStringValueToUnknownIfChecksumsChangeModifier([]string{"solution_file", "solution_file_checksum"}, []string{"settings_file", "settings_file_checksum"}),
118+
},
117119
},
118120
"is_managed": schema.BoolAttribute{
119121
MarkdownDescription: "Indicates whether the solution is managed or not",
120122
Description: "Indicates whether the solution is managed or not",
121123
Computed: true,
122124
PlanModifiers: []planmodifier.Bool{
123-
boolplanmodifier.UseStateForUnknown(),
125+
powerplatform_modifiers.SetBoolValueToUnknownIfChecksumsChangeModifier([]string{"solution_file", "solution_file_checksum"}, []string{"settings_file", "settings_file_checksum"}),
124126
},
125127
},
126-
127128
"solution_version": schema.StringAttribute{
128129
MarkdownDescription: "Version of the solution",
129130
Description: "Version of the solution",
130131
Computed: true,
131132
PlanModifiers: []planmodifier.String{
132-
stringplanmodifier.UseStateForUnknown(),
133+
powerplatform_modifiers.SetStringValueToUnknownIfChecksumsChangeModifier([]string{"solution_file", "solution_file_checksum"}, []string{"settings_file", "settings_file_checksum"}),
133134
},
134135
},
135136
},
@@ -178,7 +179,7 @@ func (r *SolutionResource) Create(ctx context.Context, req resource.CreateReques
178179
plan.DisplayName = types.StringValue(solution.DisplayName)
179180
plan.Id = types.StringValue(fmt.Sprintf("%s_%s", plan.EnvironmentId.ValueString(), solution.Name))
180181

181-
plan.SettingsFileChecksum = types.StringUnknown()
182+
plan.SettingsFileChecksum = types.StringNull()
182183
if !plan.SettingsFile.IsNull() && !plan.SettingsFile.IsUnknown() {
183184
value, err := powerplatform_helpers.CalculateMd5(plan.SettingsFile.ValueString())
184185
if err != nil {
@@ -187,8 +188,6 @@ func (r *SolutionResource) Create(ctx context.Context, req resource.CreateReques
187188
plan.SettingsFileChecksum = types.StringValue(value)
188189
tflog.Warn(ctx, fmt.Sprintf("CREATE Calculated md5 hash of settings file: %s", value))
189190
}
190-
} else {
191-
plan.SettingsFileChecksum = types.StringNull()
192191
}
193192

194193
plan.SolutionFileChecksum = types.StringUnknown()
@@ -233,7 +232,6 @@ func (r *SolutionResource) Read(ctx context.Context, req resource.ReadRequest, r
233232
if solution.Name == state.SolutionName.ValueString() {
234233
state.Id = types.StringValue(fmt.Sprintf("%s_%s", state.EnvironmentId.ValueString(), solution.Name))
235234
state.SolutionName = types.StringValue(solution.Name)
236-
//TODO test a case when solution version changes
237235
state.SolutionVersion = types.StringValue(solution.Version)
238236
state.IsManaged = types.BoolValue(solution.IsManaged)
239237
state.DisplayName = types.StringValue(solution.DisplayName)
@@ -316,6 +314,9 @@ func (r *SolutionResource) Update(ctx context.Context, req resource.UpdateReques
316314
}
317315

318316
solution := r.importSolution(ctx, plan, &resp.Diagnostics)
317+
if resp.Diagnostics.HasError() {
318+
return
319+
}
319320

320321
plan.Id = types.StringValue(fmt.Sprintf("%s_%s", plan.EnvironmentId.ValueString(), solution.Name))
321322

@@ -324,7 +325,7 @@ func (r *SolutionResource) Update(ctx context.Context, req resource.UpdateReques
324325
plan.IsManaged = types.BoolValue(solution.IsManaged)
325326
plan.DisplayName = types.StringValue(solution.DisplayName)
326327

327-
plan.SettingsFileChecksum = types.StringUnknown()
328+
plan.SettingsFileChecksum = types.StringNull()
328329
if !plan.SettingsFile.IsNull() && !plan.SettingsFile.IsUnknown() {
329330
value, err := powerplatform_helpers.CalculateMd5(plan.SettingsFile.ValueString())
330331
if err != nil {

0 commit comments

Comments
 (0)