Skip to content

Latest commit

 

History

History
115 lines (90 loc) · 7.52 KB

why-a-gateway.md

File metadata and controls

115 lines (90 loc) · 7.52 KB

Watching resources

krm-stream starts with Kubernetes watches and delivers a defined live resource view to a browser. Use it for lists and status pages, then add the editor when a page needs local drafts. The host owns authentication, authorization policy, credentials and writes.

Choose a scope and a view

Scope selects the target, resource kind, namespace, optional name and allowed label selector. Projection selects what is delivered. Suppression decides whether a change to that view needs a new object event. These are separate decisions.

The host maps target names to configured clusters and authorizes the scope and projection. The browser can request a named view; it cannot supply arbitrary field rules or an API-server URL. There is no general gateway field selector or built-in status-only projection.

Projection Fields delivered Secret values Updates suppressed
krm-full/v1 Includes status Withheld Bookkeeping-only
krm-spec/v1 Omits status Withheld Bookkeeping-only and status-only
krm-raw/v1 Includes status Included when host policy permits Bookkeeping-only

Every view strips metadata.managedFields and the last-applied-configuration annotation. Raw is a named projection, not native passthrough. Full/spec redaction covers core Kubernetes Secret values, not arbitrary sensitive content in ConfigMaps or custom resources. Withheld key paths and change revisions are disclosed in redacted; the object contains no mask to accidentally save back.

For a host that permits these requests:

/resource-stream/v1?target=production&version=v1&resource=configmaps&namespace=app&projection=krm-full/v1
/resource-stream/v1?target=production&group=apps&version=v1&resource=deployments&namespace=app&projection=krm-spec/v1
/resource-stream/v1?target=production&version=v1&resource=pods&namespace=app&labelSelector=app%3Dhello&projection=krm-full/v1

Enable ScopePolicy.AllowLabelSelector deliberately before accepting the last request. Use resourceStreamURL to encode queries in application code; see adoption.

What suppression saves

The gateway compares projected content excluding metadata.resourceVersion, plus redaction records, with what it last delivered for that UID. Unchanged views produce no object event. Secret rotations still produce updates because their redaction revisions change. Every complete snapshot includes all members, including unchanged objects.

This reduces downstream bytes and event processing. Fewer store notifications and renders depend on how the application consumes events; suppression does not eliminate the gateway's upstream work. The stream represents current state and may coalesce intermediate changes; use an audit system when every transition matters.

A quiet view can hold an older write version even while its displayed fields are correct. That tradeoff matters when adding editing: see quiet streams and saving.

Snapshot and recovery

Each connection begins with reset, zero or more resource upserts, then synced. Live upserts replace complete projected objects. reset retains old state while the snapshot arrives; only synced prunes members that were not resent. An interrupted snapshot cannot prove absence. UID distinguishes a recreated resource from an earlier object with the same name.

The fetch connector exposes connecting, syncing, live, retrying, closed, terminal and exhausted. Apply state events synchronously before rendering completion. Retryable failures recover within the connector's bounded budget. For the gateway SSE connector, every HTTP 4xx except 408/429, terminal stream errors and a mismatched protocol header stop the connection. The native connector classifies HTTP and in-stream 410 (expired watch history) as recoverable by a fresh LIST instead, and resumes its WATCH from its own checkpoint after an ordinary interruption. Dispose subscriptions and close the handle when their owner leaves. See the client lifecycle reference.

A new gateway connection receives a fresh snapshot. SSE sequence numbers and object versions are not browser resume tokens. Proposed gateway upstream continuation can reduce resnapshots without changing that browser contract; see proposal 0006.

Optional watch sharing

Without sharing, each stream uses its own backend watch. SharedBackend can keep one upstream watch per matching scope in that backend and serve subscribers from its cache. Each subscriber still needs its own snapshot, delivery and browser reconciliation. Different scopes or host processes do not become one watch automatically.

A shared watch uses one service identity. The host authorizes each subscriber before serving cached objects, checks its disclosure policy, and configures timed checks when quiet-stream revocation must be bounded. Pair sharing with kube.SubjectAccessReviewAuthorizer for Kubernetes permission checks. See shared-watch authorization and operations. Sharing reduces duplicate resource consumption; it does not supply a rate limiter or admission policy.

Native and gateway sources

Native access is the straightforward starting point for a host that already proxies Kubernetes. The native connector, connectNativeWatch, adds lifecycle and state-store reuse while retaining original resource fields. The gateway adds defined views, redaction, suppression and watch sharing, delivered over SSE. Choose the guarantees the page needs. Native access alone does not provide those gateway capabilities, and krm-raw/v1 still differs from native data.

Both sources use fetch; native Kubernetes JSON and gateway SSE are different framing formats, and both can carry errors. Both connectors handle refusal, expiry, cancellation and bounded retries through one shared lifecycle; each classifies its own framing and HTTP responses. Browser EventSource is a different client mechanism with header/retry limitations.

The native connector reads with an ordinary LIST, then a WATCH from the collection's resourceVersion. It uses the shared lifecycle and LiveResourceStore, and is live only once the snapshot is applied and the WATCH is accepted. After that complete snapshot, an EOF, a network failure or a transient refusal resumes the WATCH from the handle's checkpoint — the last event the store applied, or the last bookmark — without a LIST or a new snapshot, so the store keeps its members, drafts and conflicts and receives the missed changes as events. HTTP/in-stream 410 discards the checkpoint and recovers with a fresh LIST within the bounded policy; terminal auth refusal never selects another source. A paginated LIST response is refused rather than marked complete. Native editing writes conditional merge patches back through the same proxy. Streaming lists and pagination follow separately.

See the native usage snippet, the client reference and the native viewer example; use the gateway wiring for projected views. A same-origin, cookie-authenticated host proxy keeps Kubernetes credentials server-side. Keep stores separate across sources, scopes and identities and never fall back from a refused projected source into native access.