diff --git a/pkg/apis/core/v1/helper/BUILD b/pkg/apis/core/v1/helper/BUILD index 0067d3d5270..1dcf5974ca1 100644 --- a/pkg/apis/core/v1/helper/BUILD +++ b/pkg/apis/core/v1/helper/BUILD @@ -13,7 +13,6 @@ go_test( deps = [ "//staging/src/k8s.io/api/core/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/labels:go_default_library", ], ) diff --git a/pkg/apis/core/v1/helper/helpers.go b/pkg/apis/core/v1/helper/helpers.go index 46db0bfae2b..d60ca300b09 100644 --- a/pkg/apis/core/v1/helper/helpers.go +++ b/pkg/apis/core/v1/helper/helpers.go @@ -17,7 +17,6 @@ limitations under the License. package helper import ( - "encoding/json" "fmt" "strings" @@ -389,19 +388,6 @@ func GetMatchingTolerations(taints []v1.Taint, tolerations []v1.Toleration) (boo return true, result } -// GetAvoidPodsFromNodeAnnotations scans the list of annotations and -// returns the pods that needs to be avoided for this node from scheduling -func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (v1.AvoidPods, error) { - var avoidPods v1.AvoidPods - if len(annotations) > 0 && annotations[v1.PreferAvoidPodsAnnotationKey] != "" { - err := json.Unmarshal([]byte(annotations[v1.PreferAvoidPodsAnnotationKey]), &avoidPods) - if err != nil { - return avoidPods, err - } - } - return avoidPods, nil -} - // GetPersistentVolumeClass returns StorageClassName. func GetPersistentVolumeClass(volume *v1.PersistentVolume) string { // Use beta annotation first diff --git a/pkg/apis/core/v1/helper/helpers_test.go b/pkg/apis/core/v1/helper/helpers_test.go index 0a455ee9627..fedff439840 100644 --- a/pkg/apis/core/v1/helper/helpers_test.go +++ b/pkg/apis/core/v1/helper/helpers_test.go @@ -23,7 +23,6 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" ) @@ -430,102 +429,6 @@ func TestTolerationsTolerateTaintsWithFilter(t *testing.T) { } } -func TestGetAvoidPodsFromNode(t *testing.T) { - controllerFlag := true - testCases := []struct { - node *v1.Node - expectValue v1.AvoidPods - expectErr bool - }{ - { - node: &v1.Node{}, - expectValue: v1.AvoidPods{}, - expectErr: false, - }, - { - node: &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - v1.PreferAvoidPodsAnnotationKey: ` - { - "preferAvoidPods": [ - { - "podSignature": { - "podController": { - "apiVersion": "v1", - "kind": "ReplicationController", - "name": "foo", - "uid": "abcdef123456", - "controller": true - } - }, - "reason": "some reason", - "message": "some message" - } - ] - }`, - }, - }, - }, - expectValue: v1.AvoidPods{ - PreferAvoidPods: []v1.PreferAvoidPodsEntry{ - { - PodSignature: v1.PodSignature{ - PodController: &metav1.OwnerReference{ - APIVersion: "v1", - Kind: "ReplicationController", - Name: "foo", - UID: "abcdef123456", - Controller: &controllerFlag, - }, - }, - Reason: "some reason", - Message: "some message", - }, - }, - }, - expectErr: false, - }, - { - node: &v1.Node{ - // Missing end symbol of "podController" and "podSignature" - ObjectMeta: metav1.ObjectMeta{ - Annotations: map[string]string{ - v1.PreferAvoidPodsAnnotationKey: ` - { - "preferAvoidPods": [ - { - "podSignature": { - "podController": { - "kind": "ReplicationController", - "apiVersion": "v1" - "reason": "some reason", - "message": "some message" - } - ] - }`, - }, - }, - }, - expectValue: v1.AvoidPods{}, - expectErr: true, - }, - } - - for i, tc := range testCases { - v, err := GetAvoidPodsFromNodeAnnotations(tc.node.Annotations) - if err == nil && tc.expectErr { - t.Errorf("[%v]expected error but got none.", i) - } - if err != nil && !tc.expectErr { - t.Errorf("[%v]did not expect error but got: %v", i, err) - } - if !reflect.DeepEqual(tc.expectValue, v) { - t.Errorf("[%v]expect value %v but got %v with %v", i, tc.expectValue, v, v.PreferAvoidPods[0].PodSignature.PodController.Controller) - } - } -} - func TestMatchTopologySelectorTerms(t *testing.T) { type args struct { topologySelectorTerms []v1.TopologySelectorTerm diff --git a/pkg/apis/core/validation/BUILD b/pkg/apis/core/validation/BUILD index 70d2bd71733..52f216fd462 100644 --- a/pkg/apis/core/validation/BUILD +++ b/pkg/apis/core/validation/BUILD @@ -41,6 +41,7 @@ go_library( "//staging/src/k8s.io/apimachinery/pkg/util/validation:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", + "//staging/src/k8s.io/component-helpers/scheduling/corev1:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/utils/net:go_default_library", ], diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index fd3477176a4..597bdebd9ef 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -45,6 +45,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation" "k8s.io/apimachinery/pkg/util/validation/field" utilfeature "k8s.io/apiserver/pkg/util/feature" + schedulinghelper "k8s.io/component-helpers/scheduling/corev1" apiservice "k8s.io/kubernetes/pkg/api/service" "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/core/helper" @@ -3501,7 +3502,7 @@ func ValidateTopologySelectorTerm(term core.TopologySelectorTerm, fldPath *field func ValidateAvoidPodsInNodeAnnotations(annotations map[string]string, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} - v1Avoids, err := v1helper.GetAvoidPodsFromNodeAnnotations(annotations) + v1Avoids, err := schedulinghelper.GetAvoidPodsFromNodeAnnotations(annotations) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("AvoidPods"), core.PreferAvoidPodsAnnotationKey, err.Error())) return allErrs diff --git a/pkg/scheduler/framework/plugins/nodepreferavoidpods/BUILD b/pkg/scheduler/framework/plugins/nodepreferavoidpods/BUILD index fb497b344f7..e29307ef31c 100644 --- a/pkg/scheduler/framework/plugins/nodepreferavoidpods/BUILD +++ b/pkg/scheduler/framework/plugins/nodepreferavoidpods/BUILD @@ -6,11 +6,11 @@ go_library( importpath = "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodepreferavoidpods", visibility = ["//visibility:public"], deps = [ - "//pkg/apis/core/v1/helper:go_default_library", "//pkg/scheduler/framework:go_default_library", "//staging/src/k8s.io/api/core/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/component-helpers/scheduling/corev1:go_default_library", ], ) diff --git a/pkg/scheduler/framework/plugins/nodepreferavoidpods/node_prefer_avoid_pods.go b/pkg/scheduler/framework/plugins/nodepreferavoidpods/node_prefer_avoid_pods.go index 55384e5b1bf..93438302f1f 100644 --- a/pkg/scheduler/framework/plugins/nodepreferavoidpods/node_prefer_avoid_pods.go +++ b/pkg/scheduler/framework/plugins/nodepreferavoidpods/node_prefer_avoid_pods.go @@ -23,7 +23,7 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" + v1helper "k8s.io/component-helpers/scheduling/corev1" "k8s.io/kubernetes/pkg/scheduler/framework" ) diff --git a/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers.go b/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers.go index 57f916c265b..a21aebbff4f 100644 --- a/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers.go +++ b/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers.go @@ -17,6 +17,8 @@ limitations under the License. package corev1 import ( + "encoding/json" + v1 "k8s.io/api/core/v1" "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" ) @@ -43,3 +45,16 @@ func MatchNodeSelectorTerms( } return nodeaffinity.NewLazyErrorNodeSelector(nodeSelector).Match(node) } + +// GetAvoidPodsFromNodeAnnotations scans the list of annotations and +// returns the pods that needs to be avoided for this node from scheduling +func GetAvoidPodsFromNodeAnnotations(annotations map[string]string) (v1.AvoidPods, error) { + var avoidPods v1.AvoidPods + if len(annotations) > 0 && annotations[v1.PreferAvoidPodsAnnotationKey] != "" { + err := json.Unmarshal([]byte(annotations[v1.PreferAvoidPodsAnnotationKey]), &avoidPods) + if err != nil { + return avoidPods, err + } + } + return avoidPods, nil +} diff --git a/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers_test.go b/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers_test.go index 8428038594d..f82ea7911dd 100644 --- a/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers_test.go +++ b/staging/src/k8s.io/component-helpers/scheduling/corev1/helpers_test.go @@ -17,6 +17,7 @@ limitations under the License. package corev1 import ( + "reflect" "testing" v1 "k8s.io/api/core/v1" @@ -545,3 +546,99 @@ func TestMatchNodeSelectorTermsStateless(t *testing.T) { }) } } + +func TestGetAvoidPodsFromNode(t *testing.T) { + controllerFlag := true + testCases := []struct { + node *v1.Node + expectValue v1.AvoidPods + expectErr bool + }{ + { + node: &v1.Node{}, + expectValue: v1.AvoidPods{}, + expectErr: false, + }, + { + node: &v1.Node{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + v1.PreferAvoidPodsAnnotationKey: ` + { + "preferAvoidPods": [ + { + "podSignature": { + "podController": { + "apiVersion": "v1", + "kind": "ReplicationController", + "name": "foo", + "uid": "abcdef123456", + "controller": true + } + }, + "reason": "some reason", + "message": "some message" + } + ] + }`, + }, + }, + }, + expectValue: v1.AvoidPods{ + PreferAvoidPods: []v1.PreferAvoidPodsEntry{ + { + PodSignature: v1.PodSignature{ + PodController: &metav1.OwnerReference{ + APIVersion: "v1", + Kind: "ReplicationController", + Name: "foo", + UID: "abcdef123456", + Controller: &controllerFlag, + }, + }, + Reason: "some reason", + Message: "some message", + }, + }, + }, + expectErr: false, + }, + { + node: &v1.Node{ + // Missing end symbol of "podController" and "podSignature" + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{ + v1.PreferAvoidPodsAnnotationKey: ` + { + "preferAvoidPods": [ + { + "podSignature": { + "podController": { + "kind": "ReplicationController", + "apiVersion": "v1" + "reason": "some reason", + "message": "some message" + } + ] + }`, + }, + }, + }, + expectValue: v1.AvoidPods{}, + expectErr: true, + }, + } + + for i, tc := range testCases { + v, err := GetAvoidPodsFromNodeAnnotations(tc.node.Annotations) + if err == nil && tc.expectErr { + t.Errorf("[%v]expected error but got none.", i) + } + if err != nil && !tc.expectErr { + t.Errorf("[%v]did not expect error but got: %v", i, err) + } + if !reflect.DeepEqual(tc.expectValue, v) { + t.Errorf("[%v]expect value %v but got %v with %v", i, tc.expectValue, v, v.PreferAvoidPods[0].PodSignature.PodController.Controller) + } + } +}