'New' Event namespace validate failed (#100125)

This commit is contained in:
h4ghhh 2021-09-16 19:29:45 +08:00 committed by GitHub
parent bea2e462a5
commit 0734820279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 222 additions and 2 deletions

View File

@ -21,7 +21,7 @@ import (
"reflect" "reflect"
"time" "time"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
eventsv1beta1 "k8s.io/api/events/v1beta1" eventsv1beta1 "k8s.io/api/events/v1beta1"
apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -140,7 +140,7 @@ func legacyValidateEvent(event *core.Event) field.ErrorList {
} }
} else { } 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")) allErrs = append(allErrs, field.Invalid(field.NewPath("involvedObject", "namespace"), event.InvolvedObject.Namespace, "does not match event.namespace"))
} }
if len(event.ReportingController) == 0 { if len(event.ReportingController) == 0 {

View File

@ -22,6 +22,7 @@ import (
"log" "log"
"reflect" "reflect"
rt "runtime" rt "runtime"
"strings"
"sync" "sync"
"testing" "testing"
"time" "time"
@ -29,6 +30,7 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
eventsv1 "k8s.io/api/events/v1"
"k8s.io/apimachinery/pkg/api/equality" "k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/resource" "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) 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) { func TestSingleWatch(t *testing.T) {
result := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd()) result := kubeapiservertesting.StartTestServerOrDie(t, nil, nil, framework.SharedEtcd())
defer result.TearDownFn() defer result.TearDownFn()