Repository navigation
@W-24431985: Watch Events with an unstructured informer so events.k8s.io/v1 fields are not dropped - #292
Closed
venkatramreddykunta wants to merge 1 commit into
Conversation
….io/v1 fields are not dropped
Some API servers return Events on /api/v1 with only the events.k8s.io/v1
field names (regarding, note, deprecatedCount, deprecatedFirstTimestamp,
deprecatedLastTimestamp, deprecatedSource). The typed corev1.Event informer
decodes them with encoding/json, which silently drops those fields, so Sloop
stored the Event with "involvedObject":{}, no message, count 0 and null
timestamps. The event count table skips count 0, so the Event heatmap was
empty and the resource Events panel showed "No events found".
- Watch Events with a dynamic informer (GVR v1/events), built from the same
rest config as the typed client (MakeDynamicClient).
- normalizeEvent copies regarding/note/deprecated* (and series/eventTime as a
fallback) into the missing core/v1 fields. Core/v1 Events are unchanged.
- Use meta.Accessor when logging excluded objects; the reflect lookup of
ObjectMeta panicked for unstructured objects (Events and CRDs).
| * For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause | ||
| */ | ||
|
|
||
| package ingress |
| "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | ||
| ) | ||
|
|
||
| // Sloop reads Events with the core/v1 field names (involvedObject, message, count, firstTimestamp, |
Collaborator
Author
|
Closing this for now. The root cause is in the upstream API we point Sloop at: it serves Events in We're fixing it on the API side instead, so every client gets core/v1 Events and not only Sloop. Thanks for the review. Happy to reopen if a Sloop-side change turns out to be useful. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Problem
Some API servers serve Events on
/api/v1/eventswithapiVersion: v1but only theevents.k8s.io/v1field names (regarding,note,deprecatedCount,deprecatedFirstTimestamp,deprecatedLastTimestamp,deprecatedSource). One example is a read-only proxy that stores events.k8s.io/v1 Events.Sloop watches Events with a typed
corev1.Eventinformer. Decoding intocorev1.Eventsilently drops every one of those fields. The Event is stored like this:{"involvedObject": {}, "count": null, "firstTimestamp": null, "lastTimestamp": null, "message": null, "source": {}}updateEventCountTablethen skips it because the count is 0, and it has no involved object to attach to. The result is that the EventHeatMap shows no Events for any resource, and there is no error or log line.Fix
{"", "v1", "events"}, so unknown fields are kept.normalizeEventcopies the events.k8s.io/v1 values into the core/v1 fields only when those fields are missing:regarding→involvedObjectnote→messagedeprecatedSource→sourcereportingController→reportingComponentdeprecatedCount→countdeprecatedFirstTimestamp/deprecatedLastTimestamp→firstTimestamp/lastTimestampseries.count,series.lastObservedTime,eventTimeinvolvedObject) are returned unchanged. The informer cache object is never modified; a copy is returned.processUpdateusesmeta.Accessorinstead of a reflect lookup. The reflect lookup panicked when logging an excluded unstructured object.makeRestConfigis shared by the typed client and the newMakeDynamicClient, so both use the same kubeconfig, context and QPS settings.Tests
pkg/sloop/ingress/eventnormalize_test.go:Test_typedEventDecodeDropsEventsV1Fieldsreproduces the bug: decoding intocorev1.Eventgives an emptyinvolvedObjectand a count of 0.Test_normalizeEvent_*cover the events.k8s.io/v1 shape, an unchanged core/v1 Event, the input not being modified,series/eventTime, and a singleeventTime.Test_processUpdate_EventsV1EventandTest_processUpdate_ExcludedUnstructured: the second is the regression test for the reflect panic.Test_bigPictureEventsV1Eventruns end to end with a fake dynamic client and checks that the Event reaches the out channel in core/v1 shape.Local checks:
go vet ./...,go test -race ./...,go mod tidy(no diff),goimports(no new findings),go build ./pkg/sloop/main.go.Manual before/after against a stub API server that serves events.k8s.io/v1 shaped Events: evidence in a comment below.
Compatibility
apiVersionandkind. The events.k8s.io/v1 fields are kept next to the copied core/v1 fields.NewKubeWatcherSourcetakes an extradynamic.Interfaceargument.