mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
'New' Event namespace validate failed (#100125)
This commit is contained in:
parent
bea2e462a5
commit
0734820279
@ -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 {
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user