mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
Return the error from validateOverhead in RuntimeClass#Validate
This commit is contained in:
parent
6a2d0f67d1
commit
059243fbd2
@ -32,6 +32,7 @@ go_test(
|
|||||||
"//staging/src/k8s.io/api/node/v1beta1:go_default_library",
|
"//staging/src/k8s.io/api/node/v1beta1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
|
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/admission:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||||
|
@ -112,9 +112,10 @@ func (r *RuntimeClass) Validate(attributes admission.Attributes, o admission.Obj
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if utilfeature.DefaultFeatureGate.Enabled(features.PodOverhead) {
|
if utilfeature.DefaultFeatureGate.Enabled(features.PodOverhead) {
|
||||||
err = validateOverhead(attributes, pod, runtimeClass)
|
if err = validateOverhead(attributes, pod, runtimeClass); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -136,28 +137,17 @@ func (r *RuntimeClass) prepareObjects(attributes admission.Attributes) (pod *api
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get RuntimeClass object
|
// get RuntimeClass object
|
||||||
runtimeClass, err = r.getRuntimeClass(pod, pod.Spec.RuntimeClassName)
|
if pod.Spec.RuntimeClassName != nil {
|
||||||
if err != nil {
|
runtimeClass, err = r.runtimeClassLister.Get(*pod.Spec.RuntimeClassName)
|
||||||
return pod, nil, err
|
if err != nil {
|
||||||
|
return pod, nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the pod and runtimeClass. If no RuntimeClass is specified in PodSpec, runtimeClass will be nil
|
// return the pod and runtimeClass. If no RuntimeClass is specified in PodSpec, runtimeClass will be nil
|
||||||
return pod, runtimeClass, nil
|
return pod, runtimeClass, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRuntimeClass will return a reference to the RuntimeClass object if it is found. If it cannot be found, or a RuntimeClassName
|
|
||||||
// is not provided in the pod spec, *node.RuntimeClass returned will be nil
|
|
||||||
func (r *RuntimeClass) getRuntimeClass(pod *api.Pod, runtimeClassName *string) (runtimeClass *v1beta1.RuntimeClass, err error) {
|
|
||||||
|
|
||||||
runtimeClass = nil
|
|
||||||
|
|
||||||
if runtimeClassName != nil {
|
|
||||||
runtimeClass, err = r.runtimeClassLister.Get(*runtimeClassName)
|
|
||||||
}
|
|
||||||
|
|
||||||
return runtimeClass, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func setOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.RuntimeClass) (err error) {
|
func setOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.RuntimeClass) (err error) {
|
||||||
|
|
||||||
if runtimeClass != nil {
|
if runtimeClass != nil {
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"k8s.io/api/node/v1beta1"
|
"k8s.io/api/node/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apiserver/pkg/admission"
|
"k8s.io/apiserver/pkg/admission"
|
||||||
"k8s.io/apiserver/pkg/authentication/user"
|
"k8s.io/apiserver/pkg/authentication/user"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
@ -154,9 +155,79 @@ func TestSetOverhead(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
func NewObjectInterfacesForTest() admission.ObjectInterfaces {
|
||||||
|
scheme := runtime.NewScheme()
|
||||||
|
corev1.AddToScheme(scheme)
|
||||||
|
return admission.NewObjectInterfacesFromScheme(scheme)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidate(t *testing.T) {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodOverhead, true)()
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
runtimeClass *v1beta1.RuntimeClass
|
||||||
|
pod *core.Pod
|
||||||
|
expectError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "No Overhead in RunntimeClass, Overhead set in pod",
|
||||||
|
runtimeClass: &v1beta1.RuntimeClass{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||||
|
Handler: "bar",
|
||||||
|
},
|
||||||
|
pod: validPod("no-resource-req-no-overhead", 1, getGuaranteedRequirements(), true),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Non-matching Overheads",
|
||||||
|
runtimeClass: &v1beta1.RuntimeClass{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||||
|
Handler: "bar",
|
||||||
|
Overhead: &v1beta1.Overhead{
|
||||||
|
PodFixed: corev1.ResourceList{
|
||||||
|
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("10"),
|
||||||
|
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("10G"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pod: validPod("no-resource-req-no-overhead", 1, core.ResourceRequirements{}, true),
|
||||||
|
expectError: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Matching Overheads",
|
||||||
|
runtimeClass: &v1beta1.RuntimeClass{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||||
|
Handler: "bar",
|
||||||
|
Overhead: &v1beta1.Overhead{
|
||||||
|
PodFixed: corev1.ResourceList{
|
||||||
|
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||||
|
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pod: validPod("no-resource-req-no-overhead", 1, core.ResourceRequirements{}, false),
|
||||||
|
expectError: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rt := NewRuntimeClass()
|
||||||
|
o := NewObjectInterfacesForTest()
|
||||||
|
for _, tc := range tests {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
|
||||||
|
attrs := admission.NewAttributesRecord(tc.pod, nil, core.Kind("Pod").WithVersion("version"), tc.pod.Namespace, tc.pod.Name, core.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
|
||||||
|
|
||||||
|
errs := rt.Validate(attrs, o)
|
||||||
|
if tc.expectError {
|
||||||
|
assert.NotEmpty(t, errs)
|
||||||
|
} else {
|
||||||
|
assert.Empty(t, errs)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateOverhead(t *testing.T) {
|
func TestValidateOverhead(t *testing.T) {
|
||||||
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodOverhead, true)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodOverhead, true)()
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user