feat: add resourcequota WarningsOnCreate request less than limits

Signed-off-by: rongfu.leng <lenronfu@gmail.com>
This commit is contained in:
rongfu.leng
2025-03-13 21:06:59 +08:00
committed by Tim Hockin
parent 9624c3dcdc
commit 79678dd393
2 changed files with 94 additions and 1 deletions

View File

@@ -18,6 +18,7 @@ package resourcequota
import (
"context"
"fmt"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/validation/field"
@@ -76,7 +77,26 @@ func (resourcequotaStrategy) Validate(ctx context.Context, obj runtime.Object) f
// WarningsOnCreate returns warnings for the creation of the given object.
func (resourcequotaStrategy) WarningsOnCreate(ctx context.Context, obj runtime.Object) []string {
return nil
resourcequota := obj.(*api.ResourceQuota)
allWarnings := make([]string, 0)
coreReosurces := []api.ResourceName{
api.ResourceCPU, api.ResourceMemory,
api.ResourceStorage, api.ResourceEphemeralStorage,
}
for _, resourceName := range coreReosurces {
requestResourceName := fmt.Sprintf("requests.%s", resourceName)
requestResource, requestOK := resourcequota.Spec.Hard[api.ResourceName(requestResourceName)]
if (resourceName == api.ResourceCPU || resourceName == api.ResourceMemory) && !requestOK {
requestResourceName = string(resourceName)
requestResource, requestOK = resourcequota.Spec.Hard[api.ResourceName(requestResourceName)]
}
limitResourceName := fmt.Sprintf("limits.%s", resourceName)
limitResource, limitOK := resourcequota.Spec.Hard[api.ResourceName(limitResourceName)]
if requestOK && limitOK && requestResource.Cmp(limitResource) == 1 {
allWarnings = append(allWarnings, fmt.Sprintf("Create ResourceQuota requests.%s: %s should be less than limits.%s: %s", resourceName, requestResource.String(), resourceName, limitResource.String()))
}
}
return allWarnings
}
// Canonicalize normalizes the object after validation.

View File

@@ -17,6 +17,8 @@ limitations under the License.
package resourcequota
import (
"context"
"reflect"
"testing"
"k8s.io/apimachinery/pkg/api/resource"
@@ -58,3 +60,74 @@ func TestResourceQuotaStrategy(t *testing.T) {
t.Errorf("ResourceQuota does not allow setting status on create")
}
}
func Test_WarningsOnCreate(t *testing.T) {
tests := []struct {
name string
args *api.ResourceQuota
wantWarnings []string
}{
{
name: "Empty Hard Spec",
args: &api.ResourceQuota{},
wantWarnings: []string{},
},
{
name: "Request less than limit",
args: &api.ResourceQuota{
Spec: api.ResourceQuotaSpec{
Hard: api.ResourceList{
api.ResourceName("requests.cpu"): resource.MustParse("500m"),
api.ResourceName("limits.cpu"): resource.MustParse("1"),
api.ResourceName("requests.memory"): resource.MustParse("1Gi"),
api.ResourceName("limits.memory"): resource.MustParse("2Gi"),
},
},
},
wantWarnings: []string{},
},
{
name: "Request greater than limit",
args: &api.ResourceQuota{
Spec: api.ResourceQuotaSpec{
Hard: api.ResourceList{
api.ResourceName("requests.cpu"): resource.MustParse("2"),
api.ResourceName("limits.cpu"): resource.MustParse("1"),
api.ResourceName("requests.memory"): resource.MustParse("3Gi"),
api.ResourceName("limits.memory"): resource.MustParse("2Gi"),
},
},
},
wantWarnings: []string{
"Create ResourceQuota requests.cpu: 2 should be less than limits.cpu: 1",
"Create ResourceQuota requests.memory: 3Gi should be less than limits.memory: 2Gi",
},
},
{
name: "Request greater than limit, and not requests",
args: &api.ResourceQuota{
Spec: api.ResourceQuotaSpec{
Hard: api.ResourceList{
api.ResourceName("cpu"): resource.MustParse("2"),
api.ResourceName("limits.cpu"): resource.MustParse("1"),
api.ResourceName("memory"): resource.MustParse("3Gi"),
api.ResourceName("limits.memory"): resource.MustParse("2Gi"),
},
},
},
wantWarnings: []string{
"Create ResourceQuota requests.cpu: 2 should be less than limits.cpu: 1",
"Create ResourceQuota requests.memory: 3Gi should be less than limits.memory: 2Gi",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
warnings := Strategy.WarningsOnCreate(context.Background(), tt.args)
if !reflect.DeepEqual(warnings, tt.wantWarnings) {
t.Errorf("WarningsOnCreate() warnings = %v, wantWarnings %v", warnings, tt.wantWarnings)
}
})
}
}