@@ -27,6 +27,11 @@ const (
2727 // The value is constrained to a reasonable upper bound of 200 for most production workloads.
2828 // Upper bound is enforced after adjusting for operator semantics.
2929 maxVMInstanceCapacity = 200
30+
31+ // minVMInstanceCapacity defines the minimum allowed VM instance capacity for SKU capacity requirements.
32+ // The Azure Capacity API requires capacity values greater than 0, so minimum is set to 1.
33+ // Lower bound is enforced after adjusting for operator semantics.
34+ minVMInstanceCapacity = 1
3035)
3136
3237// PropertyChecker provides Azure-specific property validation for member clusters.
@@ -48,8 +53,8 @@ func NewPropertyChecker(vmSizeRecommenderClient compute.AttributeBasedVMSizeReco
4853
4954// CheckIfMeetSKUCapacityRequirement validates whether a member cluster can meet the specified
5055// SKU capacity requirement. It extracts the required SKU and capacity from the property selector
51- // requirement and checks to determine if the cluster's Azure subscription
52- // and location can provision the requested VM instances.
56+ // requirement and checks whether the cluster's Azure subscription and location can provision
57+ // the requested VM instances.
5358//
5459// The cluster must have both Azure location and subscription ID labels configured.
5560// Returns true if the SKU capacity requirement can be met, false otherwise.
@@ -116,9 +121,8 @@ func (s *PropertyChecker) CheckIfMeetSKUCapacityRequirement(
116121// extractCapacityRequirements extracts the capacity value from a PropertySelectorRequirement.
117122// This function is specifically designed for Azure SKU capacity properties that follow the pattern:
118123// "kubernetes.azure.com/vm-sizes/{sku}/capacity"
119- // Returns the capacity if the requirement is valid;
120- // The capacity will be updated based on the configured operator as VMSizeRecommender API
121- // checks if the current allocatableCapacity > the requested capacity.
124+ // Returns the capacity value adjusted for the operator semantics, as the VMSizeRecommender API
125+ // checks whether current allocatable capacity is greater than the requested capacity.
122126func extractCapacityRequirements (req placementv1beta1.PropertySelectorRequirement ) (uint32 , error ) {
123127 if req .Operator != placementv1beta1 .PropertySelectorGreaterThan && req .Operator != placementv1beta1 .PropertySelectorGreaterThanOrEqualTo {
124128 return 0 , fmt .Errorf ("unsupported operator %q for SKU capacity property, only GreaterThan (Gt) and GreaterThanOrEqualTo (Ge) are supported" , req .Operator )
@@ -149,7 +153,9 @@ func validateCapacity(value string, operator placementv1beta1.PropertySelectorOp
149153
150154 capacity := uint32 (valueUint ) // capacity is >= 0 since it's parsed as uint.
151155
152- if operator == placementv1beta1 .PropertySelectorGreaterThanOrEqualTo && capacity > 0 {
156+ // Adjust capacity based on operator semantics for VMSizeRecommender API.
157+ // If operator is GreaterThanOrEqualTo, decrement capacity by 1 as the API checks for strictly greater than.
158+ if operator == placementv1beta1 .PropertySelectorGreaterThanOrEqualTo && capacity >= minVMInstanceCapacity {
153159 capacity -= 1
154160 }
155161
@@ -158,9 +164,10 @@ func validateCapacity(value string, operator placementv1beta1.PropertySelectorOp
158164 return 0 , fmt .Errorf ("capacity value %d exceeds maximum allowed value of %d" , capacity , maxVMInstanceCapacity )
159165 }
160166
161- // A capacity of zero is only valid for GreaterThan operator.
162- if capacity == 0 && operator != placementv1beta1 .PropertySelectorGreaterThan {
163- return 0 , fmt .Errorf ("capacity value cannot be zero for operator %q" , operator )
167+ // Ensure capacity meets minimum requirements (minVMInstanceCapacity) after operator adjustment.
168+ // The VMSizeRecommender API requires capacity > 0.
169+ if capacity < minVMInstanceCapacity {
170+ return 0 , fmt .Errorf ("capacity value cannot be below minimum %d after adjustment" , minVMInstanceCapacity )
164171 }
165172
166173 return capacity , nil
0 commit comments