From 0734820279ccce8c6034d9d122392fe3a0c7535e Mon Sep 17 00:00:00 2001 From: h4ghhh <51307338+h4ghhh@users.noreply.github.com> Date: Thu, 16 Sep 2021 19:29:45 +0800 Subject: [PATCH] 'New' Event namespace validate failed (#100125) --- pkg/apis/core/validation/events.go | 4 +- test/integration/client/client_test.go | 220 +++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 2 deletions(-) diff --git a/pkg/apis/core/validation/events.go b/pkg/apis/core/validation/events.go index 91b3ffb8231..adb0177b7a5 100644 --- a/pkg/apis/core/validation/events.go +++ b/pkg/apis/core/validation/events.go @@ -21,7 +21,7 @@ import ( "reflect" "time" - "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" eventsv1beta1 "k8s.io/api/events/v1beta1" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -140,7 +140,7 @@ func legacyValidateEvent(event *core.Event) field.ErrorList { } } else { - if len(event.InvolvedObject.Namespace) == 0 && event.Namespace != metav1.NamespaceSystem { + if len(event.InvolvedObject.Namespace) == 0 && event.Namespace != metav1.NamespaceDefault && event.Namespace != metav1.NamespaceSystem { allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace")) } if len(event.ReportingController) == 0 { diff --git a/test/integration/client/client_test.go b/test/integration/client/client_test.go index 8b53a6a859c..6ecbde5c39d 100644 --- a/test/integration/client/client_test.go +++ b/test/integration/client/client_test.go @@ -22,6 +22,7 @@ import ( "log" "reflect" rt "runtime" + "strings" "sync" "testing" "time" @@ -29,6 +30,7 @@ import ( "github.com/google/go-cmp/cmp" appsv1 "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" + eventsv1 "k8s.io/api/events/v1" "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/resource" @@ -462,6 +464,224 @@ func TestAPIVersions(t *testing.T) { t.Errorf("Server does not support APIVersion used by client. Server supported APIVersions: '%v', client APIVersion: '%v'", versions, clientVersion) } +func TestEventValidation(t *testing.T) { + result := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd()) + defer result.TearDownFn() + + client := clientset.NewForConfigOrDie(result.ClientConfig) + + createNamespace := func(namespace string) string { + if namespace == "" { + namespace = metav1.NamespaceDefault + } + return namespace + } + + mkCoreEvent := func(ver string, ns string) *v1.Event { + name := fmt.Sprintf("%v-%v-event", ver, ns) + namespace := createNamespace(ns) + return &v1.Event{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + InvolvedObject: v1.ObjectReference{ + Namespace: ns, + Name: name, + }, + Count: 2, + Type: "Normal", + ReportingController: "test-controller", + ReportingInstance: "test-1", + Reason: fmt.Sprintf("event %v test", name), + Action: "Testing", + } + } + mkV1Event := func(ver string, ns string) *eventsv1.Event { + name := fmt.Sprintf("%v-%v-event", ver, ns) + namespace := createNamespace(ns) + return &eventsv1.Event{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Regarding: v1.ObjectReference{ + Namespace: ns, + Name: name, + }, + Series: &eventsv1.EventSeries{ + Count: 2, + LastObservedTime: metav1.MicroTime{Time: time.Now()}, + }, + Type: "Normal", + EventTime: metav1.MicroTime{Time: time.Now()}, + ReportingController: "test-controller", + ReportingInstance: "test-2", + Reason: fmt.Sprintf("event %v test", name), + Action: "Testing", + } + } + + testcases := []struct { + name string + namespace string + hasError bool + }{ + { + name: "Involved object is namespaced", + namespace: "kube-system", + hasError: false, + }, + { + name: "Involved object is cluster-scoped", + namespace: "", + hasError: false, + }, + } + + for _, test := range testcases { + // create test + oldEventObj := mkCoreEvent("corev1", test.namespace) + corev1Event, err := client.CoreV1().Events(oldEventObj.Namespace).Create(context.TODO(), oldEventObj, metav1.CreateOptions{}) + if err != nil && !test.hasError { + t.Errorf("%v, call Create failed, expect has error: %v, but got: %v", test.name, test.hasError, err) + } + newEventObj := mkV1Event("eventsv1", test.namespace) + eventsv1Event, err := client.EventsV1().Events(newEventObj.Namespace).Create(context.TODO(), newEventObj, metav1.CreateOptions{}) + if err != nil && !test.hasError { + t.Errorf("%v, call Create failed, expect has error: %v, but got: %v", test.name, test.hasError, err) + } + if corev1Event.Namespace != eventsv1Event.Namespace { + t.Errorf("%v, events created by different api client have different namespaces that isn't expected", test.name) + } + // update test + corev1Event.Count++ + corev1Event, err = client.CoreV1().Events(corev1Event.Namespace).Update(context.TODO(), corev1Event, metav1.UpdateOptions{}) + if err != nil && !test.hasError { + t.Errorf("%v, call Update failed, expect has error: %v, but got: %v", test.name, test.hasError, err) + } + eventsv1Event.Series.Count++ + eventsv1Event.Series.LastObservedTime = metav1.MicroTime{Time: time.Now()} + eventsv1Event, err = client.EventsV1().Events(eventsv1Event.Namespace).Update(context.TODO(), eventsv1Event, metav1.UpdateOptions{}) + if err != nil && !test.hasError { + t.Errorf("%v, call Update failed, expect has error: %v, but got: %v", test.name, test.hasError, err) + } + if corev1Event.Namespace != eventsv1Event.Namespace { + t.Errorf("%v, events updated by different api client have different namespaces that isn't expected", test.name) + } + } +} + +func TestEventCompatibility(t *testing.T) { + result := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd()) + defer result.TearDownFn() + + client := clientset.NewForConfigOrDie(result.ClientConfig) + + coreevents := []*v1.Event{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pass-core-default-cluster-scoped", + Namespace: "default", + }, + Type: "Normal", + Reason: "event test", + Action: "Testing", + ReportingController: "test-controller", + ReportingInstance: "test-controller-1", + InvolvedObject: v1.ObjectReference{Kind: "Node", Name: "foo", Namespace: ""}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fail-core-kube-system-cluster-scoped", + Namespace: "kube-system", + }, + Type: "Normal", + Reason: "event test", + Action: "Testing", + ReportingController: "test-controller", + ReportingInstance: "test-controller-1", + InvolvedObject: v1.ObjectReference{Kind: "Node", Name: "foo", Namespace: ""}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fail-core-other-ns-cluster-scoped", + Namespace: "test-ns", + }, + Type: "Normal", + Reason: "event test", + Action: "Testing", + ReportingController: "test-controller", + ReportingInstance: "test-controller-1", + InvolvedObject: v1.ObjectReference{Kind: "Node", Name: "foo", Namespace: ""}, + }, + } + for _, e := range coreevents { + t.Run(e.Name, func(t *testing.T) { + _, err := client.CoreV1().Events(e.Namespace).Create(context.TODO(), e, metav1.CreateOptions{}) + if err == nil && !strings.HasPrefix(e.Name, "pass-") { + t.Fatalf("unexpected pass") + } + if err != nil && !strings.HasPrefix(e.Name, "fail-") { + t.Fatalf("unexpected error: %v", err) + } + }) + } + + v1events := []*eventsv1.Event{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pass-events-default-cluster-scoped", + Namespace: "default", + }, + EventTime: metav1.MicroTime{Time: time.Now()}, + Type: "Normal", + Reason: "event test", + Action: "Testing", + ReportingController: "test-controller", + ReportingInstance: "test-controller-1", + Regarding: v1.ObjectReference{Kind: "Node", Name: "foo", Namespace: ""}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "pass-events-kube-system-cluster-scoped", + Namespace: "kube-system", + }, + EventTime: metav1.MicroTime{Time: time.Now()}, + Type: "Normal", + Reason: "event test", + Action: "Testing", + ReportingController: "test-controller", + ReportingInstance: "test-controller-1", + Regarding: v1.ObjectReference{Kind: "Node", Name: "foo", Namespace: ""}, + }, + { + ObjectMeta: metav1.ObjectMeta{ + Name: "fail-events-other-ns-cluster-scoped", + Namespace: "test-ns", + }, + EventTime: metav1.MicroTime{Time: time.Now()}, + Type: "Normal", + Reason: "event test", + Action: "Testing", + ReportingController: "test-controller", + ReportingInstance: "test-controller-1", + Regarding: v1.ObjectReference{Kind: "Node", Name: "foo", Namespace: ""}, + }, + } + for _, e := range v1events { + t.Run(e.Name, func(t *testing.T) { + _, err := client.EventsV1().Events(e.Namespace).Create(context.TODO(), e, metav1.CreateOptions{}) + if err == nil && !strings.HasPrefix(e.Name, "pass-") { + t.Fatalf("unexpected pass") + } + if err != nil && !strings.HasPrefix(e.Name, "fail-") { + t.Fatalf("unexpected error: %v", err) + } + }) + } +} + func TestSingleWatch(t *testing.T) { result := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd()) defer result.TearDownFn()