@@ -71,15 +71,14 @@ func (r *lifecycleTypeResource) Create(ctx context.Context, req resource.CreateR
71
71
resp .Diagnostics .Append (req .Config .Get (ctx , & data )... )
72
72
validateRetentionBlocksUsed (data , & resp .Diagnostics , r .serverSupportsRetentionWithStrategy )
73
73
isRetentionWithStrategyUsedExclusively := retentionWithStrategyWillBeUsedExclusively (data , r .serverSupportsRetentionWithStrategy )
74
-
75
74
if resp .Diagnostics .HasError () {
76
75
return
77
76
}
78
77
79
78
hasUserDefinedReleaseRetention , hasUserDefinedTentacleRetention := setDefaultRetention (data , isRetentionWithStrategyUsedExclusively )
80
79
hasUserDefinedReleaseRetentionWithStrategy , hasUserDefinedTentacleRetentionWithStrategy := setDefaultRetentionWithStrategy (data , isRetentionWithStrategyUsedExclusively )
81
80
82
- newLifecycle := expandLifecycle (data )
81
+ newLifecycle := expandLifecycle (data , isRetentionWithStrategyUsedExclusively )
83
82
lifecycle , err := lifecycles .Add (r .Config .Client , newLifecycle )
84
83
if err != nil {
85
84
resp .Diagnostics .AddError ("unable to create lifecycle" , err .Error ())
@@ -89,9 +88,10 @@ func (r *lifecycleTypeResource) Create(ctx context.Context, req resource.CreateR
89
88
handleUnitCasing (lifecycle , newLifecycle )
90
89
91
90
data = flattenLifecycleResource (lifecycle , isRetentionWithStrategyUsedExclusively )
91
+ tflog .Debug (ctx , fmt .Sprintf ("after the flatten rose '%v'" , data .Phase ))
92
92
removeDefaultRetentionFromUnsetBlocks (data , hasUserDefinedReleaseRetention , hasUserDefinedTentacleRetention )
93
93
removeDefaultRetentionWithStrategyFromUnsetBlocks (data , hasUserDefinedReleaseRetentionWithStrategy , hasUserDefinedTentacleRetentionWithStrategy )
94
-
94
+ tflog . Debug ( ctx , fmt . Sprintf ( "after the removal rose '%v'" , data . Phase ))
95
95
resp .Diagnostics .Append (resp .State .Set (ctx , & data )... )
96
96
}
97
97
@@ -113,7 +113,7 @@ func (r *lifecycleTypeResource) Read(ctx context.Context, req resource.ReadReque
113
113
return
114
114
}
115
115
116
- handleUnitCasing (lifecycle , expandLifecycle (data ))
116
+ handleUnitCasing (lifecycle , expandLifecycle (data , isRetentionWithStrategyUsedExclusively ))
117
117
118
118
data = flattenLifecycleResource (lifecycle , isRetentionWithStrategyUsedExclusively )
119
119
@@ -131,14 +131,15 @@ func (r *lifecycleTypeResource) Update(ctx context.Context, req resource.UpdateR
131
131
if resp .Diagnostics .HasError () {
132
132
return
133
133
}
134
+
134
135
validateRetentionBlocksUsed (data , & resp .Diagnostics , r .serverSupportsRetentionWithStrategy )
135
136
isRetentionWithStrategyUsedExclusively := retentionWithStrategyWillBeUsedExclusively (data , r .serverSupportsRetentionWithStrategy )
136
137
hasUserDefinedReleaseRetention , hasUserDefinedTentacleRetention := setDefaultRetention (data , isRetentionWithStrategyUsedExclusively )
137
138
hasUserDefinedReleaseRetentionWithStrategy , hasUserDefinedTentacleRetentionWithStrategy := setDefaultRetentionWithStrategy (data , isRetentionWithStrategyUsedExclusively )
138
139
139
140
tflog .Debug (ctx , fmt .Sprintf ("updating lifecycle '%s'" , data .ID .ValueString ()))
140
141
141
- lifecycle := expandLifecycle (data )
142
+ lifecycle := expandLifecycle (data , isRetentionWithStrategyUsedExclusively )
142
143
lifecycle .ID = state .ID .ValueString ()
143
144
144
145
updatedLifecycle , err := lifecycles .Update (r .Config .Client , lifecycle )
@@ -350,7 +351,7 @@ func flattenLifecycleResource(lifecycle *lifecycles.Lifecycle, isRetentionWithSt
350
351
SpaceID : types .StringValue (lifecycle .SpaceID ),
351
352
Name : types .StringValue (lifecycle .Name ),
352
353
Description : types .StringValue (lifecycle .Description ),
353
- Phase : flattenPhases (lifecycle .Phases ),
354
+ Phase : flattenPhasesWithStrategy (lifecycle .Phases ),
354
355
ReleaseRetentionWithStrategy : flattenRetentionWithStrategy (lifecycle .ReleaseRetentionPolicy ),
355
356
TentacleRetentionWithStrategy : flattenRetentionWithStrategy (lifecycle .TentacleRetentionPolicy ),
356
357
}
@@ -371,8 +372,35 @@ func flattenLifecycleResource(lifecycle *lifecycles.Lifecycle, isRetentionWithSt
371
372
}
372
373
373
374
func flattenPhases (phases []* lifecycles.Phase ) types.List {
375
+ var attributeTypes = getPhaseAttrTypes ()
376
+ if phases == nil {
377
+ return types .ListNull (types.ObjectType {AttrTypes : attributeTypes })
378
+ }
379
+ phasesList := make ([]attr.Value , 0 , len (phases ))
380
+
381
+ for _ , phase := range phases {
382
+ attrs := map [string ]attr.Value {
383
+ "id" : types .StringValue (phase .ID ),
384
+ "name" : types .StringValue (phase .Name ),
385
+ "automatic_deployment_targets" : util .FlattenStringList (phase .AutomaticDeploymentTargets ),
386
+ "optional_deployment_targets" : util .FlattenStringList (phase .OptionalDeploymentTargets ),
387
+ "minimum_environments_before_promotion" : types .Int64Value (int64 (phase .MinimumEnvironmentsBeforePromotion )),
388
+ "is_optional_phase" : types .BoolValue (phase .IsOptionalPhase ),
389
+ "is_priority_phase" : types .BoolValue (phase .IsPriorityPhase ),
390
+ "release_retention_policy" : util .Ternary (phase .ReleaseRetentionPolicy != nil , flattenRetention (phase .ReleaseRetentionPolicy ), types .ListNull (types.ObjectType {AttrTypes : getRetentionAttrTypes ()})),
391
+ "tentacle_retention_policy" : util .Ternary (phase .TentacleRetentionPolicy != nil , flattenRetention (phase .TentacleRetentionPolicy ), types .ListNull (types.ObjectType {AttrTypes : getRetentionAttrTypes ()})),
392
+ "release_retention_with_strategy" : types .ListNull (types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()}),
393
+ "tentacle_retention_with_strategy" : types .ListNull (types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()}),
394
+ }
395
+ phasesList = append (phasesList , types .ObjectValueMust (attributeTypes , attrs ))
396
+ }
397
+ return types .ListValueMust (types.ObjectType {AttrTypes : attributeTypes }, phasesList )
398
+ }
399
+
400
+ func flattenPhasesWithStrategy (phases []* lifecycles.Phase ) types.List {
401
+ var attributeTypes = getPhaseWithStrategyAttrTypes ()
374
402
if phases == nil {
375
- return types .ListNull (types.ObjectType {AttrTypes : getPhaseAttrTypes () })
403
+ return types .ListNull (types.ObjectType {AttrTypes : attributeTypes })
376
404
}
377
405
phasesList := make ([]attr.Value , 0 , len (phases ))
378
406
@@ -385,14 +413,14 @@ func flattenPhases(phases []*lifecycles.Phase) types.List {
385
413
"minimum_environments_before_promotion" : types .Int64Value (int64 (phase .MinimumEnvironmentsBeforePromotion )),
386
414
"is_optional_phase" : types .BoolValue (phase .IsOptionalPhase ),
387
415
"is_priority_phase" : types .BoolValue (phase .IsPriorityPhase ),
388
- "release_retention " : util . Ternary ( phase . ReleaseRetentionPolicy != nil , flattenRetention ( phase . ReleaseRetentionPolicy ), types .ListNull (types.ObjectType {AttrTypes : getRetentionAttrTypes ()}) ),
389
- "tentacle_retention " : util . Ternary ( phase . TentacleRetentionPolicy != nil , flattenRetention ( phase . TentacleRetentionPolicy ), types .ListNull (types.ObjectType {AttrTypes : getRetentionAttrTypes ()}) ),
416
+ "release_retention_policy " : types .ListNull (types.ObjectType {AttrTypes : getRetentionAttrTypes ()}),
417
+ "tentacle_retention_policy " : types .ListNull (types.ObjectType {AttrTypes : getRetentionAttrTypes ()}),
390
418
"release_retention_with_strategy" : util .Ternary (phase .ReleaseRetentionPolicy != nil , flattenRetentionWithStrategy (phase .ReleaseRetentionPolicy ), types .ListNull (types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()})),
391
419
"tentacle_retention_with_strategy" : util .Ternary (phase .TentacleRetentionPolicy != nil , flattenRetentionWithStrategy (phase .TentacleRetentionPolicy ), types .ListNull (types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()})),
392
420
}
393
- phasesList = append (phasesList , types .ObjectValueMust (getPhaseAttrTypes () , attrs ))
421
+ phasesList = append (phasesList , types .ObjectValueMust (attributeTypes , attrs ))
394
422
}
395
- return types .ListValueMust (types.ObjectType {AttrTypes : getPhaseAttrTypes () }, phasesList )
423
+ return types .ListValueMust (types.ObjectType {AttrTypes : attributeTypes }, phasesList )
396
424
}
397
425
398
426
func flattenRetention (retention * core.RetentionPeriod ) types.List {
@@ -435,7 +463,7 @@ func flattenRetentionWithStrategy(retentionWithStrategy *core.RetentionPeriod) t
435
463
)
436
464
}
437
465
438
- func expandLifecycle (data * lifecycleTypeResourceModel ) * lifecycles.Lifecycle {
466
+ func expandLifecycle (data * lifecycleTypeResourceModel , isRetentionWithStrategyUsedExclusively bool ) * lifecycles.Lifecycle {
439
467
if data == nil {
440
468
return nil
441
469
}
@@ -447,15 +475,17 @@ func expandLifecycle(data *lifecycleTypeResourceModel) *lifecycles.Lifecycle {
447
475
lifecycle .ID = data .ID .ValueString ()
448
476
}
449
477
450
- lifecycle .Phases = expandPhases (data .Phase )
451
- lifecycle .ReleaseRetentionPolicy = expandRetentionWithOrWithoutStrategy (data .ReleaseRetention , data .ReleaseRetentionWithStrategy )
452
- lifecycle .TentacleRetentionPolicy = expandRetentionWithOrWithoutStrategy (data .TentacleRetention , data .TentacleRetentionWithStrategy )
453
-
478
+ if isRetentionWithStrategyUsedExclusively {
479
+ lifecycle .Phases = expandPhasesWithStrategy (data .Phase )
480
+ lifecycle .ReleaseRetentionPolicy = expandRetentionWithStrategy (data .ReleaseRetentionWithStrategy )
481
+ } else {
482
+ lifecycle .Phases = expandPhases (data .Phase )
483
+ lifecycle .ReleaseRetentionPolicy = expandRetention (data .ReleaseRetention )
484
+ }
454
485
return lifecycle
455
486
}
456
487
457
488
func expandPhases (phases types.List ) []* lifecycles.Phase {
458
- //TODO: don't allow with strategy to be used with the pre 2025.3 octopus
459
489
if phases .IsNull () || phases .IsUnknown () || len (phases .Elements ()) == 0 {
460
490
return nil
461
491
}
@@ -499,32 +529,67 @@ func expandPhases(phases types.List) []*lifecycles.Phase {
499
529
if v , ok := phaseAttrs ["release_retention_policy" ].(types.List ); ok && ! v .IsNull () {
500
530
phase .ReleaseRetentionPolicy = expandRetention (v )
501
531
}
502
- if v , ok := phaseAttrs ["release_retention_with_strategy" ].(types.List ); ok && ! v .IsNull () {
503
- phase .ReleaseRetentionPolicy = expandRetentionWithStrategy (v )
504
- }
505
532
if v , ok := phaseAttrs ["tentacle_retention_policy" ].(types.List ); ok && ! v .IsNull () {
506
533
phase .TentacleRetentionPolicy = expandRetention (v )
507
534
}
508
- if v , ok := phaseAttrs ["release_retention_with_strategy" ].(types.List ); ok && ! v .IsNull () {
509
- phase .TentacleRetentionPolicy = expandRetentionWithStrategy (v )
510
- }
511
535
result = append (result , phase )
512
536
}
513
537
514
538
return result
515
539
}
516
-
517
- func expandRetentionWithOrWithoutStrategy (oldRetention types.List , newRetention types.List ) * core.RetentionPeriod {
518
- oldRetentionPresent := ! oldRetention .IsNull () && ! oldRetention .IsUnknown ()
519
- newRetentionPresent := ! newRetention .IsNull () && ! newRetention .IsUnknown ()
520
- if ! oldRetentionPresent && ! newRetentionPresent {
540
+ func expandPhasesWithStrategy (phases types.List ) []* lifecycles.Phase {
541
+ if phases .IsNull () || phases .IsUnknown () || len (phases .Elements ()) == 0 {
521
542
return nil
522
543
}
523
- if oldRetentionPresent {
524
- return expandRetention (oldRetention )
544
+
545
+ result := make ([]* lifecycles.Phase , 0 , len (phases .Elements ()))
546
+
547
+ for _ , phaseElem := range phases .Elements () {
548
+ phaseObj := phaseElem .(types.Object )
549
+ phaseAttrs := phaseObj .Attributes ()
550
+
551
+ phase := & lifecycles.Phase {}
552
+
553
+ if v , ok := phaseAttrs ["id" ].(types.String ); ok && ! v .IsNull () {
554
+ phase .ID = v .ValueString ()
555
+ }
556
+
557
+ if v , ok := phaseAttrs ["name" ].(types.String ); ok && ! v .IsNull () {
558
+ phase .Name = v .ValueString ()
559
+ }
560
+
561
+ if v , ok := phaseAttrs ["automatic_deployment_targets" ].(types.List ); ok && ! v .IsNull () {
562
+ phase .AutomaticDeploymentTargets = util .ExpandStringList (v )
563
+ }
564
+
565
+ if v , ok := phaseAttrs ["optional_deployment_targets" ].(types.List ); ok && ! v .IsNull () {
566
+ phase .OptionalDeploymentTargets = util .ExpandStringList (v )
567
+ }
568
+
569
+ if v , ok := phaseAttrs ["minimum_environments_before_promotion" ].(types.Int64 ); ok && ! v .IsNull () {
570
+ phase .MinimumEnvironmentsBeforePromotion = int32 (v .ValueInt64 ())
571
+ }
572
+
573
+ if v , ok := phaseAttrs ["is_optional_phase" ].(types.Bool ); ok && ! v .IsNull () {
574
+ phase .IsOptionalPhase = v .ValueBool ()
575
+ }
576
+
577
+ if v , ok := phaseAttrs ["is_priority_phase" ].(types.Bool ); ok && ! v .IsNull () {
578
+ phase .IsPriorityPhase = v .ValueBool ()
579
+ }
580
+
581
+ if v , ok := phaseAttrs ["release_retention_with_strategy" ].(types.List ); ok && ! v .IsNull () {
582
+ phase .ReleaseRetentionPolicy = expandRetentionWithStrategy (v )
583
+ }
584
+ if v , ok := phaseAttrs ["release_retention_with_strategy" ].(types.List ); ok && ! v .IsNull () {
585
+ phase .TentacleRetentionPolicy = expandRetentionWithStrategy (v )
586
+ }
587
+ result = append (result , phase )
525
588
}
526
- return expandRetentionWithStrategy (newRetention )
589
+
590
+ return result
527
591
}
592
+
528
593
func expandRetention (v types.List ) * core.RetentionPeriod {
529
594
if v .IsNull () || v .IsUnknown () || len (v .Elements ()) == 0 {
530
595
return nil
@@ -615,3 +680,19 @@ func getPhaseAttrTypes() map[string]attr.Type {
615
680
"tentacle_retention_with_strategy" : types.ListType {ElemType : types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()}},
616
681
}
617
682
}
683
+
684
+ func getPhaseWithStrategyAttrTypes () map [string ]attr.Type {
685
+ return map [string ]attr.Type {
686
+ "id" : types .StringType ,
687
+ "name" : types .StringType ,
688
+ "automatic_deployment_targets" : types.ListType {ElemType : types .StringType },
689
+ "optional_deployment_targets" : types.ListType {ElemType : types .StringType },
690
+ "minimum_environments_before_promotion" : types .Int64Type ,
691
+ "is_optional_phase" : types .BoolType ,
692
+ "is_priority_phase" : types .BoolType ,
693
+ "release_retention_policy" : types.ListType {ElemType : types.ObjectType {AttrTypes : getRetentionAttrTypes ()}},
694
+ "tentacle_retention_policy" : types.ListType {ElemType : types.ObjectType {AttrTypes : getRetentionAttrTypes ()}},
695
+ "release_retention_with_strategy" : types.ListType {ElemType : types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()}},
696
+ "tentacle_retention_with_strategy" : types.ListType {ElemType : types.ObjectType {AttrTypes : getRetentionWithStrategyAttrTypes ()}},
697
+ }
698
+ }
0 commit comments