@@ -13,6 +13,7 @@ import (
13
13
"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
14
14
"github.com/hashicorp/terraform-plugin-framework/types"
15
15
"github.com/hashicorp/terraform-plugin-log/tflog"
16
+ "strings"
16
17
17
18
tfe "github.com/hashicorp/go-tfe"
18
19
)
@@ -257,17 +258,17 @@ func (m *preserveAMD64ArchsModifier) PlanModifySet(ctx context.Context, req plan
257
258
return
258
259
}
259
260
260
- var stateURL , planURL , stateSHA , planSHA types.String
261
+ var configURL , planURL , configSHA , planSHA types.String
261
262
262
263
// Get values from state and plan
263
- req .State .GetAttribute (ctx , path .Root ("url" ), & stateURL )
264
+ req .Config .GetAttribute (ctx , path .Root ("url" ), & configURL )
264
265
req .Plan .GetAttribute (ctx , path .Root ("url" ), & planURL )
265
- req .State .GetAttribute (ctx , path .Root ("sha" ), & stateSHA )
266
+ req .State .GetAttribute (ctx , path .Root ("sha" ), & configSHA )
266
267
req .Plan .GetAttribute (ctx , path .Root ("sha" ), & planSHA )
267
268
268
269
// Check if values are changing
269
- urlChanged := ! stateURL .Equal (planURL )
270
- shaChanged := ! stateSHA .Equal (planSHA )
270
+ urlChanged := ! configURL .Equal (planURL )
271
+ shaChanged := ! configSHA .Equal (planSHA )
271
272
272
273
// If neither URL nor SHA is changing, do nothing
273
274
if ! urlChanged && ! shaChanged {
@@ -300,9 +301,9 @@ func (m *preserveAMD64ArchsModifier) PlanModifySet(ctx context.Context, req plan
300
301
"stateArchsList" : stateArchsList ,
301
302
"urlChanged" : urlChanged ,
302
303
"shaChanged" : shaChanged ,
303
- "stateURL" : stateURL ,
304
+ "stateURL" : configURL ,
304
305
"planURL" : planURL ,
305
- "stateSHA" : stateSHA ,
306
+ "stateSHA" : configSHA ,
306
307
"planSHA" : planSHA ,
307
308
})
308
309
// Check if AMD64 is already in the plan
@@ -317,10 +318,10 @@ func (m *preserveAMD64ArchsModifier) PlanModifySet(ctx context.Context, req plan
317
318
// If we found AMD64, update its URL and SHA if they are changing
318
319
// If URL or SHA is changing, update the AMD64 arch to match
319
320
if urlChanged {
320
- arch .URL = planURL
321
+ arch .URL = configURL
321
322
}
322
323
if shaChanged {
323
- arch .Sha = planSHA
324
+ arch .Sha = configURL
324
325
}
325
326
326
327
// Update the plan with the modified AMD64 arch
@@ -341,6 +342,100 @@ func (m *preserveAMD64ArchsModifier) PlanModifySet(ctx context.Context, req plan
341
342
}
342
343
}
343
344
345
+ // SyncTopLevelURLSHAWithAMD64 creates a plan modifier that synchronizes the top-level URL/SHA with the AMD64 architecture on updates where URL or SHA is not set in the config,
346
+ func SyncTopLevelURLSHAWithAMD64 () planmodifier.String {
347
+ return & SyncTopLevelURLSHAWithAMD64Modifier {}
348
+ }
349
+
350
+ // Implement the plan modifier interface
351
+ type SyncTopLevelURLSHAWithAMD64Modifier struct {}
352
+
353
+ // Description provides a plain text description of the plan modifier
354
+ func (m * SyncTopLevelURLSHAWithAMD64Modifier ) Description (ctx context.Context ) string {
355
+ return "Combines top-level URL/SHA with AMD64 architecture"
356
+ }
357
+
358
+ // MarkdownDescription provides markdown documentation
359
+ func (m * SyncTopLevelURLSHAWithAMD64Modifier ) MarkdownDescription (ctx context.Context ) string {
360
+ return "Combines top-level URL/SHA with AMD64 architecture"
361
+ }
362
+
363
+ // PlanModifySet modifies the plan to combine URL/SHA with AMD64 architecture
364
+ func (m * SyncTopLevelURLSHAWithAMD64Modifier ) PlanModifyString (ctx context.Context , req planmodifier.StringRequest , resp * planmodifier.StringResponse ) {
365
+ // Skip if we're destroying the resource or no state
366
+ if req .Plan .Raw .IsNull () || req .State .Raw .IsNull () || req .StateValue .IsNull () {
367
+ tflog .Debug (ctx , "Skipping AMD64 URL/SHA combination because state or plan is null" )
368
+ return
369
+ }
370
+
371
+ if ! req .ConfigValue .IsUnknown () && ! req .ConfigValue .IsNull () {
372
+ tflog .Debug (ctx , "Skipping because value is set in config" )
373
+ return
374
+ }
375
+
376
+ // if config archs is not set we will not modify the plan
377
+ // get the config archs
378
+
379
+ var configArchs types.Set
380
+ diags := req .Config .GetAttribute (ctx , path .Root ("archs" ), & configArchs )
381
+ if diags .HasError () {
382
+ tflog .Debug (ctx , "Error extracting config architectures" , map [string ]interface {}{
383
+ "diagnostics" : diags ,
384
+ })
385
+ return
386
+ }
387
+
388
+ if configArchs .IsNull () && configArchs .IsUnknown () {
389
+ tflog .Debug (ctx , "Skipping top level arch modifying because archs are NOT set in config" )
390
+ return
391
+ }
392
+
393
+ // we do not know the name of the attibute
394
+ // we are modifying, so we will use the path to get the attribute name
395
+ segments := req .Path .String ()
396
+ attributeName := segments [strings .LastIndex (segments , "." )+ 1 :]
397
+
398
+ // get the archs from the plan
399
+ // get the amd arch from the configArchs
400
+ var amd64Arch ToolArchitecture
401
+ var configArchsList []ToolArchitecture
402
+ diags = configArchs .ElementsAs (ctx , & configArchsList , false )
403
+ if diags .HasError () {
404
+ tflog .Debug (ctx , "Error extracting config architectures" , map [string ]interface {}{
405
+ "diagnostics" : diags ,
406
+ })
407
+ return
408
+ }
409
+
410
+ for _ , arch := range configArchsList {
411
+ if arch .Arch .ValueString () == "amd64" {
412
+ amd64Arch = arch
413
+ break
414
+ }
415
+ }
416
+
417
+ if amd64Arch .Arch .IsNull () || amd64Arch .Arch .IsUnknown () {
418
+ tflog .Debug (ctx , "No AMD64 architecture found in config archs, skipping modification" )
419
+ return
420
+ }
421
+
422
+ // Get the value of the attributeName from the amd64 arch
423
+ switch attributeName {
424
+ case "url" :
425
+ // set the plan value to the URL of the AMD64 arch
426
+ resp .PlanValue = types .StringValue (amd64Arch .URL .ValueString ())
427
+ case "sha" :
428
+ // set the plan value to the SHA of the AMD64 arch
429
+ resp .PlanValue = types .StringValue (amd64Arch .Sha .ValueString ())
430
+ default :
431
+ tflog .Debug (ctx , "Unsupported attribute for AMD64 combination" , map [string ]interface {}{
432
+ "attribute" : attributeName ,
433
+ })
434
+ return
435
+ }
436
+
437
+ }
438
+
344
439
//
345
440
// // ValidateToolVersion provides common validation for tool version resources
346
441
// func ValidateToolVersion(ctx context.Context, url, sha types.String, archs types.Set, resourceType string) diag.Diagnostics {
0 commit comments