Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'new' Event namespace validate failed #100125

Merged
merged 1 commit into from Sep 16, 2021

Conversation

h4ghhh
Copy link
Contributor

@h4ghhh h4ghhh commented Mar 11, 2021

What type of PR is this?

/kind bug

What this PR does / why we need it:

In events.k8s.io/v1, if involvedObject.namespace is "" , type Event's validation will fail.
When event.InvolvedObject.Namespace is "", event.Namespace is set "default", but compared with "kube-system".

func (recorder *recorderImpl) makeEvent(refRegarding *v1.ObjectReference, refRelated *v1.ObjectReference, timestamp metav1.MicroTime, eventtype, reason, message string, reportingController string, reportingInstance string, action string) 
  *eventsv1.Event {
	t := metav1.Time{Time: recorder.clock.Now()}
	namespace := refRegarding.Namespace
	if namespace == "" {
		namespace = metav1.NamespaceDefault
	}
}

Which issue(s) this PR fixes:

Fixes # #100119

Special notes for your reviewer:

Does this PR introduce a user-facing change?

kube-apiserver: events created via the `events.k8s.io` API group for cluster-scoped objects are now permitted in the default namespace as well for compatibility with events clients and the `v1` API

Additional documentation e.g., KEPs (Kubernetes Enhancement Proposals), usage docs, etc.:

KEP: https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/383-new-event-api-ga-graduation


@k8s-ci-robot k8s-ci-robot added kind/bug Categorizes issue or PR as related to a bug. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. do-not-merge/release-note-label-needed Indicates that a PR should not merge because it's missing one of the release note labels. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. labels Mar 11, 2021
@k8s-ci-robot
Copy link
Contributor

Hi @h4ghhh. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. sig/apps Categorizes an issue or PR as relevant to SIG Apps. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Mar 11, 2021
@@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/hold

should we fix the event producer? Won't this break existing clients that are currently working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/hold

should we fix the event producer? Won't this break existing clients that are currently working?

No matter 'new' or 'old', the Event's default namespace is always 'default'.
Refer to line 132, where compared with NamespaceDefault.
These codes are introduced as new type Event check. If existing clients use events.k8s.io/v1 rather than core/v1, has this problem long been exposed?

Copy link
Contributor Author

@h4ghhh h4ghhh Mar 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refer to https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/383-new-event-api-ga-graduation
Namespace in which Event will live will be equal to

  • Namespace of Regarding object, if it's namespaced,
  • NamespaceSystem, if it's not.

I decide to fix event producer. Thx.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixing the producer is the correct approach, but this PR is still trying to change API validation

I created an integration test that tries to create events for cluster-scoped objects against kube-system and default namespaces, via v1 Events and events.k8s.io/v1 Events

diff --git a/test/integration/events/events_test.go b/test/integration/events/events_test.go
index bb8830076ef..3f931bb78dc 100644
--- a/test/integration/events/events_test.go
+++ b/test/integration/events/events_test.go
@@ -18,10 +18,12 @@ package events
 
 import (
 	"context"
+	"strings"
 	"testing"
 	"time"
 
 	v1 "k8s.io/api/core/v1"
+	eventsv1 "k8s.io/api/events/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	clientset "k8s.io/client-go/kubernetes"
 
@@ -92,4 +94,84 @@ func TestEventCompatibility(t *testing.T) {
 	if err != nil {
 		t.Fatalf("unexpected err: %v", err)
 	}
+
+	coreevents := []*v1.Event{
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "pass-core-kube-system-cluster-scoped",
+				Namespace: "kube-system",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			InvolvedObject:      v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fail-core-default-cluster-scoped",
+				Namespace: "default",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			InvolvedObject:      v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+	}
+	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-kube-system-cluster-scoped",
+				Namespace: "kube-system",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			Regarding:           v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fail-events-default-cluster-scoped",
+				Namespace: "default",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			Regarding:           v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+	}
+	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)
+			}
+		})
+	}
 }

Running that against 1.19, 1.20, 1.21, and 1.22 showed that events for cluster-scoped objects could only be created in the kube-system namespace in 1.19+

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert the changes to this file, add the integration test, and fix the namespace used when recording events for cluster-scoped objects in the event producer

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh... that test is setting EventTime unnecessarily when creating corev1 events

This updated version of the test shows that you could create events for cluster-scoped objects in either the kube-system or default namespaces depending on whether you specific event time:

diff --git a/test/integration/events/events_test.go b/test/integration/events/events_test.go
index bb8830076ef..54f4001fa34 100644
--- a/test/integration/events/events_test.go
+++ b/test/integration/events/events_test.go
@@ -18,10 +18,12 @@ package events
 
 import (
 	"context"
+	"strings"
 	"testing"
 	"time"
 
 	v1 "k8s.io/api/core/v1"
+	eventsv1 "k8s.io/api/events/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	clientset "k8s.io/client-go/kubernetes"
 
@@ -92,4 +94,108 @@ func TestEventCompatibility(t *testing.T) {
 	if err != nil {
 		t.Fatalf("unexpected err: %v", err)
 	}
+
+	coreevents := []*v1.Event{
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fail-core-kube-system-cluster-scoped-no-time",
+				Namespace: "kube-system",
+			},
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			InvolvedObject:      v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "pass-core-kube-system-cluster-scoped-with-time",
+				Namespace: "kube-system",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			InvolvedObject:      v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "pass-core-default-cluster-scoped-no-time",
+				Namespace: "default",
+			},
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			InvolvedObject:      v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fail-core-default-cluster-scoped-with-time",
+				Namespace: "default",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			InvolvedObject:      v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+	}
+	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.Errorf("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-kube-system-cluster-scoped",
+				Namespace: "kube-system",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			Regarding:           v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+		{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "fail-events-default-cluster-scoped",
+				Namespace: "default",
+			},
+			EventTime:           metav1.NewMicroTime(time.Now()),
+			Type:                "Warning",
+			Action:              "myaction",
+			Reason:              "myreason",
+			Regarding:           v1.ObjectReference{Name: "foo", Namespace: "", Kind: "Node", APIVersion: "v1"},
+			ReportingController: "mycontroller",
+			ReportingInstance:   "myinstance",
+		},
+	}
+	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.Errorf("unexpected pass")
+			}
+			if err != nil && !strings.HasPrefix(e.Name, "fail-") {
+				t.Fatalf("unexpected error: %v", err)
+			}
+		})
+	}
 }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And #88815 in 1.18 made both event reporters collapse onto the default namespace.

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Mar 12, 2021
@h4ghhh
Copy link
Contributor Author

h4ghhh commented Mar 12, 2021

/sig api-machinery

@k8s-ci-robot k8s-ci-robot added the sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. label Mar 12, 2021
@h4ghhh h4ghhh requested a review from liggitt March 12, 2021 05:39
@jiahuif
Copy link
Member

jiahuif commented Mar 13, 2021

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Mar 13, 2021
@h4ghhh
Copy link
Contributor Author

h4ghhh commented Mar 14, 2021

refer to https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/383-new-event-api-ga-graduation
Namespace in which Event will live will be equal to

  • Namespace of Regarding object, if it's namespaced,
  • NamespaceSystem, if it's not.

I decide to fix event producer. Thx.

@h4ghhh
Copy link
Contributor Author

h4ghhh commented Mar 15, 2021

I'm modifying kube-controller-manger to use new Event API, but this problem must be solved first.
Please check if there is anything that not has been considered.

/cc @kubernetes/api-reviewers

@liggitt
Copy link
Member

liggitt commented Mar 15, 2021

/assign @wojtek-t

I think this change looks good, but we need tests exercising the following:

  • creation of an events.k8s.io/v1 event for a cluster-scoped object that would have caught this issue
  • a test ensuring kubectl describe on a built-in cluster-scoped object finds events recorded by both the old and new events client

@fejta
Copy link
Contributor

fejta commented Mar 15, 2021

/uncc

@k8s-ci-robot k8s-ci-robot removed the request for review from fejta March 15, 2021 17:29
@fedebongio
Copy link
Contributor

/triage accepted

@k8s-ci-robot k8s-ci-robot added the triage/accepted Indicates an issue or PR is ready to be actively worked on. label Mar 16, 2021
@k8s-ci-robot k8s-ci-robot added priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. and removed needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Sep 15, 2021
@liggitt
Copy link
Member

liggitt commented Sep 15, 2021

/hold

actually, can you squash this to a single commit before merge? it will make cherry-picks easier

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Sep 15, 2021
@liggitt
Copy link
Member

liggitt commented Sep 16, 2021

/retest

@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Sep 16, 2021
@h4ghhh
Copy link
Contributor Author

h4ghhh commented Sep 16, 2021

/hold

actually, can you squash this to a single commit before merge? it will make cherry-picks easier

ok

@wojtek-t
Copy link
Member

/lgtm

/hold cancel

@k8s-ci-robot k8s-ci-robot added lgtm "Looks good to me", indicates that a PR is ready to be merged. and removed do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. labels Sep 16, 2021
@h4ghhh
Copy link
Contributor Author

h4ghhh commented Sep 16, 2021

/retest

@k8s-ci-robot k8s-ci-robot merged commit 0734820 into kubernetes:master Sep 16, 2021
@k8s-ci-robot k8s-ci-robot added this to the v1.23 milestone Sep 16, 2021
@liggitt liggitt moved this from In progress to API review completed, 1.23 in API Reviews Sep 16, 2021
@liggitt
Copy link
Member

liggitt commented Sep 16, 2021

please open cherry-picks against 1.20-1.22

@h4ghhh
Copy link
Contributor Author

h4ghhh commented Sep 17, 2021

please open cherry-picks against 1.20-1.22

ok

k8s-ci-robot added a commit that referenced this pull request Sep 19, 2021
…25-upstream-release-1.20

Automated cherry pick of #100125: 'New' Event namespace validate failed
k8s-ci-robot added a commit that referenced this pull request Sep 19, 2021
…25-upstream-release-1.22

Automated cherry pick of #100125: 'New' Event namespace validate failed
k8s-ci-robot added a commit that referenced this pull request Sep 19, 2021
…25-upstream-release-1.21

Automated cherry pick of #100125: 'New' Event namespace validate failed
ibabou pushed a commit to ibabou/kubernetes that referenced this pull request Sep 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api-review Categorizes an issue or PR as actively needing an API review. approved Indicates a PR has been approved by an approver from all required OWNERS files. area/test cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/bug Categorizes issue or PR as related to a bug. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. priority/important-soon Must be staffed and worked on either currently, or very soon, ideally in time for the next release. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/apps Categorizes an issue or PR as relevant to SIG Apps. sig/testing Categorizes an issue or PR as relevant to SIG Testing. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. tide/merge-method-squash Denotes a PR that should be squashed by tide when it merges. triage/accepted Indicates an issue or PR is ready to be actively worked on.
Projects
Status: API review completed, 1.23
Development

Successfully merging this pull request may close these issues.

None yet

8 participants