Skip to content

Commit 060b50d

Browse files
authored
Merge branch 'main' into main
2 parents d69fb92 + f0f453f commit 060b50d

10 files changed

Lines changed: 302 additions & 93 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ jobs:
2626
go-version: ${{ env.GO_VERSION }}
2727

2828
- name: Setup Terraform
29-
uses: hashicorp/setup-terraform@v3
29+
uses: hashicorp/setup-terraform@v4
3030
with:
3131
terraform_wrapper: false
3232

go.mod

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/gorilla/mux v1.8.1
99
github.com/hashicorp/terraform-plugin-framework v1.17.0
1010
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
11-
github.com/hashicorp/terraform-plugin-go v0.29.0
11+
github.com/hashicorp/terraform-plugin-go v0.30.0
1212
github.com/hashicorp/terraform-plugin-log v0.10.0
1313
github.com/hashicorp/terraform-plugin-testing v1.14.0
1414
github.com/stackitcloud/stackit-sdk-go/core v0.22.0
@@ -97,9 +97,9 @@ require (
9797
golang.org/x/text v0.33.0 // indirect
9898
golang.org/x/tools v0.41.0 // indirect
9999
google.golang.org/appengine v1.6.8 // indirect
100-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
101-
google.golang.org/grpc v1.75.1 // indirect
102-
google.golang.org/protobuf v1.36.9 // indirect
100+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
101+
google.golang.org/grpc v1.79.1 // indirect
102+
google.golang.org/protobuf v1.36.11 // indirect
103103
)
104104

105105
tool golang.org/x/tools/cmd/goimports

go.sum

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
1111
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
1212
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
1313
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
14+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
15+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
1416
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
1517
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
1618
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -91,8 +93,8 @@ github.com/hashicorp/terraform-plugin-framework v1.17.0 h1:JdX50CFrYcYFY31gkmitA
9193
github.com/hashicorp/terraform-plugin-framework v1.17.0/go.mod h1:4OUXKdHNosX+ys6rLgVlgklfxN3WHR5VHSOABeS/BM0=
9294
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0 h1:Zz3iGgzxe/1XBkooZCewS0nJAaCFPFPHdNJd8FgE4Ow=
9395
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0/go.mod h1:GBKTNGbGVJohU03dZ7U8wHqc2zYnMUawgCN+gC0itLc=
94-
github.com/hashicorp/terraform-plugin-go v0.29.0 h1:1nXKl/nSpaYIUBU1IG/EsDOX0vv+9JxAltQyDMpq5mU=
95-
github.com/hashicorp/terraform-plugin-go v0.29.0/go.mod h1:vYZbIyvxyy0FWSmDHChCqKvI40cFTDGSb3D8D70i9GM=
96+
github.com/hashicorp/terraform-plugin-go v0.30.0 h1:VmEiD0n/ewxbvV5VI/bYwNtlSEAXtHaZlSnyUUuQK6k=
97+
github.com/hashicorp/terraform-plugin-go v0.30.0/go.mod h1:8d523ORAW8OHgA9e8JKg0ezL3XUO84H0A25o4NY/jRo=
9698
github.com/hashicorp/terraform-plugin-log v0.10.0 h1:eu2kW6/QBVdN4P3Ju2WiB2W3ObjkAsyfBsL3Wh1fj3g=
9799
github.com/hashicorp/terraform-plugin-log v0.10.0/go.mod h1:/9RR5Cv2aAbrqcTSdNmY1NRHP4E3ekrXRGjqORpXyB0=
98100
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 h1:mlAq/OrMlg04IuJT7NpefI1wwtdpWudnEmjuQs04t/4=
@@ -231,18 +233,18 @@ github.com/zclconf/go-cty v1.17.0 h1:seZvECve6XX4tmnvRzWtJNHdscMtYEx5R7bnnVyd/d0
231233
github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=
232234
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
233235
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
234-
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
235-
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
236-
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
237-
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
238-
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
239-
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
240-
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
241-
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
242-
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
243-
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
244-
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
245-
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
236+
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
237+
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
238+
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
239+
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
240+
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
241+
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
242+
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
243+
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
244+
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
245+
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
246+
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
247+
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
246248
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
247249
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
248250
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
@@ -298,14 +300,14 @@ gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E
298300
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
299301
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
300302
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
301-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 h1:pFyd6EwwL2TqFf8emdthzeX+gZE1ElRq3iM8pui4KBY=
302-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
303-
google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI=
304-
google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ=
303+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
304+
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
305+
google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY=
306+
google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
305307
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
306308
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
307-
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
308-
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
309+
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
310+
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
309311
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
310312
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
311313
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

stackit/internal/services/observability/instance/resource.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import (
88
"strings"
99

1010
"github.com/google/go-cmp/cmp"
11-
"github.com/hashicorp/terraform-plugin-framework/resource/schema/int64planmodifier"
1211
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils"
12+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils/planmodifiers/int64planmodifier"
1313

1414
observabilityUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/observability/utils"
1515

@@ -543,23 +543,23 @@ func (r *instanceResource) Schema(_ context.Context, _ resource.SchemaRequest, r
543543
Optional: true,
544544
Computed: true,
545545
PlanModifiers: []planmodifier.Int64{
546-
int64planmodifier.UseStateForUnknown(),
546+
int64planmodifier.UseStateForUnknownIf(utils.Int64Changed, "metrics_retention_days", "sets `UseStateForUnknown` only if `metrics_retention_days` has not changed"),
547547
},
548548
},
549549
"metrics_retention_days_5m_downsampling": schema.Int64Attribute{
550550
Description: "Specifies for how many days the 5m downsampled metrics are kept. must be less than the value of the general retention. Default is set to `90`.",
551551
Optional: true,
552552
Computed: true,
553553
PlanModifiers: []planmodifier.Int64{
554-
int64planmodifier.UseStateForUnknown(),
554+
int64planmodifier.UseStateForUnknownIf(utils.Int64Changed, "metrics_retention_days_5m_downsampling", "sets `UseStateForUnknown` only if `metrics_retention_days_5m_downsampling` has not changed"),
555555
},
556556
},
557557
"metrics_retention_days_1h_downsampling": schema.Int64Attribute{
558558
Description: "Specifies for how many days the 1h downsampled metrics are kept. must be less than the value of the 5m downsampling retention. Default is set to `90`.",
559559
Optional: true,
560560
Computed: true,
561561
PlanModifiers: []planmodifier.Int64{
562-
int64planmodifier.UseStateForUnknown(),
562+
int64planmodifier.UseStateForUnknownIf(utils.Int64Changed, "metrics_retention_days_1h_downsampling", "sets `UseStateForUnknown` only if `metrics_retention_days_1h_downsampling` has not changed"),
563563
},
564564
},
565565
"metrics_url": schema.StringAttribute{

stackit/internal/services/ske/cluster/resource.go

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
serviceenablementUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/serviceenablement/utils"
1313
skeUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/services/ske/utils"
14+
stringplanmodifierUtils "github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils/planmodifiers/stringplanmodifier"
1415

1516
"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
1617
"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
@@ -368,7 +369,7 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re
368369
Description: "Full Kubernetes version used. For example, if 1.22 was set in `kubernetes_version_min`, this value may result to 1.22.15. " + SKEUpdateDoc,
369370
Computed: true,
370371
PlanModifiers: []planmodifier.String{
371-
utils.UseStateForUnknownIf(hasKubernetesMinChanged, "sets `UseStateForUnknown` only if `kubernetes_min_version` has not changed"),
372+
stringplanmodifierUtils.UseStateForUnknownIf(utils.StringChanged, "kubernetes_version_min", "sets `UseStateForUnknown` only if `kubernetes_min_version` has not changed"),
372373
},
373374
},
374375
"egress_address_ranges": schema.ListAttribute{
@@ -451,7 +452,7 @@ func (r *clusterResource) Schema(_ context.Context, _ resource.SchemaRequest, re
451452
Description: "Full OS image version used. For example, if 3815.2 was set in `os_version_min`, this value may result to 3815.2.2. " + SKEUpdateDoc,
452453
Computed: true,
453454
PlanModifiers: []planmodifier.String{
454-
utils.UseStateForUnknownIf(hasOsVersionMinChanged, "sets `UseStateForUnknown` only if `os_version_min` has not changed"),
455+
stringplanmodifierUtils.UseStateForUnknownIf(utils.StringChanged, "os_version_min", "sets `UseStateForUnknown` only if `os_version_min` has not changed"),
455456
},
456457
},
457458
"volume_type": schema.StringAttribute{
@@ -2108,52 +2109,6 @@ func getLatestSupportedKubernetesVersion(versions []ske.KubernetesVersion) (*str
21082109
return latestVersion, nil
21092110
}
21102111

2111-
func hasKubernetesMinChanged(ctx context.Context, request planmodifier.StringRequest, response *utils.UseStateForUnknownFuncResponse) { // nolint:gocritic // function signature required by Terraform
2112-
dependencyPath := path.Root("kubernetes_version_min")
2113-
2114-
var minVersionPlan types.String
2115-
diags := request.Plan.GetAttribute(ctx, dependencyPath, &minVersionPlan)
2116-
response.Diagnostics.Append(diags...)
2117-
if response.Diagnostics.HasError() {
2118-
return
2119-
}
2120-
2121-
var minVersionState types.String
2122-
diags = request.State.GetAttribute(ctx, dependencyPath, &minVersionState)
2123-
response.Diagnostics.Append(diags...)
2124-
if response.Diagnostics.HasError() {
2125-
return
2126-
}
2127-
2128-
if minVersionState == minVersionPlan {
2129-
response.UseStateForUnknown = true
2130-
return
2131-
}
2132-
}
2133-
2134-
func hasOsVersionMinChanged(ctx context.Context, request planmodifier.StringRequest, response *utils.UseStateForUnknownFuncResponse) { // nolint:gocritic // function signature required by Terraform
2135-
dependencyPath := request.Path.ParentPath().AtName("os_version_min")
2136-
2137-
var minVersionPlan types.String
2138-
diags := request.Plan.GetAttribute(ctx, dependencyPath, &minVersionPlan)
2139-
response.Diagnostics.Append(diags...)
2140-
if response.Diagnostics.HasError() {
2141-
return
2142-
}
2143-
2144-
var minVersionState types.String
2145-
diags = request.State.GetAttribute(ctx, dependencyPath, &minVersionState)
2146-
response.Diagnostics.Append(diags...)
2147-
if response.Diagnostics.HasError() {
2148-
return
2149-
}
2150-
2151-
if minVersionState == minVersionPlan {
2152-
response.UseStateForUnknown = true
2153-
return
2154-
}
2155-
}
2156-
21572112
func (r *clusterResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { // nolint:gocritic // function signature required by Terraform
21582113
var state Model
21592114
diags := req.State.Get(ctx, &state)

stackit/internal/utils/attributes.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import (
77

88
"github.com/hashicorp/terraform-plugin-framework/diag"
99
"github.com/hashicorp/terraform-plugin-framework/path"
10+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
1011
"github.com/hashicorp/terraform-plugin-framework/types"
1112
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/core"
13+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils/planmodifiers/int64planmodifier"
14+
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/utils/planmodifiers/stringplanmodifier"
1215
)
1316

1417
type attributeGetter interface {
@@ -44,3 +47,51 @@ func GetTimeFromStringAttribute(ctx context.Context, attributePath path.Path, so
4447

4548
return diags
4649
}
50+
51+
// Int64Changed sets UseStateForUnkown to true if the attribute's planned value matches the current state
52+
func Int64Changed(ctx context.Context, attributeName string, request planmodifier.Int64Request, response *int64planmodifier.UseStateForUnknownFuncResponse) { // nolint:gocritic // function signature required by Terraform
53+
dependencyPath := request.Path.ParentPath().AtName(attributeName)
54+
55+
var attributePlan types.Int64
56+
diags := request.Plan.GetAttribute(ctx, dependencyPath, &attributePlan)
57+
response.Diagnostics.Append(diags...)
58+
if response.Diagnostics.HasError() {
59+
return
60+
}
61+
62+
var attributeState types.Int64
63+
diags = request.State.GetAttribute(ctx, dependencyPath, &attributeState)
64+
response.Diagnostics.Append(diags...)
65+
if response.Diagnostics.HasError() {
66+
return
67+
}
68+
69+
if attributeState == attributePlan {
70+
response.UseStateForUnknown = true
71+
return
72+
}
73+
}
74+
75+
// StringChanged sets UseStateForUnkown to true if the attribute's planned value matches the current state
76+
func StringChanged(ctx context.Context, attributeName string, request planmodifier.StringRequest, response *stringplanmodifier.UseStateForUnknownFuncResponse) { // nolint:gocritic // function signature required by Terraform
77+
dependencyPath := request.Path.ParentPath().AtName(attributeName)
78+
79+
var attributePlan types.String
80+
diags := request.Plan.GetAttribute(ctx, dependencyPath, &attributePlan)
81+
response.Diagnostics.Append(diags...)
82+
if response.Diagnostics.HasError() {
83+
return
84+
}
85+
86+
var attributeState types.String
87+
diags = request.State.GetAttribute(ctx, dependencyPath, &attributeState)
88+
response.Diagnostics.Append(diags...)
89+
if response.Diagnostics.HasError() {
90+
return
91+
}
92+
93+
if attributeState == attributePlan {
94+
response.UseStateForUnknown = true
95+
return
96+
}
97+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package int64planmodifier
2+
3+
import (
4+
"context"
5+
6+
"github.com/hashicorp/terraform-plugin-framework/diag"
7+
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
8+
)
9+
10+
type UseStateForUnknownFuncResponse struct {
11+
UseStateForUnknown bool
12+
Diagnostics diag.Diagnostics
13+
}
14+
15+
// UseStateForUnknownIfFunc is a conditional function used in UseStateForUnknownIf
16+
type UseStateForUnknownIfFunc func(context.Context, string, planmodifier.Int64Request, *UseStateForUnknownFuncResponse)
17+
18+
type useStateForUnknownIf struct {
19+
ifFunc UseStateForUnknownIfFunc
20+
attributeName string
21+
description string
22+
}
23+
24+
// UseStateForUnknownIf returns a plan modifier similar to UseStateForUnknown with a conditional
25+
func UseStateForUnknownIf(f UseStateForUnknownIfFunc, attributeName, description string) planmodifier.Int64 {
26+
return useStateForUnknownIf{
27+
ifFunc: f,
28+
attributeName: attributeName,
29+
description: description,
30+
}
31+
}
32+
33+
func (m useStateForUnknownIf) Description(context.Context) string {
34+
return m.description
35+
}
36+
37+
func (m useStateForUnknownIf) MarkdownDescription(ctx context.Context) string {
38+
return m.Description(ctx)
39+
}
40+
41+
func (m useStateForUnknownIf) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, resp *planmodifier.Int64Response) { // nolint:gocritic // function signature required by Terraform
42+
// Do nothing if there is no state value.
43+
if req.StateValue.IsNull() {
44+
return
45+
}
46+
47+
// Do nothing if there is a known planned value.
48+
if !req.PlanValue.IsUnknown() {
49+
return
50+
}
51+
52+
// Do nothing if there is an unknown configuration value, otherwise interpolation gets messed up.
53+
if req.ConfigValue.IsUnknown() {
54+
return
55+
}
56+
57+
// The above checks are taken from the UseStateForUnknown plan modifier implementation
58+
// (https://github.com/hashicorp/terraform-plugin-framework/blob/44348af3923c82a93c64ae7dca906d9850ba956b/resource/schema/stringplanmodifier/use_state_for_unknown.go#L38)
59+
60+
funcResponse := &UseStateForUnknownFuncResponse{}
61+
m.ifFunc(ctx, m.attributeName, req, funcResponse)
62+
63+
resp.Diagnostics.Append(funcResponse.Diagnostics...)
64+
if resp.Diagnostics.HasError() {
65+
return
66+
}
67+
68+
if funcResponse.UseStateForUnknown {
69+
resp.PlanValue = req.StateValue
70+
}
71+
}

0 commit comments

Comments
 (0)