Commit 374e6316 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #50757 from NickrenREN/local-storage-limitrange

Automatic merge from submit-queue Add local ephemeral storage support in LimitRange **Special notes for your reviewer**: For a single local ephemeral storage resource xref #43607 **Release note**: ```release-note Add local ephemeral storage support to LimitRange ``` /assign @jingxu97 cc @ddysher
parents ad6c85ca 370e0bec
...@@ -3554,6 +3554,10 @@ func validateLimitRangeTypeName(value string, fldPath *field.Path) field.ErrorLi ...@@ -3554,6 +3554,10 @@ func validateLimitRangeTypeName(value string, fldPath *field.Path) field.ErrorLi
// Validate limit range resource name // Validate limit range resource name
// limit types (other than Pod/Container) could contain storage not just cpu or memory // limit types (other than Pod/Container) could contain storage not just cpu or memory
func validateLimitRangeResourceName(limitType api.LimitType, value string, fldPath *field.Path) field.ErrorList { func validateLimitRangeResourceName(limitType api.LimitType, value string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if value == string(api.ResourceEphemeralStorage) && !utilfeature.DefaultFeatureGate.Enabled(features.LocalStorageCapacityIsolation) {
return append(allErrs, field.Forbidden(fldPath, "ResourceEphemeralStorage field disabled by feature-gate for Resource LimitRange"))
}
switch limitType { switch limitType {
case api.LimitTypePod, api.LimitTypeContainer: case api.LimitTypePod, api.LimitTypeContainer:
return validateContainerResourceName(value, fldPath) return validateContainerResourceName(value, fldPath)
......
...@@ -8711,6 +8711,71 @@ func getStorageResourceList(storage string) api.ResourceList { ...@@ -8711,6 +8711,71 @@ func getStorageResourceList(storage string) api.ResourceList {
return res return res
} }
func getLocalStorageResourceList(ephemeralStorage string) api.ResourceList {
res := api.ResourceList{}
if ephemeralStorage != "" {
res[api.ResourceEphemeralStorage] = resource.MustParse(ephemeralStorage)
}
return res
}
func TestValidateLimitRangeForLocalStorage(t *testing.T) {
testCases := []struct {
name string
spec api.LimitRangeSpec
}{
{
name: "all-fields-valid",
spec: api.LimitRangeSpec{
Limits: []api.LimitRangeItem{
{
Type: api.LimitTypePod,
Max: getLocalStorageResourceList("10000Mi"),
Min: getLocalStorageResourceList("100Mi"),
MaxLimitRequestRatio: getLocalStorageResourceList(""),
},
{
Type: api.LimitTypeContainer,
Max: getLocalStorageResourceList("10000Mi"),
Min: getLocalStorageResourceList("100Mi"),
Default: getLocalStorageResourceList("500Mi"),
DefaultRequest: getLocalStorageResourceList("200Mi"),
MaxLimitRequestRatio: getLocalStorageResourceList(""),
},
},
},
},
}
// Enable alpha feature LocalStorageCapacityIsolation
err := utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=true")
if err != nil {
t.Errorf("Failed to enable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, testCase := range testCases {
limitRange := &api.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec}
if errs := ValidateLimitRange(limitRange); len(errs) != 0 {
t.Errorf("Case %v, unexpected error: %v", testCase.name, errs)
}
}
// Disable alpha feature LocalStorageCapacityIsolation
err = utilfeature.DefaultFeatureGate.Set("LocalStorageCapacityIsolation=false")
if err != nil {
t.Errorf("Failed to disable feature gate for LocalStorageCapacityIsolation: %v", err)
return
}
for _, testCase := range testCases {
limitRange := &api.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: testCase.name, Namespace: "foo"}, Spec: testCase.spec}
if errs := ValidateLimitRange(limitRange); len(errs) == 0 {
t.Errorf("Case %v, expected feature gate unable error but actually no error", testCase.name)
}
}
}
func TestValidateLimitRange(t *testing.T) { func TestValidateLimitRange(t *testing.T) {
successCases := []struct { successCases := []struct {
name string name string
...@@ -8905,7 +8970,7 @@ func TestValidateLimitRange(t *testing.T) { ...@@ -8905,7 +8970,7 @@ func TestValidateLimitRange(t *testing.T) {
}}, }},
"default value 2 is greater than max value 1", "default value 2 is greater than max value 1",
}, },
"invalid spec defaultrequest outside range": { "invalid spec default request outside range": {
api.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: api.LimitRangeSpec{ api.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: api.LimitRangeSpec{
Limits: []api.LimitRangeItem{ Limits: []api.LimitRangeItem{
{ {
...@@ -8918,7 +8983,7 @@ func TestValidateLimitRange(t *testing.T) { ...@@ -8918,7 +8983,7 @@ func TestValidateLimitRange(t *testing.T) {
}}, }},
"default request value 2 is greater than max value 1", "default request value 2 is greater than max value 1",
}, },
"invalid spec defaultrequest more than default": { "invalid spec default request more than default": {
api.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: api.LimitRangeSpec{ api.LimitRange{ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: "foo"}, Spec: api.LimitRangeSpec{
Limits: []api.LimitRangeItem{ Limits: []api.LimitRangeItem{
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment