mirror of https://github.com/k3s-io/k3s
Only reject quota admission if status is missing relevant usage
parent
27cd2be49f
commit
bef996d0a4
|
@ -1098,10 +1098,12 @@ func TestAdmitBestEffortQuotaLimitIgnoresBurstable(t *testing.T) {
|
|||
func TestHasUsageStats(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
a corev1.ResourceQuota
|
||||
relevant []corev1.ResourceName
|
||||
expected bool
|
||||
}{
|
||||
"empty": {
|
||||
a: corev1.ResourceQuota{Status: corev1.ResourceQuotaStatus{Hard: corev1.ResourceList{}}},
|
||||
relevant: []corev1.ResourceName{corev1.ResourceMemory},
|
||||
expected: true,
|
||||
},
|
||||
"hard-only": {
|
||||
|
@ -1113,6 +1115,7 @@ func TestHasUsageStats(t *testing.T) {
|
|||
Used: corev1.ResourceList{},
|
||||
},
|
||||
},
|
||||
relevant: []corev1.ResourceName{corev1.ResourceMemory},
|
||||
expected: false,
|
||||
},
|
||||
"hard-used": {
|
||||
|
@ -1126,11 +1129,27 @@ func TestHasUsageStats(t *testing.T) {
|
|||
},
|
||||
},
|
||||
},
|
||||
relevant: []corev1.ResourceName{corev1.ResourceMemory},
|
||||
expected: true,
|
||||
},
|
||||
"hard-used-relevant": {
|
||||
a: corev1.ResourceQuota{
|
||||
Status: corev1.ResourceQuotaStatus{
|
||||
Hard: corev1.ResourceList{
|
||||
corev1.ResourceMemory: resource.MustParse("1Gi"),
|
||||
corev1.ResourcePods: resource.MustParse("1"),
|
||||
},
|
||||
Used: corev1.ResourceList{
|
||||
corev1.ResourceMemory: resource.MustParse("500Mi"),
|
||||
},
|
||||
},
|
||||
},
|
||||
relevant: []corev1.ResourceName{corev1.ResourceMemory},
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
for testName, testCase := range testCases {
|
||||
if result := hasUsageStats(&testCase.a); result != testCase.expected {
|
||||
if result := hasUsageStats(&testCase.a, testCase.relevant); result != testCase.expected {
|
||||
t.Errorf("%s expected: %v, actual: %v", testName, testCase.expected, result)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -460,8 +460,8 @@ func CheckRequest(quotas []corev1.ResourceQuota, a admission.Attributes, evaluat
|
|||
if err := evaluator.Constraints(restrictedResources, inputObject); err != nil {
|
||||
return nil, admission.NewForbidden(a, fmt.Errorf("failed quota: %s: %v", resourceQuota.Name, err))
|
||||
}
|
||||
if !hasUsageStats(&resourceQuota) {
|
||||
return nil, admission.NewForbidden(a, fmt.Errorf("status unknown for quota: %s", resourceQuota.Name))
|
||||
if !hasUsageStats(&resourceQuota, restrictedResources) {
|
||||
return nil, admission.NewForbidden(a, fmt.Errorf("status unknown for quota: %s, resources: %s", resourceQuota.Name, prettyPrintResourceNames(restrictedResources)))
|
||||
}
|
||||
interestingQuotaIndexes = append(interestingQuotaIndexes, i)
|
||||
localRestrictedResourcesSet := quota.ToSet(restrictedResources)
|
||||
|
@ -702,9 +702,13 @@ func prettyPrintResourceNames(a []corev1.ResourceName) string {
|
|||
return strings.Join(values, ",")
|
||||
}
|
||||
|
||||
// hasUsageStats returns true if for each hard constraint there is a value for its current usage
|
||||
func hasUsageStats(resourceQuota *corev1.ResourceQuota) bool {
|
||||
// hasUsageStats returns true if for each hard constraint in interestingResources there is a value for its current usage
|
||||
func hasUsageStats(resourceQuota *corev1.ResourceQuota, interestingResources []corev1.ResourceName) bool {
|
||||
interestingSet := quota.ToSet(interestingResources)
|
||||
for resourceName := range resourceQuota.Status.Hard {
|
||||
if !interestingSet.Has(string(resourceName)) {
|
||||
continue
|
||||
}
|
||||
if _, found := resourceQuota.Status.Used[resourceName]; !found {
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue