Skip to content

Commit b97830e

Browse files
authored
Merge branch 'main' into dependabot/go_modules/github.com/hashicorp/terraform-plugin-docs-0.23.0
2 parents c0bf63d + 5edd692 commit b97830e

9 files changed

+376
-9
lines changed

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/hashicorp/terraform-plugin-go v0.26.0
1212
github.com/hashicorp/terraform-plugin-testing v1.12.0
1313
github.com/segmentio/public-api-sdk-go v0.0.0-20250113195817-34106b6e08dd
14+
github.com/stretchr/testify v1.10.0
1415
gotest.tools/gotestsum v1.13.0
1516
)
1617

@@ -19,8 +20,10 @@ require (
1920
github.com/Kunde21/markdownfmt/v3 v3.1.0 // indirect
2021
github.com/bitfield/gotestdox v0.2.2 // indirect
2122
github.com/bmatcuk/doublestar/v4 v4.9.1 // indirect
23+
github.com/davecgh/go-spew v1.1.1 // indirect
2224
github.com/hashicorp/cli v1.1.7 // indirect
2325
github.com/mattn/go-runewidth v0.0.9 // indirect
26+
github.com/pmezard/go-difflib v1.0.0 // indirect
2427
github.com/yuin/goldmark v1.7.7 // indirect
2528
github.com/yuin/goldmark-meta v1.1.0 // indirect
2629
go.abhg.dev/goldmark/frontmatter v0.2.0 // indirect

internal/provider/destination_resource.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,9 +615,18 @@ func (r *destinationResource) Read(ctx context.Context, req resource.ReadRequest
615615
return
616616
}
617617

618-
// This is to satisfy terraform requirements that the returned fields must match the input ones because new settings can be generated in the response
618+
// Merge settings: keep config-defined settings while ignoring backend-generated ones not in config
619619
if !previousState.Settings.IsNull() && !previousState.Settings.IsUnknown() {
620-
state.Settings = previousState.Settings
620+
mergedSettings, err := mergeSettings(previousState.Settings, state.Settings, false)
621+
if err != nil {
622+
resp.Diagnostics.AddError(
623+
"Unable to merge Destination settings",
624+
err.Error(),
625+
)
626+
627+
return
628+
}
629+
state.Settings = mergedSettings
621630
}
622631

623632
diags = resp.State.Set(ctx, &state)

internal/provider/destination_subscription_resource.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,18 @@ func (r *destinationSubscriptionResource) Read(ctx context.Context, req resource
255255
return
256256
}
257257

258+
// Merge settings: keep config-defined settings while ignoring backend-generated ones not in config
258259
if !previousState.Settings.IsNull() && !previousState.Settings.IsUnknown() {
259-
state.Settings = previousState.Settings
260+
mergedSettings, err := mergeSettings(previousState.Settings, state.Settings, false)
261+
if err != nil {
262+
resp.Diagnostics.AddError(
263+
"Unable to merge Destination subscription settings",
264+
err.Error(),
265+
)
266+
267+
return
268+
}
269+
state.Settings = mergedSettings
260270
}
261271

262272
diags = resp.State.Set(ctx, &state)

internal/provider/insert_function_instance_resource.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,18 @@ func (r *insertFunctionInstanceResource) Read(ctx context.Context, req resource.
186186
return
187187
}
188188

189+
// Merge settings: keep config-defined settings while ignoring backend-generated ones not in config
189190
if !previousState.Settings.IsNull() && !previousState.Settings.IsUnknown() {
190-
state.Settings = previousState.Settings
191+
mergedSettings, err := mergeSettings(previousState.Settings, state.Settings, false)
192+
if err != nil {
193+
resp.Diagnostics.AddError(
194+
"Unable to merge Insert Function instance settings",
195+
err.Error(),
196+
)
197+
198+
return
199+
}
200+
state.Settings = mergedSettings
191201
}
192202

193203
// This is to satisfy terraform requirements that the input fields must match the returned ones. The input FunctionID can be prefixed with "ifnd_" and the returned one is not.

internal/provider/profiles_warehouse_resource.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,18 @@ func (r *profilesWarehouseResource) Read(ctx context.Context, req resource.ReadR
195195
return
196196
}
197197

198+
// Merge settings: keep config-defined settings while ignoring backend-generated ones not in config
198199
if !previousState.Settings.IsNull() && !previousState.Settings.IsUnknown() {
199-
state.Settings = previousState.Settings
200+
mergedSettings, err := mergeSettings(previousState.Settings, state.Settings, true)
201+
if err != nil {
202+
resp.Diagnostics.AddError(
203+
"Unable to merge Profiles Warehouse settings",
204+
err.Error(),
205+
)
206+
207+
return
208+
}
209+
state.Settings = mergedSettings
200210
}
201211

202212
diags = resp.State.Set(ctx, &state)

internal/provider/source_resource.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,9 +415,18 @@ func (r *sourceResource) Read(ctx context.Context, req resource.ReadRequest, res
415415
return
416416
}
417417

418-
// This is to satisfy terraform requirements that the returned fields must match the input ones because new settings can be generated in the response
418+
// Merge settings: keep config-defined settings while ignoring backend-generated ones not in config
419419
if !previousState.Settings.IsNull() && !previousState.Settings.IsUnknown() {
420-
state.Settings = previousState.Settings
420+
mergedSettings, err := mergeSettings(previousState.Settings, state.Settings, false)
421+
if err != nil {
422+
resp.Diagnostics.AddError(
423+
"Unable to merge Source settings",
424+
err.Error(),
425+
)
426+
427+
return
428+
}
429+
state.Settings = mergedSettings
421430
}
422431

423432
diags = resp.State.Set(ctx, &state)

internal/provider/utils.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ package provider
33
import (
44
"bytes"
55
"encoding/json"
6+
"fmt"
67
"io"
78
"net/http"
9+
"strings"
10+
11+
"github.com/hashicorp/terraform-plugin-framework-jsontypes/jsontypes"
12+
"github.com/segmentio/terraform-provider-segment/internal/provider/models"
813
)
914

1015
func getError(err error, body *http.Response) string {
@@ -23,3 +28,39 @@ func getError(err error, body *http.Response) string {
2328

2429
return err.Error() + "\n" + formattedBody.String()
2530
}
31+
32+
// mergeSettings merges config settings with remote settings, preserving only the keys defined in config.
33+
func mergeSettings(configSettings, remoteSettings jsontypes.Normalized, isWarehouse bool) (jsontypes.Normalized, error) {
34+
var configMap map[string]interface{}
35+
if diags := configSettings.Unmarshal(&configMap); diags.HasError() {
36+
return jsontypes.NewNormalizedNull(), fmt.Errorf("failed to unmarshal config settings: %s", diags.Errors())
37+
}
38+
39+
var remoteMap map[string]interface{}
40+
if diags := remoteSettings.Unmarshal(&remoteMap); diags.HasError() {
41+
return jsontypes.NewNormalizedNull(), fmt.Errorf("failed to unmarshal remote settings: %s", diags.Errors())
42+
}
43+
44+
// Create merged map with only config-defined keys that exist in remote (to detect drift)
45+
// Keys in config but not in remote are excluded (they don't exist or aren't supported)
46+
merged := make(map[string]interface{})
47+
for key := range configMap {
48+
if isWarehouse && key == "password" { // Warehouses do not output password in the response
49+
merged[key] = configMap[key]
50+
} else if value, exists := remoteMap[key]; exists {
51+
strValue, ok := value.(string)
52+
if ok && strings.Contains(strValue, "•") { // If the secret is censored, do not update it
53+
merged[key] = configMap[key]
54+
} else {
55+
merged[key] = value
56+
}
57+
}
58+
}
59+
60+
result, err := models.GetSettings(merged)
61+
if err != nil {
62+
return jsontypes.Normalized{}, fmt.Errorf("failed to merge settings: %w", err)
63+
}
64+
65+
return result, nil
66+
}

0 commit comments

Comments
 (0)