Skip to content

feat(controller): migrate Instance event emission to the supported events API#178

Draft
scotwells wants to merge 1 commit into
mainfrom
feat/119-supported-events-api
Draft

feat(controller): migrate Instance event emission to the supported events API#178
scotwells wants to merge 1 commit into
mainfrom
feat/119-supported-events-api

Conversation

@scotwells

@scotwells scotwells commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

When an Instance won't schedule — project quota exhausted, no budget configured, project misconfigured — operators find out why by reading the Kubernetes Events on the Instance (kubectl describe instance). That quota-failure observability was added in #118 and is now part of how operators self-diagnose.

That emission was wired through controller-runtime's deprecated event recorder, an API slated for removal. Left as-is, a routine dependency bump could have silently broken event emission — or the build — quietly degrading the diagnostics operators depend on. This moves Instance event emission onto the supported Kubernetes events API (events.k8s.io) so that visibility keeps working through future dependency upgrades.

Two user-visible wins come with the new API:

  • Each event now carries a machine-readable action — what the controller was doing (claiming quota, releasing quota, resolving referenced data, removing the scheduling gate) — alongside the existing reason (what happened). Reasons stay the outcome; actions name the operation.
  • Repeated events are deduplicated into a series. On a busy or flapping Instance the new API aggregates identical events into one entry with a rising count instead of emitting a fresh event each reconcile, cutting event noise.

All existing event reasons and messages are unchanged, so nothing operators already rely on breaks — kubectl describe instance shows the same Warning/Normal events, now backed by events.k8s.io.

What changed

  • Swapped the reconciler's recorder from the deprecated record.EventRecorder to events.EventRecorder, and removed the //nolint:staticcheck suppression the earlier deferral left behind.
  • Every emit site funnels through one helper that maps the operation to a small set of action constants; reason codes and human-readable messages pass through byte-identical.
  • The helper truncates a note to the events API's 1024-character server-side validation limit, so an oversized message (e.g. a long list of missing companions) is never silently rejected, and passes the message such that a literal % in backend error text can't be mis-rendered.
  • Regenerated the controller RBAC so the events grant moves from the core group to events.k8s.io (create/patch).
  • Tests use a small capturing fake recorder that reproduces the byte-identical event strings the old fake produced (so existing assertions are unchanged) while additionally capturing the structured action/reason fields the stock fake discards.

Notes for reviewers / deployers

  • RBAC: the controller's ClusterRole now needs the events.k8s.io create/patch grant, which ships in this PR's role.yaml. envtest runs as admin, so a missing grant in a deployment overlay would be silent in CI — worth confirming events actually land on a live cell during lab verification, and that any overlay mirroring the controller role carries the events.k8s.io rule.
  • Event consumers: tooling that scrapes core/v1 Events specifically (rather than kubectl / describe, which surface both APIs) would no longer see these events. Low risk — no such in-repo consumer was found — flagged for awareness.

Closes #119.

🤖 Generated with Claude Code

@scotwells scotwells force-pushed the feat/119-supported-events-api branch from 0701ff4 to f66cf23 Compare July 9, 2026 23:37
…ents API

The InstanceReconciler emitted quota and referenced-data events through the
deprecated core/v1 event recorder. Move to the events.k8s.io/v1 recorder so
Instance events keep flowing on the supported API surface, with each event now
carrying a machine-readable action (the controller operation) alongside its
existing reason (the outcome). Operators see the same Warning/Normal events in
`kubectl describe instance`, now backed by events.k8s.io.

All emit sites funnel through the emitEvent helper, which passes the message as
a "%s" argument so backend error text containing a literal '%' is not
format-expanded, and truncates the note to the 1024-character server-side limit
so oversized notes are not silently rejected. The controller RBAC role is
regenerated to grant events.k8s.io instead of the core events group.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@scotwells scotwells force-pushed the feat/119-supported-events-api branch from f66cf23 to 6e90009 Compare July 9, 2026 23:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate quota event emission to the supported events API

1 participant