Skip to content

Commit 7bd7205

Browse files
committed
feat: Add rollout behavior to workload optimization scaling policy
1 parent 1b5986c commit 7bd7205

4 files changed

Lines changed: 100 additions & 0 deletions

File tree

castai/resource_workload_scaling_policy.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ const (
3636
FieldLimitStrategyType = "type"
3737
FieldLimitStrategyMultiplier = "multiplier"
3838
FieldConfidence = "confidence"
39+
FieldRolloutBehavior = "rollout_behavior"
40+
FieldType = "type"
41+
FieldRolloutBehaviorNoDisruptionType = "NO_DISRUPTION"
3942
FieldPredictiveScaling = "predictive_scaling"
4043
FieldConfidenceThreshold = "threshold"
4144
DeprecatedFieldApplyThreshold = "apply_threshold"
@@ -268,6 +271,23 @@ It can be either:
268271
},
269272
},
270273
},
274+
FieldRolloutBehavior: {
275+
Type: schema.TypeList,
276+
Optional: true,
277+
MaxItems: 1,
278+
Description: "Defines the rollout behavior used when applying recommendations.",
279+
Elem: &schema.Resource{
280+
Schema: map[string]*schema.Schema{
281+
FieldType: {
282+
Type: schema.TypeString,
283+
Required: true,
284+
Description: `Defines the rollout type to be used when applying recommendations.
285+
- NO_DISRUPTION - pods are restarted without causing service disruption.`,
286+
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{FieldRolloutBehaviorNoDisruptionType}, false)),
287+
},
288+
},
289+
},
290+
},
271291
},
272292
Timeouts: &schema.ResourceTimeout{
273293
Create: schema.DefaultTimeout(15 * time.Second),
@@ -544,6 +564,8 @@ func resourceWorkloadScalingPolicyCreate(ctx context.Context, d *schema.Resource
544564

545565
req.RecommendationPolicies.PredictiveScaling = toPredictiveScaling(toSection(d, FieldPredictiveScaling))
546566

567+
req.RecommendationPolicies.RolloutBehavior = toRolloutBehavior(toSection(d, FieldRolloutBehavior))
568+
547569
ar, err := toAssignmentRules(toSection(d, FieldAssignmentRules))
548570
if err != nil {
549571
return diag.FromErr(err)
@@ -627,6 +649,9 @@ func resourceWorkloadScalingPolicyRead(ctx context.Context, d *schema.ResourceDa
627649
if err := d.Set(FieldPredictiveScaling, toPredictiveScalingMap(sp.RecommendationPolicies.PredictiveScaling)); err != nil {
628650
return diag.FromErr(fmt.Errorf("setting predictive scaling: %w", err))
629651
}
652+
if err := d.Set(FieldRolloutBehavior, toRolloutBehaviorMap(sp.RecommendationPolicies.RolloutBehavior)); err != nil {
653+
return diag.FromErr(fmt.Errorf("setting rollout behavior: %w", err))
654+
}
630655

631656
if err := d.Set(FieldAssignmentRules, toAssignmentRulesMap(getResourceFrom(d, FieldAssignmentRules), sp.AssignmentRules)); err != nil {
632657
return diag.FromErr(fmt.Errorf("setting assignment rules: %w", err))
@@ -656,6 +681,7 @@ func resourceWorkloadScalingPolicyUpdate(ctx context.Context, d *schema.Resource
656681
FieldConfidence,
657682
FieldAssignmentRules,
658683
FieldPredictiveScaling,
684+
FieldRolloutBehavior,
659685
) {
660686
tflog.Info(ctx, "scaling policy up to date")
661687
return nil
@@ -690,6 +716,7 @@ func resourceWorkloadScalingPolicyUpdate(ctx context.Context, d *schema.Resource
690716
AntiAffinity: toAntiAffinity(toSection(d, "anti_affinity")),
691717
Confidence: toConfidence(toSection(d, FieldConfidence)),
692718
PredictiveScaling: toPredictiveScaling(toSection(d, FieldPredictiveScaling)),
719+
RolloutBehavior: toRolloutBehavior(toSection(d, FieldRolloutBehavior)),
693720
},
694721
}
695722

@@ -1250,6 +1277,31 @@ func toPredictiveScalingResource(m map[string]any) *sdk.WorkloadoptimizationV1Pr
12501277
return r
12511278
}
12521279

1280+
func toRolloutBehavior(m map[string]any) *sdk.WorkloadoptimizationV1RolloutBehaviorSettings {
1281+
if len(m) == 0 {
1282+
return nil
1283+
}
1284+
1285+
r := &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{}
1286+
if v, ok := m[FieldType].(string); ok && v != "" {
1287+
r.Type = lo.ToPtr(sdk.WorkloadoptimizationV1RolloutBehaviorType(v))
1288+
}
1289+
1290+
return r
1291+
}
1292+
1293+
func toRolloutBehaviorMap(s *sdk.WorkloadoptimizationV1RolloutBehaviorSettings) []map[string]any {
1294+
if s == nil {
1295+
return nil
1296+
}
1297+
1298+
return []map[string]any{
1299+
{
1300+
FieldType: s.Type,
1301+
},
1302+
}
1303+
}
1304+
12531305
func getWorkloadScalingPolicyByName(ctx context.Context, client sdk.ClientWithResponsesInterface, clusterID, name string) (*sdk.WorkloadoptimizationV1WorkloadScalingPolicy, error) {
12541306
list, err := client.WorkloadOptimizationAPIListWorkloadScalingPoliciesWithResponse(ctx, clusterID)
12551307
if checkErr := sdk.CheckOKResponse(list, err); checkErr != nil {

castai/resource_workload_scaling_policy_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
1212
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1313
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
14+
"github.com/samber/lo"
1415
"github.com/stretchr/testify/require"
1516

1617
"github.com/castai/terraform-provider-castai/castai/sdk"
@@ -108,6 +109,7 @@ func TestAccResourceWorkloadScalingPolicy(t *testing.T) {
108109
resource.TestCheckResourceAttr(resourceName, "assignment_rules.0.rules.1.workload.0.labels_expressions.0.key", "helm.sh/chart"),
109110
resource.TestCheckResourceAttr(resourceName, "assignment_rules.0.rules.1.workload.0.labels_expressions.0.operator", "DoesNotExist"),
110111
resource.TestCheckResourceAttr(resourceName, "predictive_scaling.0.cpu.0.enabled", "true"),
112+
resource.TestCheckResourceAttr(resourceName, "rollout_behavior.0.type", "NO_DISRUPTION"),
111113
),
112114
},
113115
},
@@ -221,6 +223,9 @@ func scalingPolicyConfigUpdated(clusterName, projectID, name string) string {
221223
enabled = true
222224
}
223225
}
226+
rollout_behavior {
227+
type = "NO_DISRUPTION"
228+
}
224229
cpu {
225230
function = "QUANTILE"
226231
overhead = 0.15
@@ -433,3 +438,30 @@ func Test_toPredictiveScaling(t *testing.T) {
433438
})
434439
}
435440
}
441+
442+
func Test_toRolloutBehavior(t *testing.T) {
443+
tests := map[string]struct {
444+
args map[string]any
445+
exp *sdk.WorkloadoptimizationV1RolloutBehaviorSettings
446+
}{
447+
"should return rollout behavior settings": {
448+
args: map[string]any{
449+
FieldType: FieldRolloutBehaviorNoDisruptionType,
450+
},
451+
exp: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
452+
Type: lo.ToPtr(sdk.NODISRUPTION),
453+
},
454+
},
455+
"should return nil on empty map": {
456+
args: map[string]any{},
457+
exp: nil,
458+
},
459+
}
460+
for name, tt := range tests {
461+
t.Run(name, func(t *testing.T) {
462+
r := require.New(t)
463+
got := toRolloutBehavior(tt.args)
464+
r.Equal(tt.exp, got)
465+
})
466+
}
467+
}

docs/resources/workload_scaling_policy.md

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/resources/castai_workload_scaling_policy/resource.tf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,7 @@ resource "castai_workload_scaling_policy" "services" {
6868
confidence {
6969
threshold = 0.9
7070
}
71+
rollout_behavior {
72+
type = "NO_DISRUPTION"
73+
}
7174
}

0 commit comments

Comments
 (0)