Skip to content

Commit 945befd

Browse files
committed
feat: add confidence threshold to workload scaling policy
1 parent 1fe0630 commit 945befd

File tree

5 files changed

+94
-4
lines changed

5 files changed

+94
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.idea/
2+
.vscode/
23

34
# built binary
45
terraform-provider-castai

castai/resource_workload_scaling_policy.go

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,18 @@ const (
2525
minApplyThresholdValue = 0.01
2626
maxApplyThresholdValue = 2.5
2727
defaultApplyThresholdPercentage = 0.1
28+
defaultConfidenceThreshold = 0.9
2829
minNumeratorValue = 0.0
2930
maxExponentValue = 1.
3031
minExponentValue = 0.
3132
)
3233

3334
const (
34-
FieldLimitStrategy = "limit"
35-
FieldLimitStrategyType = "type"
36-
FieldLimitStrategyMultiplier = "multiplier"
37-
35+
FieldLimitStrategy = "limit"
36+
FieldLimitStrategyType = "type"
37+
FieldLimitStrategyMultiplier = "multiplier"
38+
FieldConfidence = "confidence"
39+
FieldConfidenceThreshold = "threshold"
3840
DeprecatedFieldApplyThreshold = "apply_threshold"
3941
FieldApplyThresholdStrategy = "apply_threshold_strategy"
4042
FieldApplyThresholdStrategyType = "type"
@@ -119,6 +121,26 @@ func resourceWorkloadScalingPolicy() *schema.Resource {
119121
},
120122
},
121123
},
124+
FieldConfidence: {
125+
Type: schema.TypeList,
126+
Optional: true,
127+
MaxItems: 1,
128+
Description: "Defines the confidence settings for applying recommendations.",
129+
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
130+
return suppressConfidenceThresholdDefaultValueDiff(FieldConfidence, old, new, d)
131+
},
132+
Elem: &schema.Resource{
133+
Schema: map[string]*schema.Schema{
134+
FieldConfidenceThreshold: {
135+
Type: schema.TypeFloat,
136+
Optional: true,
137+
Default: 0.9,
138+
Description: "Defines the confidence threshold for applying recommendations. The smaller number indicates that we require fewer metrics data points to apply recommendations.",
139+
ValidateDiagFunc: validation.ToDiagFunc(validation.FloatBetween(0, 1)),
140+
},
141+
},
142+
},
143+
},
122144
"downscaling": {
123145
Type: schema.TypeList,
124146
Optional: true,
@@ -381,6 +403,8 @@ func resourceWorkloadScalingPolicyCreate(ctx context.Context, d *schema.Resource
381403
}
382404
req.RecommendationPolicies.Memory = memory
383405
}
406+
407+
req.RecommendationPolicies.Confidence = toConfidence(toSection(d, FieldConfidence))
384408

385409
req.RecommendationPolicies.Startup = toStartup(toSection(d, "startup"))
386410

@@ -452,6 +476,9 @@ func resourceWorkloadScalingPolicyRead(ctx context.Context, d *schema.ResourceDa
452476
if err := d.Set("startup", toStartupMap(sp.RecommendationPolicies.Startup)); err != nil {
453477
return diag.FromErr(fmt.Errorf("setting startup: %w", err))
454478
}
479+
if err := d.Set(FieldConfidence, toConfidenceMap(sp.RecommendationPolicies.Confidence)); err != nil {
480+
return diag.FromErr(fmt.Errorf("setting confidence: %w", err))
481+
}
455482
if err := d.Set("downscaling", toDownscalingMap(sp.RecommendationPolicies.Downscaling)); err != nil {
456483
return diag.FromErr(fmt.Errorf("setting downscaling: %w", err))
457484
}
@@ -483,6 +510,7 @@ func resourceWorkloadScalingPolicyUpdate(ctx context.Context, d *schema.Resource
483510
"downscaling",
484511
"memory_event",
485512
"anti_affinity",
513+
FieldConfidence,
486514
) {
487515
tflog.Info(ctx, "scaling policy up to date")
488516
return nil
@@ -509,6 +537,7 @@ func resourceWorkloadScalingPolicyUpdate(ctx context.Context, d *schema.Resource
509537
Downscaling: toDownscaling(toSection(d, "downscaling")),
510538
MemoryEvent: toMemoryEvent(toSection(d, "memory_event")),
511539
AntiAffinity: toAntiAffinity(toSection(d, "anti_affinity")),
540+
Confidence: toConfidence(toSection(d, FieldConfidence)),
512541
},
513542
}
514543

@@ -740,6 +769,17 @@ func suppressThresholdStrategyDefaultValueDiff(resource, oldValue, newValue stri
740769
return oldValue == newValue
741770
}
742771

772+
func suppressConfidenceThresholdDefaultValueDiff(resource, oldValue, newValue string, d *schema.ResourceData) bool {
773+
isConfidenceUnset := newValue == "0" || newValue == ""
774+
if isConfidenceUnset {
775+
confidenceThreshold := d.Get(fmt.Sprintf("%s.0.%s", resource, FieldConfidenceThreshold))
776+
// Suppress diff if configuration saved from API equals to default
777+
return confidenceThreshold == defaultConfidenceThreshold
778+
}
779+
780+
return oldValue == newValue
781+
}
782+
743783
func toWorkloadResourceLimit(obj map[string]any) (*sdk.WorkloadoptimizationV1ResourceLimitStrategy, error) {
744784
if len(obj) == 0 {
745785
return nil, nil
@@ -852,6 +892,32 @@ func applyThresholdStrategyToMap(s *sdk.WorkloadoptimizationV1ApplyThresholdStra
852892
return []map[string]any{m}
853893
}
854894

895+
func toConfidence(confidence map[string]any) *sdk.WorkloadoptimizationV1ConfidenceSettings {
896+
if len(confidence) == 0 {
897+
return nil
898+
}
899+
900+
result := &sdk.WorkloadoptimizationV1ConfidenceSettings{}
901+
902+
if v, ok := confidence[FieldConfidenceThreshold].(float64); ok {
903+
result.Threshold = &v
904+
}
905+
906+
return result
907+
}
908+
909+
func toConfidenceMap(s *sdk.WorkloadoptimizationV1ConfidenceSettings) []map[string]any {
910+
if s == nil {
911+
return nil
912+
}
913+
914+
m := map[string]any{
915+
FieldConfidenceThreshold: s.Threshold,
916+
}
917+
918+
return []map[string]any{m}
919+
}
920+
855921
func toStartup(startup map[string]any) *sdk.WorkloadoptimizationV1StartupSettings {
856922
if len(startup) == 0 {
857923
return nil

castai/resource_workload_scaling_policy_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func TestAccResourceWorkloadScalingPolicy(t *testing.T) {
5252
resource.TestCheckResourceAttr(resourceName, "memory.0.limit.0.type", "MULTIPLIER"),
5353
resource.TestCheckResourceAttr(resourceName, "memory.0.limit.0.multiplier", "1.8"),
5454
resource.TestCheckResourceAttr(resourceName, "memory.0.management_option", "READ_ONLY"),
55+
resource.TestCheckResourceAttr(resourceName, "confidence.0.threshold", "0.4"),
5556
),
5657
},
5758
{
@@ -88,6 +89,7 @@ func TestAccResourceWorkloadScalingPolicy(t *testing.T) {
8889
resource.TestCheckResourceAttr(resourceName, "startup.0.period_seconds", "123"),
8990
resource.TestCheckResourceAttr(resourceName, "downscaling.0.apply_type", "DEFERRED"),
9091
resource.TestCheckResourceAttr(resourceName, "memory_event.0.apply_type", "DEFERRED"),
92+
resource.TestCheckResourceAttr(resourceName, "confidence.0.threshold", "0.6"),
9193
resource.TestCheckResourceAttr(resourceName, "anti_affinity.0.consider_anti_affinity", "true"),
9294
),
9395
},
@@ -112,6 +114,9 @@ func scalingPolicyConfig(clusterName, projectID, name string) string {
112114
cluster_id = castai_gke_cluster.test.id
113115
apply_type = "IMMEDIATE"
114116
management_option = "READ_ONLY"
117+
confidence {
118+
threshold = 0.4
119+
}
115120
cpu {
116121
function = "QUANTILE"
117122
overhead = 0.05
@@ -195,6 +200,9 @@ func scalingPolicyConfigUpdated(clusterName, projectID, name string) string {
195200
anti_affinity {
196201
consider_anti_affinity = true
197202
}
203+
confidence {
204+
threshold = 0.6
205+
}
198206
}`, updatedName)
199207

200208
return ConfigCompose(testAccGKEClusterConfig(name, clusterName, projectID), cfg)

docs/resources/workload_scaling_policy.md

Lines changed: 12 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
@@ -39,4 +39,7 @@ resource "castai_workload_scaling_policy" "services" {
3939
anti_affinity {
4040
consider_anti_affinity = false
4141
}
42+
confidence {
43+
threshold = 0.9
44+
}
4245
}

0 commit comments

Comments
 (0)