@@ -7,18 +7,23 @@ import (
7
7
"fmt"
8
8
"io"
9
9
"net/http"
10
+ "time"
10
11
11
12
"github.com/cloudflare/cloudflare-go/v5"
12
13
"github.com/cloudflare/cloudflare-go/v5/option"
13
14
"github.com/cloudflare/cloudflare-go/v5/zero_trust"
14
15
"github.com/cloudflare/terraform-provider-cloudflare/internal/apijson"
15
16
"github.com/cloudflare/terraform-provider-cloudflare/internal/logging"
17
+ "github.com/hashicorp/terraform-plugin-framework/path"
16
18
"github.com/hashicorp/terraform-plugin-framework/resource"
19
+ "github.com/hashicorp/terraform-plugin-framework/types"
20
+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
17
21
)
18
22
19
23
// Ensure provider defined types fully satisfy framework interfaces.
20
24
var _ resource.ResourceWithConfigure = (* ZeroTrustAccessMTLSHostnameSettingsResource )(nil )
21
25
var _ resource.ResourceWithModifyPlan = (* ZeroTrustAccessMTLSHostnameSettingsResource )(nil )
26
+ var _ resource.ResourceWithImportState = (* ZeroTrustAccessMTLSHostnameSettingsResource )(nil )
22
27
23
28
func NewResource () resource.Resource {
24
29
return & ZeroTrustAccessMTLSHostnameSettingsResource {}
@@ -76,13 +81,23 @@ func (r *ZeroTrustAccessMTLSHostnameSettingsResource) Create(ctx context.Context
76
81
params .ZoneID = cloudflare .F (data .ZoneID .ValueString ())
77
82
}
78
83
79
- _ , err = r .client .ZeroTrust .Access .Certificates .Settings .Update (
80
- ctx ,
81
- params ,
82
- option .WithRequestBody ("application/json" , dataBytes ),
83
- option .WithResponseBodyInto (& res ),
84
- option .WithMiddleware (logging .Middleware (ctx )),
85
- )
84
+ err = retry .RetryContext (ctx , 2 * time .Minute , func () * retry.RetryError {
85
+ _ , retryErr := r .client .ZeroTrust .Access .Certificates .Settings .Update (
86
+ ctx ,
87
+ params ,
88
+ option .WithRequestBody ("application/json" , dataBytes ),
89
+ option .WithResponseBodyInto (& res ),
90
+ option .WithMiddleware (logging .Middleware (ctx )),
91
+ )
92
+ if retryErr != nil {
93
+ // Check if it's a conflict error that should be retried
94
+ if res != nil && res .StatusCode == 409 {
95
+ return retry .RetryableError (retryErr )
96
+ }
97
+ return retry .NonRetryableError (retryErr )
98
+ }
99
+ return nil
100
+ })
86
101
if err != nil {
87
102
resp .Diagnostics .AddError ("failed to make http request" , err .Error ())
88
103
return
@@ -130,13 +145,23 @@ func (r *ZeroTrustAccessMTLSHostnameSettingsResource) Update(ctx context.Context
130
145
params .ZoneID = cloudflare .F (data .ZoneID .ValueString ())
131
146
}
132
147
133
- _ , err = r .client .ZeroTrust .Access .Certificates .Settings .Update (
134
- ctx ,
135
- params ,
136
- option .WithRequestBody ("application/json" , dataBytes ),
137
- option .WithResponseBodyInto (& res ),
138
- option .WithMiddleware (logging .Middleware (ctx )),
139
- )
148
+ err = retry .RetryContext (ctx , 2 * time .Minute , func () * retry.RetryError {
149
+ _ , retryErr := r .client .ZeroTrust .Access .Certificates .Settings .Update (
150
+ ctx ,
151
+ params ,
152
+ option .WithRequestBody ("application/json" , dataBytes ),
153
+ option .WithResponseBodyInto (& res ),
154
+ option .WithMiddleware (logging .Middleware (ctx )),
155
+ )
156
+ if retryErr != nil {
157
+ // Check if it's a conflict error that should be retried
158
+ if res != nil && res .StatusCode == 409 {
159
+ return retry .RetryableError (retryErr )
160
+ }
161
+ return retry .NonRetryableError (retryErr )
162
+ }
163
+ return nil
164
+ })
140
165
if err != nil {
141
166
resp .Diagnostics .AddError ("failed to make http request" , err .Error ())
142
167
return
@@ -201,6 +226,52 @@ func (r *ZeroTrustAccessMTLSHostnameSettingsResource) Delete(ctx context.Context
201
226
202
227
}
203
228
229
+ func (r * ZeroTrustAccessMTLSHostnameSettingsResource ) ImportState (ctx context.Context , req resource.ImportStateRequest , resp * resource.ImportStateResponse ) {
230
+ var data * ZeroTrustAccessMTLSHostnameSettingsModel = new (ZeroTrustAccessMTLSHostnameSettingsModel )
231
+ importID := req .ID
232
+
233
+ // Check if it's a zone ID or account ID and set the appropriate field
234
+ if len (importID ) == 32 {
235
+ // Account ID
236
+ resp .Diagnostics .Append (resp .State .SetAttribute (ctx , path .Root ("account_id" ), importID )... )
237
+ data .AccountID = types .StringValue (importID )
238
+ } else {
239
+ // Zone ID
240
+ resp .Diagnostics .Append (resp .State .SetAttribute (ctx , path .Root ("zone_id" ), importID )... )
241
+ data .ZoneID = types .StringValue (importID )
242
+ }
243
+
244
+ if resp .Diagnostics .HasError () {
245
+ return
246
+ }
247
+
248
+ // Since import just passes the identifier, we need to read the current state
249
+ // from the API. We'll do this by creating a mock ReadRequest and calling Read()
250
+ var fullData * ZeroTrustAccessMTLSHostnameSettingsModel = new (ZeroTrustAccessMTLSHostnameSettingsModel )
251
+ if ! data .AccountID .IsNull () {
252
+ fullData .AccountID = data .AccountID
253
+ } else {
254
+ fullData .ZoneID = data .ZoneID
255
+ }
256
+
257
+ // Set the full data in state first so Read can process it
258
+ resp .Diagnostics .Append (resp .State .Set (ctx , fullData )... )
259
+ if resp .Diagnostics .HasError () {
260
+ return
261
+ }
262
+
263
+ // Create a Read request and response to fetch the full state
264
+ readReq := resource.ReadRequest {State : resp .State }
265
+ readResp := & resource.ReadResponse {State : resp .State , Diagnostics : resp .Diagnostics }
266
+
267
+ // Call the Read method to populate the full state
268
+ r .Read (ctx , readReq , readResp )
269
+
270
+ // Copy back the results
271
+ resp .State = readResp .State
272
+ resp .Diagnostics = readResp .Diagnostics
273
+ }
274
+
204
275
func (r * ZeroTrustAccessMTLSHostnameSettingsResource ) ModifyPlan (ctx context.Context , req resource.ModifyPlanRequest , resp * resource.ModifyPlanResponse ) {
205
276
if req .State .Raw .IsNull () {
206
277
resp .Diagnostics .AddWarning (
0 commit comments