mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-15 06:01:50 +00:00
GA of RuntimeClass feature gate and API
This commit is contained in:
@@ -8,10 +8,10 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/node:go_default_library",
|
||||
"//pkg/apis/node/v1beta1:go_default_library",
|
||||
"//pkg/apis/node/v1:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/util/tolerations:go_default_library",
|
||||
"//staging/src/k8s.io/api/node/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/node/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/equality:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
@@ -19,8 +19,8 @@ go_library(
|
||||
"//staging/src/k8s.io/apiserver/pkg/admission/initializer:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/informers:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/node/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/node/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/typed/node/v1:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/listers/node/v1:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
|
||||
],
|
||||
)
|
||||
@@ -34,7 +34,7 @@ go_test(
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/node/v1beta1:go_default_library",
|
||||
"//staging/src/k8s.io/api/node/v1: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/runtime:go_default_library",
|
||||
|
@@ -17,7 +17,7 @@ limitations under the License.
|
||||
// Package runtimeclass contains an admission controller for modifying and validating new Pods to
|
||||
// take RuntimeClass into account. For RuntimeClass definitions which describe an overhead associated
|
||||
// with running a pod, this admission controller will set the pod.Spec.Overhead field accordingly. This
|
||||
// field should only be set through this controller, so vaidation will be carried out to ensure the pod's
|
||||
// field should only be set through this controller, so validation will be carried out to ensure the pod's
|
||||
// value matches what is defined in the coresponding RuntimeClass.
|
||||
package runtimeclass
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
v1beta1 "k8s.io/api/node/v1beta1"
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -34,12 +34,12 @@ import (
|
||||
genericadmissioninitailizer "k8s.io/apiserver/pkg/admission/initializer"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
nodev1beta1client "k8s.io/client-go/kubernetes/typed/node/v1beta1"
|
||||
nodev1beta1listers "k8s.io/client-go/listers/node/v1beta1"
|
||||
nodev1client "k8s.io/client-go/kubernetes/typed/node/v1"
|
||||
nodev1listers "k8s.io/client-go/listers/node/v1"
|
||||
"k8s.io/component-base/featuregate"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
node "k8s.io/kubernetes/pkg/apis/node"
|
||||
nodev1beta1 "k8s.io/kubernetes/pkg/apis/node/v1beta1"
|
||||
apinodev1 "k8s.io/kubernetes/pkg/apis/node/v1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/util/tolerations"
|
||||
)
|
||||
@@ -60,12 +60,11 @@ func Register(plugins *admission.Plugins) {
|
||||
// not specified, the pod is rejected.
|
||||
type RuntimeClass struct {
|
||||
*admission.Handler
|
||||
runtimeClassLister nodev1beta1listers.RuntimeClassLister
|
||||
runtimeClassClient nodev1beta1client.RuntimeClassInterface
|
||||
runtimeClassLister nodev1listers.RuntimeClassLister
|
||||
runtimeClassClient nodev1client.RuntimeClassInterface
|
||||
|
||||
inspectedFeatures bool
|
||||
runtimeClassEnabled bool
|
||||
podOverheadEnabled bool
|
||||
inspectedFeatures bool
|
||||
podOverheadEnabled bool
|
||||
}
|
||||
|
||||
var _ admission.MutationInterface = &RuntimeClass{}
|
||||
@@ -76,22 +75,18 @@ var _ genericadmissioninitailizer.WantsExternalKubeClientSet = &RuntimeClass{}
|
||||
|
||||
// SetExternalKubeClientSet sets the client for the plugin
|
||||
func (r *RuntimeClass) SetExternalKubeClientSet(client kubernetes.Interface) {
|
||||
r.runtimeClassClient = client.NodeV1beta1().RuntimeClasses()
|
||||
r.runtimeClassClient = client.NodeV1().RuntimeClasses()
|
||||
}
|
||||
|
||||
// InspectFeatureGates allows setting bools without taking a dep on a global variable
|
||||
func (r *RuntimeClass) InspectFeatureGates(featureGates featuregate.FeatureGate) {
|
||||
r.runtimeClassEnabled = featureGates.Enabled(features.RuntimeClass)
|
||||
r.podOverheadEnabled = featureGates.Enabled(features.PodOverhead)
|
||||
r.inspectedFeatures = true
|
||||
}
|
||||
|
||||
// SetExternalKubeInformerFactory implements the WantsExternalKubeInformerFactory interface.
|
||||
func (r *RuntimeClass) SetExternalKubeInformerFactory(f informers.SharedInformerFactory) {
|
||||
if !r.runtimeClassEnabled {
|
||||
return
|
||||
}
|
||||
runtimeClassInformer := f.Node().V1beta1().RuntimeClasses()
|
||||
runtimeClassInformer := f.Node().V1().RuntimeClasses()
|
||||
r.SetReadyFunc(runtimeClassInformer.Informer().HasSynced)
|
||||
r.runtimeClassLister = runtimeClassInformer.Lister()
|
||||
}
|
||||
@@ -101,9 +96,6 @@ func (r *RuntimeClass) ValidateInitialization() error {
|
||||
if !r.inspectedFeatures {
|
||||
return fmt.Errorf("InspectFeatureGates was not called")
|
||||
}
|
||||
if !r.runtimeClassEnabled {
|
||||
return nil
|
||||
}
|
||||
if r.runtimeClassLister == nil {
|
||||
return fmt.Errorf("missing RuntimeClass lister")
|
||||
}
|
||||
@@ -115,10 +107,6 @@ func (r *RuntimeClass) ValidateInitialization() error {
|
||||
|
||||
// Admit makes an admission decision based on the request attributes
|
||||
func (r *RuntimeClass) Admit(ctx context.Context, attributes admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if !r.runtimeClassEnabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
if shouldIgnore(attributes) {
|
||||
return nil
|
||||
@@ -143,10 +131,6 @@ func (r *RuntimeClass) Admit(ctx context.Context, attributes admission.Attribute
|
||||
|
||||
// Validate makes sure that pod adhere's to RuntimeClass's definition
|
||||
func (r *RuntimeClass) Validate(ctx context.Context, attributes admission.Attributes, o admission.ObjectInterfaces) error {
|
||||
if !r.runtimeClassEnabled {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ignore all calls to subresources or resources other than pods.
|
||||
if shouldIgnore(attributes) {
|
||||
return nil
|
||||
@@ -173,7 +157,7 @@ func NewRuntimeClass() *RuntimeClass {
|
||||
}
|
||||
|
||||
// prepareObjects returns pod and runtimeClass types from the given admission attributes
|
||||
func (r *RuntimeClass) prepareObjects(ctx context.Context, attributes admission.Attributes) (pod *api.Pod, runtimeClass *v1beta1.RuntimeClass, err error) {
|
||||
func (r *RuntimeClass) prepareObjects(ctx context.Context, attributes admission.Attributes) (pod *api.Pod, runtimeClass *nodev1.RuntimeClass, err error) {
|
||||
pod, ok := attributes.GetObject().(*api.Pod)
|
||||
if !ok {
|
||||
return nil, nil, apierrors.NewBadRequest("Resource was marked with kind Pod but was unable to be converted")
|
||||
@@ -197,14 +181,14 @@ func (r *RuntimeClass) prepareObjects(ctx context.Context, attributes admission.
|
||||
return pod, runtimeClass, err
|
||||
}
|
||||
|
||||
func setOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.RuntimeClass) (err error) {
|
||||
func setOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *nodev1.RuntimeClass) (err error) {
|
||||
if runtimeClass == nil || runtimeClass.Overhead == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// convert to internal type and assign to pod's Overhead
|
||||
nodeOverhead := &node.Overhead{}
|
||||
if err = nodev1beta1.Convert_v1beta1_Overhead_To_node_Overhead(runtimeClass.Overhead, nodeOverhead, nil); err != nil {
|
||||
if err = apinodev1.Convert_v1_Overhead_To_node_Overhead(runtimeClass.Overhead, nodeOverhead, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -218,14 +202,14 @@ func setOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.Run
|
||||
return nil
|
||||
}
|
||||
|
||||
func setScheduling(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.RuntimeClass) (err error) {
|
||||
func setScheduling(a admission.Attributes, pod *api.Pod, runtimeClass *nodev1.RuntimeClass) (err error) {
|
||||
if runtimeClass == nil || runtimeClass.Scheduling == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// convert to internal type and assign to pod's Scheduling
|
||||
nodeScheduling := &node.Scheduling{}
|
||||
if err = nodev1beta1.Convert_v1beta1_Scheduling_To_node_Scheduling(runtimeClass.Scheduling, nodeScheduling, nil); err != nil {
|
||||
if err = apinodev1.Convert_v1_Scheduling_To_node_Scheduling(runtimeClass.Scheduling, nodeScheduling, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -250,11 +234,11 @@ func setScheduling(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.R
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *v1beta1.RuntimeClass) (err error) {
|
||||
func validateOverhead(a admission.Attributes, pod *api.Pod, runtimeClass *nodev1.RuntimeClass) (err error) {
|
||||
if runtimeClass != nil && runtimeClass.Overhead != nil {
|
||||
// If the Overhead set doesn't match what is provided in the RuntimeClass definition, reject the pod
|
||||
nodeOverhead := &node.Overhead{}
|
||||
if err := nodev1beta1.Convert_v1beta1_Overhead_To_node_Overhead(runtimeClass.Overhead, nodeOverhead, nil); err != nil {
|
||||
if err := apinodev1.Convert_v1_Overhead_To_node_Overhead(runtimeClass.Overhead, nodeOverhead, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if !apiequality.Semantic.DeepEqual(nodeOverhead.PodFixed, pod.Spec.Overhead) {
|
||||
|
@@ -23,7 +23,7 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/api/node/v1beta1"
|
||||
nodev1 "k8s.io/api/node/v1"
|
||||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -86,17 +86,17 @@ func getGuaranteedRequirements() core.ResourceRequirements {
|
||||
func TestSetOverhead(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
runtimeClass *v1beta1.RuntimeClass
|
||||
runtimeClass *nodev1.RuntimeClass
|
||||
pod *core.Pod
|
||||
expectError bool
|
||||
expectedPod *core.Pod
|
||||
}{
|
||||
{
|
||||
name: "overhead, no container requirements",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||
@@ -109,10 +109,10 @@ func TestSetOverhead(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "overhead, guaranteed pod",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||
@@ -125,10 +125,10 @@ func TestSetOverhead(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "overhead, pod with differing overhead already set",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("10"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("10G"),
|
||||
@@ -141,10 +141,10 @@ func TestSetOverhead(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "overhead, pod with same overhead already set",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||
@@ -175,14 +175,14 @@ func TestSetOverhead(t *testing.T) {
|
||||
func TestSetScheduling(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
runtimeClass *v1beta1.RuntimeClass
|
||||
runtimeClass *nodev1.RuntimeClass
|
||||
pod *core.Pod
|
||||
expectError bool
|
||||
expectedPod *core.Pod
|
||||
}{
|
||||
{
|
||||
name: "scheduling, nil scheduling",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Scheduling: nil,
|
||||
@@ -193,10 +193,10 @@ func TestSetScheduling(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "scheduling, conflict node selector",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Scheduling: &v1beta1.Scheduling{
|
||||
Scheduling: &nodev1.Scheduling{
|
||||
NodeSelector: map[string]string{
|
||||
"foo": "conflict",
|
||||
},
|
||||
@@ -207,10 +207,10 @@ func TestSetScheduling(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "scheduling, nil node selector",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Scheduling: &v1beta1.Scheduling{
|
||||
Scheduling: &nodev1.Scheduling{
|
||||
NodeSelector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
@@ -222,10 +222,10 @@ func TestSetScheduling(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "scheduling, node selector with the same key value",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Scheduling: &v1beta1.Scheduling{
|
||||
Scheduling: &nodev1.Scheduling{
|
||||
NodeSelector: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
@@ -237,10 +237,10 @@ func TestSetScheduling(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "scheduling, node selector with different key value",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Scheduling: &v1beta1.Scheduling{
|
||||
Scheduling: &nodev1.Scheduling{
|
||||
NodeSelector: map[string]string{
|
||||
"foo": "bar",
|
||||
"fizz": "buzz",
|
||||
@@ -253,10 +253,10 @@ func TestSetScheduling(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "scheduling, multiple tolerations",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Scheduling: &v1beta1.Scheduling{
|
||||
Scheduling: &nodev1.Scheduling{
|
||||
Tolerations: []v1.Toleration{
|
||||
{
|
||||
Key: "foo",
|
||||
@@ -322,18 +322,17 @@ func NewObjectInterfacesForTest() admission.ObjectInterfaces {
|
||||
return admission.NewObjectInterfacesFromScheme(scheme)
|
||||
}
|
||||
|
||||
func newRuntimeClassForTest(runtimeClassEnabled bool,
|
||||
func newRuntimeClassForTest(
|
||||
featureInspection bool,
|
||||
addLister bool,
|
||||
listerObject *v1beta1.RuntimeClass,
|
||||
listerObject *nodev1.RuntimeClass,
|
||||
addClient bool,
|
||||
clientObject *v1beta1.RuntimeClass) *RuntimeClass {
|
||||
clientObject *nodev1.RuntimeClass) *RuntimeClass {
|
||||
runtimeClass := NewRuntimeClass()
|
||||
|
||||
if featureInspection {
|
||||
relevantFeatures := map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
features.RuntimeClass: {Default: runtimeClassEnabled},
|
||||
features.PodOverhead: {Default: false},
|
||||
features.PodOverhead: {Default: false},
|
||||
}
|
||||
fg := featuregate.NewFeatureGate()
|
||||
fg.Add(relevantFeatures)
|
||||
@@ -344,7 +343,7 @@ func newRuntimeClassForTest(runtimeClassEnabled bool,
|
||||
informerFactory := informers.NewSharedInformerFactory(nil, controller.NoResyncPeriodFunc())
|
||||
runtimeClass.SetExternalKubeInformerFactory(informerFactory)
|
||||
if listerObject != nil {
|
||||
informerFactory.Node().V1beta1().RuntimeClasses().Informer().GetStore().Add(listerObject)
|
||||
informerFactory.Node().V1().RuntimeClasses().Informer().GetStore().Add(listerObject)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,30 +366,25 @@ func TestValidateInitialization(t *testing.T) {
|
||||
expectError bool
|
||||
runtimeClass *RuntimeClass
|
||||
}{
|
||||
{
|
||||
name: "runtimeClass disabled, success",
|
||||
expectError: false,
|
||||
runtimeClass: newRuntimeClassForTest(false, true, true, nil, true, nil),
|
||||
},
|
||||
{
|
||||
name: "runtimeClass enabled, success",
|
||||
expectError: false,
|
||||
runtimeClass: newRuntimeClassForTest(true, true, true, nil, true, nil),
|
||||
runtimeClass: newRuntimeClassForTest(true, true, nil, true, nil),
|
||||
},
|
||||
{
|
||||
name: "runtimeClass enabled, no feature inspection",
|
||||
expectError: true,
|
||||
runtimeClass: newRuntimeClassForTest(true, false, true, nil, true, nil),
|
||||
runtimeClass: newRuntimeClassForTest(false, true, nil, true, nil),
|
||||
},
|
||||
{
|
||||
name: "runtimeClass enabled, no lister",
|
||||
expectError: true,
|
||||
runtimeClass: newRuntimeClassForTest(true, true, false, nil, true, nil),
|
||||
runtimeClass: newRuntimeClassForTest(true, false, nil, true, nil),
|
||||
},
|
||||
{
|
||||
name: "runtimeClass enabled, no client",
|
||||
expectError: true,
|
||||
runtimeClass: newRuntimeClassForTest(true, true, true, nil, false, nil),
|
||||
runtimeClass: newRuntimeClassForTest(true, true, nil, false, nil),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -409,7 +403,7 @@ func TestValidateInitialization(t *testing.T) {
|
||||
func TestAdmit(t *testing.T) {
|
||||
runtimeClassName := "runtimeClassName"
|
||||
|
||||
rc := &v1beta1.RuntimeClass{
|
||||
rc := &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: runtimeClassName},
|
||||
}
|
||||
|
||||
@@ -440,17 +434,17 @@ func TestAdmit(t *testing.T) {
|
||||
{
|
||||
name: "runtimeClass found by lister",
|
||||
expectError: false,
|
||||
runtimeClass: newRuntimeClassForTest(true, true, true, rc, true, nil),
|
||||
runtimeClass: newRuntimeClassForTest(true, true, rc, true, nil),
|
||||
},
|
||||
{
|
||||
name: "runtimeClass found by client",
|
||||
expectError: false,
|
||||
runtimeClass: newRuntimeClassForTest(true, true, true, nil, true, rc),
|
||||
runtimeClass: newRuntimeClassForTest(true, true, nil, true, rc),
|
||||
},
|
||||
{
|
||||
name: "runtimeClass not found by lister nor client",
|
||||
expectError: true,
|
||||
runtimeClass: newRuntimeClassForTest(true, true, true, nil, true, nil),
|
||||
runtimeClass: newRuntimeClassForTest(true, true, nil, true, nil),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -469,13 +463,13 @@ func TestAdmit(t *testing.T) {
|
||||
func TestValidate(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
runtimeClass *v1beta1.RuntimeClass
|
||||
runtimeClass *nodev1.RuntimeClass
|
||||
pod *core.Pod
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "No Overhead in RunntimeClass, Overhead set in pod",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
},
|
||||
@@ -484,10 +478,10 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Non-matching Overheads",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("10"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("10G"),
|
||||
@@ -499,10 +493,10 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Matching Overheads",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||
@@ -514,7 +508,6 @@ func TestValidate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
rt := NewRuntimeClass()
|
||||
rt.runtimeClassEnabled = true
|
||||
rt.podOverheadEnabled = true
|
||||
o := NewObjectInterfacesForTest()
|
||||
for _, tc := range tests {
|
||||
@@ -535,16 +528,16 @@ func TestValidate(t *testing.T) {
|
||||
func TestValidateOverhead(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
runtimeClass *v1beta1.RuntimeClass
|
||||
runtimeClass *nodev1.RuntimeClass
|
||||
pod *core.Pod
|
||||
expectError bool
|
||||
}{
|
||||
{
|
||||
name: "Overhead part of RuntimeClass, no Overhead defined in pod",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||
@@ -556,7 +549,7 @@ func TestValidateOverhead(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "No Overhead in RunntimeClass, Overhead set in pod",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
},
|
||||
@@ -571,10 +564,10 @@ func TestValidateOverhead(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Non-matching Overheads",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("10"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("10G"),
|
||||
@@ -586,10 +579,10 @@ func TestValidateOverhead(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Matching Overheads",
|
||||
runtimeClass: &v1beta1.RuntimeClass{
|
||||
runtimeClass: &nodev1.RuntimeClass{
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "foo"},
|
||||
Handler: "bar",
|
||||
Overhead: &v1beta1.Overhead{
|
||||
Overhead: &nodev1.Overhead{
|
||||
PodFixed: corev1.ResourceList{
|
||||
corev1.ResourceName(corev1.ResourceCPU): resource.MustParse("100m"),
|
||||
corev1.ResourceName(corev1.ResourceMemory): resource.MustParse("1"),
|
||||
|
@@ -175,9 +175,7 @@ func NodeRules() []rbacv1.PolicyRule {
|
||||
}
|
||||
|
||||
// RuntimeClass
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.RuntimeClass) {
|
||||
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get", "list", "watch").Groups("node.k8s.io").Resources("runtimeclasses").RuleOrDie())
|
||||
}
|
||||
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get", "list", "watch").Groups("node.k8s.io").Resources("runtimeclasses").RuleOrDie())
|
||||
return nodePolicyRules
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user