Skip to content

Commit a1719bb

Browse files
feat: config option to prefer one-by-one recommendation rollouts
- marking rollout behavior type optional
1 parent 8483bfc commit a1719bb

File tree

6 files changed

+213
-694
lines changed

6 files changed

+213
-694
lines changed

castai/resource_workload_scaling_policy.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const (
4545
FieldRolloutBehavior = "rollout_behavior"
4646
FieldRolloutBehaviorType = "type"
4747
FieldRolloutBehaviorNoDisruptionType = "NO_DISRUPTION"
48+
FieldRolloutBehaviorPreferOneByOneType = "prefer_one_by_one"
4849
FieldPredictiveScaling = "predictive_scaling"
4950
FieldConfidenceThreshold = "threshold"
5051
DeprecatedFieldApplyThreshold = "apply_threshold"
@@ -291,11 +292,16 @@ It can be either:
291292
Schema: map[string]*schema.Schema{
292293
FieldRolloutBehaviorType: {
293294
Type: schema.TypeString,
294-
Required: true,
295+
Optional: true,
295296
Description: `Defines the rollout type to be used when applying recommendations.
296297
- NO_DISRUPTION - pods are restarted without causing service disruption.`,
297298
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{FieldRolloutBehaviorNoDisruptionType}, false)),
298299
},
300+
FieldRolloutBehaviorPreferOneByOneType: {
301+
Type: schema.TypeBool,
302+
Optional: true,
303+
Description: `Defines if pods should be restarted one by one to avoid service disruption.`,
304+
},
299305
},
300306
},
301307
},
@@ -1358,20 +1364,37 @@ func toRolloutBehavior(m map[string]any) *sdk.WorkloadoptimizationV1RolloutBehav
13581364
if v, ok := m[FieldRolloutBehaviorType].(string); ok && v != "" {
13591365
r.Type = lo.ToPtr(sdk.WorkloadoptimizationV1RolloutBehaviorType(v))
13601366
}
1367+
if v, ok := m[FieldRolloutBehaviorPreferOneByOneType].(bool); ok {
1368+
r.PreferOneByOne = lo.ToPtr(v)
1369+
}
1370+
1371+
// If neither type nor prefer_one_by_one is set, return nil
1372+
if r.Type == nil && r.PreferOneByOne == nil {
1373+
return nil
1374+
}
13611375

13621376
return r
13631377
}
13641378

13651379
func toRolloutBehaviorMap(s *sdk.WorkloadoptimizationV1RolloutBehaviorSettings) []map[string]any {
1366-
if s == nil || s.Type == nil {
1380+
if s == nil {
13671381
return nil
13681382
}
13691383

1370-
return []map[string]any{
1371-
{
1372-
FieldRolloutBehaviorType: string(*s.Type),
1373-
},
1384+
// If neither type nor prefer_one_by_one is set, return nil
1385+
if s.Type == nil && s.PreferOneByOne == nil {
1386+
return nil
13741387
}
1388+
1389+
m := map[string]any{}
1390+
if s.Type != nil {
1391+
m[FieldRolloutBehaviorType] = string(*s.Type)
1392+
}
1393+
if s.PreferOneByOne != nil {
1394+
m[FieldRolloutBehaviorPreferOneByOneType] = *s.PreferOneByOne
1395+
}
1396+
1397+
return []map[string]any{m}
13751398
}
13761399

13771400
func getWorkloadScalingPolicyByName(ctx context.Context, client sdk.ClientWithResponsesInterface, clusterID, name string) (*sdk.WorkloadoptimizationV1WorkloadScalingPolicy, error) {

castai/resource_workload_scaling_policy_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,42 @@ func Test_toRolloutBehavior(t *testing.T) {
582582
Type: lo.ToPtr(sdk.NODISRUPTION),
583583
},
584584
},
585+
"should return rollout behavior settings with prefer_one_by_one": {
586+
args: map[string]any{
587+
FieldRolloutBehaviorType: FieldRolloutBehaviorNoDisruptionType,
588+
FieldRolloutBehaviorPreferOneByOneType: true,
589+
},
590+
exp: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
591+
Type: lo.ToPtr(sdk.NODISRUPTION),
592+
PreferOneByOne: lo.ToPtr(true),
593+
},
594+
},
595+
"should return rollout behavior settings with prefer_one_by_one false": {
596+
args: map[string]any{
597+
FieldRolloutBehaviorType: FieldRolloutBehaviorNoDisruptionType,
598+
FieldRolloutBehaviorPreferOneByOneType: false,
599+
},
600+
exp: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
601+
Type: lo.ToPtr(sdk.NODISRUPTION),
602+
PreferOneByOne: lo.ToPtr(false),
603+
},
604+
},
605+
"should return rollout behavior settings with only prefer_one_by_one": {
606+
args: map[string]any{
607+
FieldRolloutBehaviorPreferOneByOneType: true,
608+
},
609+
exp: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
610+
PreferOneByOne: lo.ToPtr(true),
611+
},
612+
},
613+
"should return nil when only prefer_one_by_one is false": {
614+
args: map[string]any{
615+
FieldRolloutBehaviorPreferOneByOneType: false,
616+
},
617+
exp: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
618+
PreferOneByOne: lo.ToPtr(false),
619+
},
620+
},
585621
"should return nil on empty map": {
586622
args: map[string]any{},
587623
exp: nil,
@@ -596,6 +632,83 @@ func Test_toRolloutBehavior(t *testing.T) {
596632
}
597633
}
598634

635+
func Test_toRolloutBehaviorMap(t *testing.T) {
636+
tests := map[string]struct {
637+
args *sdk.WorkloadoptimizationV1RolloutBehaviorSettings
638+
exp []map[string]any
639+
}{
640+
"should return rollout behavior map": {
641+
args: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
642+
Type: lo.ToPtr(sdk.NODISRUPTION),
643+
},
644+
exp: []map[string]any{
645+
{
646+
FieldRolloutBehaviorType: string(sdk.NODISRUPTION),
647+
},
648+
},
649+
},
650+
"should return rollout behavior map with prefer_one_by_one": {
651+
args: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
652+
Type: lo.ToPtr(sdk.NODISRUPTION),
653+
PreferOneByOne: lo.ToPtr(true),
654+
},
655+
exp: []map[string]any{
656+
{
657+
FieldRolloutBehaviorType: string(sdk.NODISRUPTION),
658+
FieldRolloutBehaviorPreferOneByOneType: true,
659+
},
660+
},
661+
},
662+
"should return rollout behavior map with prefer_one_by_one false": {
663+
args: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
664+
Type: lo.ToPtr(sdk.NODISRUPTION),
665+
PreferOneByOne: lo.ToPtr(false),
666+
},
667+
exp: []map[string]any{
668+
{
669+
FieldRolloutBehaviorType: string(sdk.NODISRUPTION),
670+
FieldRolloutBehaviorPreferOneByOneType: false,
671+
},
672+
},
673+
},
674+
"should return rollout behavior map with only prefer_one_by_one": {
675+
args: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
676+
PreferOneByOne: lo.ToPtr(true),
677+
},
678+
exp: []map[string]any{
679+
{
680+
FieldRolloutBehaviorPreferOneByOneType: true,
681+
},
682+
},
683+
},
684+
"should return rollout behavior map with only prefer_one_by_one false": {
685+
args: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{
686+
PreferOneByOne: lo.ToPtr(false),
687+
},
688+
exp: []map[string]any{
689+
{
690+
FieldRolloutBehaviorPreferOneByOneType: false,
691+
},
692+
},
693+
},
694+
"should return nil for nil input": {
695+
args: nil,
696+
exp: nil,
697+
},
698+
"should return nil for empty settings": {
699+
args: &sdk.WorkloadoptimizationV1RolloutBehaviorSettings{},
700+
exp: nil,
701+
},
702+
}
703+
for name, tt := range tests {
704+
t.Run(name, func(t *testing.T) {
705+
r := require.New(t)
706+
got := toRolloutBehaviorMap(tt.args)
707+
r.Equal(tt.exp, got)
708+
})
709+
}
710+
}
711+
599712
func Test_resourceWorkloadScalingPolicyCreate(t *testing.T) {
600713
organizationId := "63d2af53-9a42-4968-be1e-39316ebfd8d4"
601714
clusterId := "4e4cd9eb-82eb-407e-a926-e5fef81cab50"

0 commit comments

Comments
 (0)