Kuadrant / Kuadrant/developer-portal-controller

Filter APIKeyStatus Secret watch by label instead of watching all Secrets cluster-wide

Open
#83 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage/accepted
Dominant language
Go
Stars
2
Forks
12
Avg merge
13h 37m
Merged PRs (30d)
5

Description

Background

#82 adds a Secret watch to APIKeyStatusReconciler (internal/controller/apikey_status_controller.go) so that APIKeys stuck in SecretNotFound recover once their referenced Secret is created. See #78.

The watch is currently unfiltered:

Watches(&corev1.Secret{}, handler.EnqueueRequestsFromMapFunc(r.enqueueClass)).

This reconciler uses a "class reconciler" pattern: every watched event enqueues the same fixed key and triggers a full list-and-reconcile of all APIKeys (Reconcile, internal/controller/apikey_status_controller.go:63). The manager's cache is not namespace-scoped (cmd/main.go), so in practice any Secret create/update/delete anywhere in the cluster now triggers a full reconcile pass of every APIKey.

Proposal

Define a label that marks a Secret as an APIKey's referenced secret (e.g. devportal.kuadrant.io/apikey-secret: "true"), and filter the Secret watch in apikey_status_controller.go with a predicate so it only reacts to Secrets carrying that label.

Scope — when the label is (and isn't) needed

The label is only relevant to the Secret-created-after-APIKey race. If the Secret already exists at the time the APIKey is created (the normal/original ordering), reconciliation is already triggered by the APIKey watch itself — no Secret event, and therefore no label, is needed for that path to succeed. The label-scoped watch exists solely to catch the recovery case from #78/#82: APIKey created first, referencing a Secret that doesn't exist yet, created moments later. Consumers/plugins that always create the Secret before the APIKey never need to set this label for correctness — only those that create the APIKey first (e.g. to set an ownerReference, per kuadrant-console-plugin#541) need it.

Non-goal: keeping the APIKey in sync with later Secret content changes. This watch only reacts to the Secret appearing (create/update events firing the same generic re-reconcile). It does not mean the system keeps API key material in sync if someone edits the Secret's data.api_key after the fact:

  • APIKeyStatusReconciler only re-checks existence/non-emptiness of the entry, it doesn't project the value anywhere that would need re-syncing.
  • APIKeySecretReconciler (internal/controller/apikey_secret_controller.go), which copies the consumer Secret's api_key value into the Authorino-enforced secret, does not watch Secrets at all (only APIKey) — so an in-place edit of the consumer's Secret value is never propagated to enforcement, label or no label.

This issue is scoped to detecting Secret creation for the missing-secret recovery case, not to general Secret-content sync. That gap (edits to an existing Secret's value not propagating to enforcement) is a separate, pre-existing issue if it needs addressing.

Tasks

  • Decide on the label key/value
  • Add predicate to the Secret watch in apikey_status_controller.go
  • Document the label (and its limited scope, per above) in this repo
  • Document the label in docs.kuadrant.io
  • Update kuadrant-console-plugin (RequestAPIKeyModal.tsx) to set the label — only strictly required for the create-APIKey-before-Secret flow (kuadrant-console-plugin#541)
  • Update kuadrant-backstage-plugin (router.ts POST /secrets) to set the label if/when it adopts the same create-order

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with internal/controller/apikey_status_controller.go and its Secret watch, then read cmd/main.go to understand the cluster-wide cache behavior. Decide the label key and value, add the predicate, and document its limited missing-Secret recovery scope in this repository and docs.kuadrant.io; completion also includes the named console and Backstage integration updates where applicable.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend, documentation, infrastructure
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.