diff --git a/castai/resource_workload_scaling_policy.go b/castai/resource_workload_scaling_policy.go index fc5f6c1c..4f3470ad 100644 --- a/castai/resource_workload_scaling_policy.go +++ b/castai/resource_workload_scaling_policy.go @@ -19,6 +19,8 @@ import ( "github.com/castai/terraform-provider-castai/castai/sdk" ) +const minResourceMultiplierValue = 1.0 + var ( k8sNameRegex = regexp.MustCompile("^[a-z0-9A-Z][a-z0-9A-Z._-]{0,61}[a-z0-9A-Z]$") ) @@ -51,7 +53,7 @@ func resourceWorkloadScalingPolicy() *schema.Resource { "apply_type": { Type: schema.TypeString, Required: true, - Description: `Recommendation apply type. + Description: `Recommendation apply type. - IMMEDIATE - pods are restarted immediately when new recommendation is generated. - DEFERRED - pods are not restarted and recommendation values are applied during natural restarts only (new deployment, etc.)`, ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{"IMMEDIATE", "DEFERRED"}, false)), @@ -203,6 +205,37 @@ func workloadScalingPolicyResourceSchema(function string, overhead, minRecommend Optional: true, Description: "Max values for the recommendation, applies to every container. For memory - this is in MiB, for CPU - this is in cores.", }, + "limit": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Description: "Resource limit settings", + Elem: workloadScalingPolicyResourceLimitSchema(), + }, + }, + } +} + +func workloadScalingPolicyResourceLimitSchema() *schema.Resource { + return &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": { + Type: schema.TypeString, + Required: true, + Description: `Defines limit strategy type. + - NONE - removes the resource limit even if it was specified in the workload spec. + - MULTIPLIER - used to calculate the resource limit. The final value is determined by multiplying the resource request by the specified factor.`, + ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{"NONE", "MULTIPLIER"}, true)), // FIXME: any reason to be strict about it? + DiffSuppressFunc: func(k, oldValue, newValue string, d *schema.ResourceData) bool { // FIXME: + return strings.EqualFold(oldValue, newValue) + }, + }, + "multiplier": { + Type: schema.TypeFloat, + Optional: true, + Description: "Multiplier used to calculate the resource limit. It must be defined for the MULTIPLIER strategy.", + ValidateDiagFunc: validation.ToDiagFunc(validation.FloatAtLeast(minResourceMultiplierValue)), + }, }, } } @@ -375,19 +408,22 @@ func resourceWorkloadScalingPolicyDiff(_ context.Context, d *schema.ResourceDiff cpu := toWorkloadScalingPolicies(d.Get("cpu").([]interface{})[0].(map[string]interface{})) memory := toWorkloadScalingPolicies(d.Get("memory").([]interface{})[0].(map[string]interface{})) - if err := validateArgs(cpu, "cpu"); err != nil { + if err := validateResourcePolicy(cpu, "cpu"); err != nil { return err } - return validateArgs(memory, "memory") + return validateResourcePolicy(memory, "memory") } -func validateArgs(r sdk.WorkloadoptimizationV1ResourcePolicies, res string) error { +func validateResourcePolicy(r sdk.WorkloadoptimizationV1ResourcePolicies, res string) error { if r.Function == "QUANTILE" && len(r.Args) == 0 { return fmt.Errorf("field %q: QUANTILE function requires args to be provided", res) } if r.Function == "MAX" && len(r.Args) > 0 { return fmt.Errorf("field %q: MAX function doesn't accept any args", res) } + + // TODO: validate type and multiplier, once API is updated + return nil } @@ -449,10 +485,33 @@ func toWorkloadScalingPolicies(obj map[string]interface{}) sdk.Workloadoptimizat if v, ok := obj["max"].(float64); ok && v > 0 { out.Max = lo.ToPtr(v) } + if v, ok := obj["limit"].([]any); ok { + out.Limit = toWorkloadResourceLimit(v[0].(map[string]any)) + } return out } +func toWorkloadResourceLimit(obj map[string]any) *sdk.WorkloadoptimizationV1ResourceLimitStrategy { + if len(obj) == 0 { + return nil + } + + out := &sdk.WorkloadoptimizationV1ResourceLimitStrategy{} + // TODO: validate type and multiplier, once API is updated + if v, ok := obj["type"].(string); ok { + switch v { + case "NONE": + out.None = lo.ToPtr(true) + case "MULTIPLIER": + if v, ok := obj["multiplier"].(float64); ok && v > 0 { + out.Multiplier = lo.ToPtr(v) + } + } + } + return out +} + func toWorkloadScalingPoliciesMap(p sdk.WorkloadoptimizationV1ResourcePolicies) []map[string]interface{} { m := map[string]interface{}{ "function": p.Function, @@ -467,6 +526,22 @@ func toWorkloadScalingPoliciesMap(p sdk.WorkloadoptimizationV1ResourcePolicies) m["look_back_period_seconds"] = int(*p.LookBackPeriodSeconds) } + // TODO: change casting, once API is updated + if p.Limit != nil { + if p.Limit.None != nil { + m["limit"] = []map[string]any{ + {"type": "NONE"}, + } + } else if p.Limit.Multiplier != nil { + m["limit"] = []map[string]any{ + { + "type": "MULTIPLIER", + "multiplier": *p.Limit.Multiplier, + }, + } + } + } + return []map[string]interface{}{m} } diff --git a/castai/resource_workload_scaling_policy_test.go b/castai/resource_workload_scaling_policy_test.go index 26e26be9..8d774260 100644 --- a/castai/resource_workload_scaling_policy_test.go +++ b/castai/resource_workload_scaling_policy_test.go @@ -152,7 +152,7 @@ func scalingPolicyConfigUpdated(clusterName, projectID, name string) string { } memory_event { apply_type = "DEFERRED" - } + } anti_affinity { consider_anti_affinity = true } @@ -187,7 +187,7 @@ func testAccCheckScalingPolicyDestroy(s *terraform.State) error { return nil } -func Test_validateArgs(t *testing.T) { +func Test_validateResourcePolicy(t *testing.T) { tests := map[string]struct { args sdk.WorkloadoptimizationV1ResourcePolicies wantErr bool @@ -211,11 +211,14 @@ func Test_validateArgs(t *testing.T) { }, wantErr: true, }, + "should return error when no value is specified for the multiplier strategy": {}, + "should return error when the value is lower than 1 for the multiplier strategy": {}, + "should return error when a value is specified for the none strategy": {}, } for name, tt := range tests { t.Run(name, func(t *testing.T) { - if err := validateArgs(tt.args, ""); (err != nil) != tt.wantErr { - t.Errorf("validateArgs() error = %v, wantErr %v", err, tt.wantErr) + if err := validateResourcePolicy(tt.args, ""); (err != nil) != tt.wantErr { + t.Errorf("validateResourcePolicy() error = %v, wantErr %v", err, tt.wantErr) } }) } diff --git a/castai/sdk/api.gen.go b/castai/sdk/api.gen.go index 6d8204dd..f622a0c9 100644 --- a/castai/sdk/api.gen.go +++ b/castai/sdk/api.gen.go @@ -363,10 +363,16 @@ const ( WorkloadoptimizationV1ResourceConfigFunctionQUANTILE WorkloadoptimizationV1ResourceConfigFunction = "QUANTILE" ) +// Defines values for WorkloadoptimizationV1ResourceConfigOverridesFunction. +const ( + WorkloadoptimizationV1ResourceConfigOverridesFunctionMAX WorkloadoptimizationV1ResourceConfigOverridesFunction = "MAX" + WorkloadoptimizationV1ResourceConfigOverridesFunctionQUANTILE WorkloadoptimizationV1ResourceConfigOverridesFunction = "QUANTILE" +) + // Defines values for WorkloadoptimizationV1ResourcePoliciesFunction. const ( - WorkloadoptimizationV1ResourcePoliciesFunctionMAX WorkloadoptimizationV1ResourcePoliciesFunction = "MAX" - WorkloadoptimizationV1ResourcePoliciesFunctionQUANTILE WorkloadoptimizationV1ResourcePoliciesFunction = "QUANTILE" + MAX WorkloadoptimizationV1ResourcePoliciesFunction = "MAX" + QUANTILE WorkloadoptimizationV1ResourcePoliciesFunction = "QUANTILE" ) // CommitmentsAPIBatchDeleteCommitmentsRequest defines model for CommitmentsAPI_BatchDeleteCommitments_request. @@ -417,12 +423,13 @@ type RoleBindingIsTheRoleBindingToBeUpdated struct { // CreateServiceAccountKeyRequest is the request for creating a service account key. type ServiceAccountsAPICreateServiceAccountKeyRequest struct { - // Key is the readable version of the service account key. + // Key is the key to create. Key CastaiServiceaccountsV1beta1CreateServiceAccountKeyRequestKey `json:"key"` } // UpdateServiceAccountRequest is the request for updating a service account. type ServiceAccountsAPIUpdateServiceAccountRequest struct { + // ServiceAccount is the service account to be updated. ServiceAccount CastaiServiceaccountsV1beta1UpdateServiceAccountRequestServiceAccount `json:"serviceAccount"` } @@ -1617,9 +1624,9 @@ type CastaiRbacV1beta1UserSubject struct { Name *string `json:"name,omitempty"` } -// Key is the readable version of the service account key. +// Key is the key to create. type CastaiServiceaccountsV1beta1CreateServiceAccountKeyRequestKey struct { - // Active is the active state of the key. + // Active is the active state of the key. If not provided, the default is true. Active *bool `json:"active,omitempty"` // ExpiresAt is the expiration time of the key. @@ -1651,7 +1658,7 @@ type CastaiServiceaccountsV1beta1CreateServiceAccountKeyResponse struct { Token *string `json:"token,omitempty"` } -// ServiceAccounts is the readable version of the service accounts. +// ServiceAccounts is the service account to be created. type CastaiServiceaccountsV1beta1CreateServiceAccountRequestServiceAccount struct { // Description is the description of the role binding. Description *string `json:"description,omitempty"` @@ -1662,6 +1669,7 @@ type CastaiServiceaccountsV1beta1CreateServiceAccountRequestServiceAccount struc // CreateServiceAccountResponse is the response for creating a service account. type CastaiServiceaccountsV1beta1CreateServiceAccountResponse struct { + // Author is the author of the service account. Author *CastaiServiceaccountsV1beta1CreateServiceAccountResponseAuthor `json:"author,omitempty"` CreatedAt *time.Time `json:"createdAt,omitempty"` Description *string `json:"description,omitempty"` @@ -1670,7 +1678,7 @@ type CastaiServiceaccountsV1beta1CreateServiceAccountResponse struct { Name *string `json:"name,omitempty"` } -// CastaiServiceaccountsV1beta1CreateServiceAccountResponseAuthor defines model for castai.serviceaccounts.v1beta1.CreateServiceAccountResponse.Author. +// Author is the author of the service account. type CastaiServiceaccountsV1beta1CreateServiceAccountResponseAuthor struct { Email *string `json:"email,omitempty"` Id *string `json:"id,omitempty"` @@ -1787,7 +1795,7 @@ type CastaiServiceaccountsV1beta1UpdateServiceAccountKeyResponse struct { Prefix *string `json:"prefix,omitempty"` } -// CastaiServiceaccountsV1beta1UpdateServiceAccountRequestServiceAccount defines model for castai.serviceaccounts.v1beta1.UpdateServiceAccountRequest.ServiceAccount. +// ServiceAccount is the service account to be updated. type CastaiServiceaccountsV1beta1UpdateServiceAccountRequestServiceAccount struct { Description *string `json:"description,omitempty"` Name string `json:"name"` @@ -4023,6 +4031,13 @@ type WorkloadoptimizationV1ApplyType string // WorkloadoptimizationV1AssignScalingPolicyWorkloadsResponse defines model for workloadoptimization.v1.AssignScalingPolicyWorkloadsResponse. type WorkloadoptimizationV1AssignScalingPolicyWorkloadsResponse = map[string]interface{} +// WorkloadoptimizationV1ConfidenceSettings defines model for workloadoptimization.v1.ConfidenceSettings. +type WorkloadoptimizationV1ConfidenceSettings struct { + // Defines the confidence threshold that's enough to automatically optimize a given workload vertically. Value must be [0:1]. + // When not defined on scaling policy level or workload level, defaults to 0.9 (90%) confidence. + Threshold *float64 `json:"threshold"` +} + // WorkloadoptimizationV1ConfigurationChangedEventV2 defines model for workloadoptimization.v1.ConfigurationChangedEventV2. type WorkloadoptimizationV1ConfigurationChangedEventV2 struct { Current WorkloadoptimizationV1ConfigurationChangedV2 `json:"current"` @@ -4035,6 +4050,15 @@ type WorkloadoptimizationV1ConfigurationChangedV2 struct { WorkloadConfig WorkloadoptimizationV1WorkloadConfigV2 `json:"workloadConfig"` } +// WorkloadoptimizationV1Constraints defines model for workloadoptimization.v1.Constraints. +type WorkloadoptimizationV1Constraints struct { + // Defines the maximum value. For memory - this is in MiB, for CPU - this is in cores. + Max *float64 `json:"max"` + + // Defines the minimum value. For memory - this is in MiB, for CPU - this is in cores. + Min *float64 `json:"min"` +} + // WorkloadoptimizationV1Container defines model for workloadoptimization.v1.Container. type WorkloadoptimizationV1Container struct { // Name of the container. @@ -4057,6 +4081,14 @@ type WorkloadoptimizationV1ContainerConstraints struct { Memory *WorkloadoptimizationV1ResourceConfig `json:"memory,omitempty"` } +// WorkloadoptimizationV1ContainerConstraintsV2 defines model for workloadoptimization.v1.ContainerConstraintsV2. +type WorkloadoptimizationV1ContainerConstraintsV2 struct { + // Defines the container name for which the constraints are for. + ContainerName string `json:"containerName"` + Cpu *WorkloadoptimizationV1Constraints `json:"cpu,omitempty"` + Memory *WorkloadoptimizationV1Constraints `json:"memory,omitempty"` +} + // WorkloadoptimizationV1CpuMetrics defines model for workloadoptimization.v1.CpuMetrics. type WorkloadoptimizationV1CpuMetrics struct { TotalCpuCores []WorkloadoptimizationV1TimeSeriesMetric `json:"totalCpuCores"` @@ -4192,6 +4224,24 @@ type WorkloadoptimizationV1HPAConfigUpdate struct { MinReplicas *int32 `json:"minReplicas"` } +// WorkloadoptimizationV1HorizontalOverrides defines model for workloadoptimization.v1.HorizontalOverrides. +type WorkloadoptimizationV1HorizontalOverrides struct { + // Defines possible options for workload management. + // READ_ONLY - workload watched (metrics collected), but no actions may be performed by CAST AI. + // MANAGED - workload watched (metrics collected), CAST AI may perform actions on the workload. + ManagementOption *WorkloadoptimizationV1ManagementOption `json:"managementOption,omitempty"` + + // Max replicas a workload can have. + MaxReplicas int32 `json:"maxReplicas"` + + // Min replicas a workload can have. + MinReplicas int32 `json:"minReplicas"` + ScaleDown *WorkloadoptimizationV1ScalingBehaviour `json:"scaleDown,omitempty"` + + // Defines the window of time to make a horizontal scaling decision. + ShortAverageSeconds *int32 `json:"shortAverageSeconds"` +} + // WorkloadoptimizationV1InitiatedBy defines model for workloadoptimization.v1.InitiatedBy. type WorkloadoptimizationV1InitiatedBy struct { Email *string `json:"email"` @@ -4240,10 +4290,7 @@ type WorkloadoptimizationV1MemoryEventSettings struct { // WorkloadoptimizationV1NewWorkloadScalingPolicy defines model for workloadoptimization.v1.NewWorkloadScalingPolicy. type WorkloadoptimizationV1NewWorkloadScalingPolicy struct { - ApplyType WorkloadoptimizationV1ApplyType `json:"applyType"` - - // Confidence threshold used for evaluation if the recommendation should be applied. If not set, the default value(0.9) will be used. - ConfidenceThreshold *float64 `json:"confidenceThreshold"` + ApplyType WorkloadoptimizationV1ApplyType `json:"applyType"` Name string `json:"name"` RecommendationPolicies WorkloadoptimizationV1RecommendationPolicies `json:"recommendationPolicies"` } @@ -4276,6 +4323,8 @@ type WorkloadoptimizationV1RecommendationEventType string // WorkloadoptimizationV1RecommendationPolicies defines model for workloadoptimization.v1.RecommendationPolicies. type WorkloadoptimizationV1RecommendationPolicies struct { AntiAffinity *WorkloadoptimizationV1AntiAffinitySettings `json:"antiAffinity,omitempty"` + ApplyType WorkloadoptimizationV1ApplyType `json:"applyType"` + Confidence *WorkloadoptimizationV1ConfidenceSettings `json:"confidence,omitempty"` Cpu WorkloadoptimizationV1ResourcePolicies `json:"cpu"` Downscaling *WorkloadoptimizationV1DownscalingSettings `json:"downscaling,omitempty"` @@ -4341,6 +4390,38 @@ type WorkloadoptimizationV1ResourceConfig struct { // MAX - the max function. type WorkloadoptimizationV1ResourceConfigFunction string +// WorkloadoptimizationV1ResourceConfigOverrides defines model for workloadoptimization.v1.ResourceConfigOverrides. +type WorkloadoptimizationV1ResourceConfigOverrides struct { + // The threshold of when to apply the recommendation - when diff of current requests and recommendation is greater than this, apply the recommendation. + ApplyThreshold *float64 `json:"applyThreshold"` + + // The arguments for the function - i.e. for a quantile, this should be a [0, 1] float. + Args *[]string `json:"args,omitempty"` + + // The function which to use when calculating the resource recommendation. + // QUANTILE - the quantile function. + // MAX - the max function. + Function *WorkloadoptimizationV1ResourceConfigOverridesFunction `json:"function,omitempty"` + Limit *WorkloadoptimizationV1ResourceLimitStrategy `json:"limit,omitempty"` + + // Period of time over which the resource recommendation is calculated. + LookBackPeriodSeconds *int32 `json:"lookBackPeriodSeconds"` + + // Max values for the recommendation. For memory - this is in MiB, for CPU - this is in cores. + Max *float64 `json:"max"` + + // Min values for the recommendation. For memory - this is in MiB, for CPU - this is in cores. + Min *float64 `json:"min"` + + // The overhead for the recommendation, the formula is: (1 + overhead) * function(args). + Overhead *float64 `json:"overhead"` +} + +// The function which to use when calculating the resource recommendation. +// QUANTILE - the quantile function. +// MAX - the max function. +type WorkloadoptimizationV1ResourceConfigOverridesFunction string + // WorkloadoptimizationV1ResourceConfigUpdate defines model for workloadoptimization.v1.ResourceConfigUpdate. type WorkloadoptimizationV1ResourceConfigUpdate struct { // Max values for the recommendation. For memory - this is in MiB, for CPU - this is in cores. @@ -4417,6 +4498,12 @@ type WorkloadoptimizationV1Resources struct { Requests *WorkloadoptimizationV1ResourceQuantity `json:"requests,omitempty"` } +// WorkloadoptimizationV1ScalingBehaviour defines model for workloadoptimization.v1.ScalingBehaviour. +type WorkloadoptimizationV1ScalingBehaviour struct { + // Defines the minimum time to make a scaling decision after decision has been made. + StabilizationWindowSeconds *int32 `json:"stabilizationWindowSeconds"` +} + // WorkloadoptimizationV1ScalingPolicyAssigned defines model for workloadoptimization.v1.ScalingPolicyAssigned. type WorkloadoptimizationV1ScalingPolicyAssigned struct { Policy WorkloadoptimizationV1WorkloadScalingPolicy `json:"policy"` @@ -4477,10 +4564,7 @@ type WorkloadoptimizationV1UpdateWorkloadResponseV2 struct { // WorkloadoptimizationV1UpdateWorkloadScalingPolicy defines model for workloadoptimization.v1.UpdateWorkloadScalingPolicy. type WorkloadoptimizationV1UpdateWorkloadScalingPolicy struct { - ApplyType WorkloadoptimizationV1ApplyType `json:"applyType"` - - // Confidence threshold used for evaluation if the recommendation should be applied. If not set, the default value(0.9) will be used. - ConfidenceThreshold *float64 `json:"confidenceThreshold"` + ApplyType WorkloadoptimizationV1ApplyType `json:"applyType"` Name string `json:"name"` RecommendationPolicies WorkloadoptimizationV1RecommendationPolicies `json:"recommendationPolicies"` } @@ -4521,6 +4605,26 @@ type WorkloadoptimizationV1VPAConfigUpdate struct { MemoryEvent *WorkloadoptimizationV1MemoryEventSettings `json:"memoryEvent,omitempty"` } +// WorkloadoptimizationV1VerticalOverrides defines model for workloadoptimization.v1.VerticalOverrides. +type WorkloadoptimizationV1VerticalOverrides struct { + AntiAffinity *WorkloadoptimizationV1AntiAffinitySettings `json:"antiAffinity,omitempty"` + ApplyType *WorkloadoptimizationV1ApplyType `json:"applyType,omitempty"` + Confidence *WorkloadoptimizationV1ConfidenceSettings `json:"confidence,omitempty"` + + // Defines container specific overrides. + ContainerConstraints *[]WorkloadoptimizationV1ContainerConstraintsV2 `json:"containerConstraints,omitempty"` + Cpu *WorkloadoptimizationV1ResourceConfigOverrides `json:"cpu,omitempty"` + Downscaling *WorkloadoptimizationV1DownscalingSettings `json:"downscaling,omitempty"` + + // Defines possible options for workload management. + // READ_ONLY - workload watched (metrics collected), but no actions may be performed by CAST AI. + // MANAGED - workload watched (metrics collected), CAST AI may perform actions on the workload. + ManagementOption *WorkloadoptimizationV1ManagementOption `json:"managementOption,omitempty"` + Memory *WorkloadoptimizationV1ResourceConfigOverrides `json:"memory,omitempty"` + MemoryEvent *WorkloadoptimizationV1MemoryEventSettings `json:"memoryEvent,omitempty"` + Startup *WorkloadoptimizationV1StartupSettings `json:"startup,omitempty"` +} + // WorkloadoptimizationV1Workload defines model for workloadoptimization.v1.Workload. type WorkloadoptimizationV1Workload struct { // Annotations as defined on the workload manifest. These are annotations from the controller meta, not the pod meta. @@ -4561,11 +4665,13 @@ type WorkloadoptimizationV1Workload struct { Recommendation *WorkloadoptimizationV1WorkloadRecommendation `json:"recommendation,omitempty"` // The number of replicas the workload should have, as defined on the workload spec. - Replicas int32 `json:"replicas"` - ScalingPolicyId string `json:"scalingPolicyId"` - UpdatedAt time.Time `json:"updatedAt"` - Version string `json:"version"` - WorkloadConfigV2 WorkloadoptimizationV1WorkloadConfigV2 `json:"workloadConfigV2"` + Replicas int32 `json:"replicas"` + ScalingPolicyId string `json:"scalingPolicyId"` + ScalingPolicyName string `json:"scalingPolicyName"` + UpdatedAt time.Time `json:"updatedAt"` + Version string `json:"version"` + WorkloadConfigV2 WorkloadoptimizationV1WorkloadConfigV2 `json:"workloadConfigV2"` + WorkloadOverrides *WorkloadoptimizationV1WorkloadOverrides `json:"workloadOverrides,omitempty"` } // WorkloadoptimizationV1WorkloadConfigUpdateV2 defines model for workloadoptimization.v1.WorkloadConfigUpdateV2. @@ -4619,6 +4725,12 @@ type WorkloadoptimizationV1WorkloadMetrics struct { Pods WorkloadoptimizationV1PodMetrics `json:"pods"` } +// WorkloadoptimizationV1WorkloadOverrides defines model for workloadoptimization.v1.WorkloadOverrides. +type WorkloadoptimizationV1WorkloadOverrides struct { + Horizontal *WorkloadoptimizationV1HorizontalOverrides `json:"horizontal,omitempty"` + Vertical *WorkloadoptimizationV1VerticalOverrides `json:"vertical,omitempty"` +} + // WorkloadoptimizationV1WorkloadRecommendation defines model for workloadoptimization.v1.WorkloadRecommendation. type WorkloadoptimizationV1WorkloadRecommendation struct { // Defines the confidence of the recommendation. Value between 0 and 1. 1 means max confidence, 0 means no confidence. @@ -4652,7 +4764,6 @@ type WorkloadoptimizationV1WorkloadResourceConfigUpdate struct { type WorkloadoptimizationV1WorkloadScalingPolicy struct { ApplyType WorkloadoptimizationV1ApplyType `json:"applyType"` ClusterId string `json:"clusterId"` - ConfidenceThreshold float64 `json:"confidenceThreshold"` CreatedAt time.Time `json:"createdAt"` HasWorkloadsConfiguredByAnnotations bool `json:"hasWorkloadsConfiguredByAnnotations"` Id string `json:"id"` diff --git a/docs/resources/workload_scaling_policy.md b/docs/resources/workload_scaling_policy.md index 1f348f2a..8398af6b 100644 --- a/docs/resources/workload_scaling_policy.md +++ b/docs/resources/workload_scaling_policy.md @@ -54,7 +54,7 @@ resource "castai_workload_scaling_policy" "services" { ### Required -- `apply_type` (String) Recommendation apply type. +- `apply_type` (String) Recommendation apply type. - IMMEDIATE - pods are restarted immediately when new recommendation is generated. - DEFERRED - pods are not restarted and recommendation values are applied during natural restarts only (new deployment, etc.) - `cluster_id` (String) CAST AI cluster id @@ -85,11 +85,26 @@ Optional: - `apply_threshold` (Number) The threshold of when to apply the recommendation. Recommendation will be applied when diff of current requests and new recommendation is greater than set value - `args` (List of String) The arguments for the function - i.e. for `QUANTILE` this should be a [0, 1] float. `MAX` doesn't accept any args - `function` (String) The function used to calculate the resource recommendation. Supported values: `QUANTILE`, `MAX` +- `limit` (Block List, Max: 1) Resource limit settings (see [below for nested schema](#nestedblock--cpu--limit)) - `look_back_period_seconds` (Number) The look back period in seconds for the recommendation. - `max` (Number) Max values for the recommendation, applies to every container. For memory - this is in MiB, for CPU - this is in cores. - `min` (Number) Min values for the recommendation, applies to every container. For memory - this is in MiB, for CPU - this is in cores. - `overhead` (Number) Overhead for the recommendation, e.g. `0.1` will result in 10% higher recommendation + +### Nested Schema for `cpu.limit` + +Required: + +- `type` (String) Defines limit strategy type. + - NONE - removes the resource limit even if it was specified in the workload spec. + - MULTIPLIER - used to calculate the resource limit. The final value is determined by multiplying the resource request by the specified factor. + +Optional: + +- `multiplier` (Number) Multiplier used to calculate the resource limit. It must be defined for the MULTIPLIER strategy. + + ### Nested Schema for `memory` @@ -99,11 +114,26 @@ Optional: - `apply_threshold` (Number) The threshold of when to apply the recommendation. Recommendation will be applied when diff of current requests and new recommendation is greater than set value - `args` (List of String) The arguments for the function - i.e. for `QUANTILE` this should be a [0, 1] float. `MAX` doesn't accept any args - `function` (String) The function used to calculate the resource recommendation. Supported values: `QUANTILE`, `MAX` +- `limit` (Block List, Max: 1) Resource limit settings (see [below for nested schema](#nestedblock--memory--limit)) - `look_back_period_seconds` (Number) The look back period in seconds for the recommendation. - `max` (Number) Max values for the recommendation, applies to every container. For memory - this is in MiB, for CPU - this is in cores. - `min` (Number) Min values for the recommendation, applies to every container. For memory - this is in MiB, for CPU - this is in cores. - `overhead` (Number) Overhead for the recommendation, e.g. `0.1` will result in 10% higher recommendation + +### Nested Schema for `memory.limit` + +Required: + +- `type` (String) Defines limit strategy type. + - NONE - removes the resource limit even if it was specified in the workload spec. + - MULTIPLIER - used to calculate the resource limit. The final value is determined by multiplying the resource request by the specified factor. + +Optional: + +- `multiplier` (Number) Multiplier used to calculate the resource limit. It must be defined for the MULTIPLIER strategy. + + ### Nested Schema for `anti_affinity` diff --git a/examples/resources/castai_workload_scaling_policy/resource.tf b/examples/resources/castai_workload_scaling_policy/resource.tf index 339b24ce..1c4146bb 100644 --- a/examples/resources/castai_workload_scaling_policy/resource.tf +++ b/examples/resources/castai_workload_scaling_policy/resource.tf @@ -16,6 +16,10 @@ resource "castai_workload_scaling_policy" "services" { function = "MAX" overhead = 0.35 apply_threshold = 0.2 + limit { + type = "MULTIPLIER" + multiplier = 1.5 + } } startup { period_seconds = 240 @@ -29,4 +33,4 @@ resource "castai_workload_scaling_policy" "services" { anti_affinity { consider_anti_affinity = false } -} \ No newline at end of file +}