Documentation
¶
Overview ¶
Package stores provides abstractions for accessing and composing resource stores.
Package stores provides abstractions for accessing and composing resource stores.
This package defines:
- StoreProvider: Interface for accessing stores by name
- RealStoreProvider: Implementation that returns actual stores
- ValidationContext: Unified container for K8s and HTTP overlays
- OverlayStoreProvider: Implementation that applies ValidationContext overlays
These abstractions enable "what if" scenarios by allowing components to render and validate configurations with proposed changes without modifying actual state.
Index ¶
- Variables
- func GetContext(ctx context.Context, store Store, keys ...string) ([]any, error)
- func HasIdentityOrderedReads(snapshot ReadSnapshot) bool
- func ListContext(ctx context.Context, store Store) ([]any, error)
- func SupportsExactRevisionJournal(store Store) bool
- func SupportsSnapshotCommitFence(store Store) bool
- type CompositeStore
- func (s *CompositeStore) AcquireSnapshotCommitFence(ctx context.Context) (func(), error)
- func (s *CompositeStore) Add(_ any, _ []string) error
- func (s *CompositeStore) ChangesSince(sequence uint64) (uint64, []RevisionChange, bool)
- func (s *CompositeStore) Clear() error
- func (s *CompositeStore) Delete(_, _ string, _ []string) error
- func (s *CompositeStore) ExactRevisionJournalSource() RevisionSource
- func (s *CompositeStore) Get(keys ...string) ([]any, error)
- func (s *CompositeStore) GetContext(ctx context.Context, keys ...string) ([]any, error)
- func (s *CompositeStore) GetIdentity(namespace, name string) (item any, found bool, err error)
- func (s *CompositeStore) GetRevision(keys ...string) Revision
- func (s *CompositeStore) GetSnapshot(keys ...string) (items []any, revision Revision, sequence uint64, err error)
- func (s *CompositeStore) IdentityRevision(namespace, name string) Revision
- func (s *CompositeStore) IdentitySnapshot(namespace, name string) (item any, found bool, revision Revision, sequence uint64, err error)
- func (s *CompositeStore) List() ([]any, error)
- func (s *CompositeStore) ListCached() ([]any, error)
- func (s *CompositeStore) ListContext(ctx context.Context) ([]any, error)
- func (s *CompositeStore) ListRevision() Revision
- func (s *CompositeStore) ListSnapshot() (items []any, sequence uint64, err error)
- func (s *CompositeStore) Pin() (ReadSnapshot, error)
- func (s *CompositeStore) RevisionSource() RevisionSource
- func (s *CompositeStore) Update(_ any, _ []string) error
- type ContentOverlay
- type ContextGetter
- type ContextLister
- type ContextReadSnapshot
- type ExactRevisionJournal
- type ExactRevisionRangeJournal
- type ExactSnapshotDiffer
- type HTTPContentOverlay
- type IdentityGetter
- type IdentityOrderedReadSnapshot
- type OverlayChange
- type OverlayStoreProvider
- func (p *OverlayStoreProvider) GetBaseStore(name string) Store
- func (p *OverlayStoreProvider) GetHTTPOverlay() HTTPContentOverlay
- func (p *OverlayStoreProvider) GetK8sOverlay(name string) *StoreOverlay
- func (p *OverlayStoreProvider) GetStore(name string) Store
- func (p *OverlayStoreProvider) StoreNames() []string
- func (p *OverlayStoreProvider) Validate() error
- type ReadOnlyStoreError
- type ReadSnapshot
- type RealStoreProvider
- type Revision
- type RevisionChange
- type RevisionJournal
- type RevisionSource
- type Revisioned
- type SnapshotChange
- type SnapshotCommitFencer
- type SnapshotCommitMutex
- type SnapshotProvider
- type SnapshotReader
- type Store
- type StoreOverlay
- type StoreProvider
- type ValidationContext
Constants ¶
This section is empty.
Variables ¶
var ErrIdentityLookupUnsupported = errors.New("exact identity lookup is unsupported")
ErrIdentityLookupUnsupported means an adapter cannot perform an exact identity read.
var ErrSnapshotChanged = errors.New("store changed after its snapshot was pinned")
ErrSnapshotChanged means a lazy snapshot read could not reproduce its pinned root.
var ErrSnapshotCommitFenceUnsupported = errors.New("snapshot commit fence is unsupported")
var ErrSnapshotUnsupported = errors.New("atomic store snapshot is unsupported")
ErrSnapshotUnsupported means a store cannot bind a read to a revision watermark.
Functions ¶
func GetContext ¶
GetContext uses the store's context-aware read when available. Legacy reads check cancellation before and after the call but cannot interrupt a read in progress.
func HasIdentityOrderedReads ¶
func HasIdentityOrderedReads(snapshot ReadSnapshot) bool
HasIdentityOrderedReads reports whether collection order is authenticated for the snapshot source.
func ListContext ¶
ListContext uses the store's context-aware read or checks cancellation around List.
func SupportsExactRevisionJournal ¶
SupportsExactRevisionJournal reports whether journal changes are certified complete for the store's immutable snapshot source.
func SupportsSnapshotCommitFence ¶
SupportsSnapshotCommitFence reports whether fence calls reach an underlying implementation.
Types ¶
type CompositeStore ¶
type CompositeStore struct {
// contains filtered or unexported fields
}
CompositeStore wraps a base store with an overlay, providing a unified view that reflects both the actual state and proposed changes.
Read operations (Get, List) return the merged view. Write operations are not supported and will return an error.
Thread Safety ¶
CompositeStore itself is not thread-safe, but this is by design:
- A new CompositeStore is created for each validation request (not shared across goroutines)
- The base store must be thread-safe (k8s.Store uses sync.RWMutex internally)
- The overlay must not be modified after construction (immutable during validation)
This design avoids synchronization overhead since each request gets its own instance.
func NewCompositeStore ¶
func NewCompositeStore(base Store, overlay *StoreOverlay) *CompositeStore
NewCompositeStore creates a new CompositeStore.
Parameters:
- base: The underlying store with actual state
- overlay: The proposed changes to apply on top
func (*CompositeStore) AcquireSnapshotCommitFence ¶
func (s *CompositeStore) AcquireSnapshotCommitFence(ctx context.Context) (func(), error)
func (*CompositeStore) Add ¶
func (s *CompositeStore) Add(_ any, _ []string) error
Add is not supported on CompositeStore. CompositeStore is read-only; modifications should be made through the overlay.
func (*CompositeStore) ChangesSince ¶
func (s *CompositeStore) ChangesSince(sequence uint64) (uint64, []RevisionChange, bool)
func (*CompositeStore) Clear ¶
func (s *CompositeStore) Clear() error
Clear is not supported on CompositeStore. CompositeStore is read-only; modifications should be made through the overlay.
func (*CompositeStore) Delete ¶
func (s *CompositeStore) Delete(_, _ string, _ []string) error
Delete is not supported on CompositeStore. CompositeStore is read-only; modifications should be made through the overlay.
func (*CompositeStore) ExactRevisionJournalSource ¶
func (s *CompositeStore) ExactRevisionJournalSource() RevisionSource
func (*CompositeStore) Get ¶
func (s *CompositeStore) Get(keys ...string) ([]any, error)
Get returns resources matching the given keys.
The result includes:
- Resources from the base store (excluding deletions)
- Modifications (replacing base resources with same keys)
- Additions that match the keys
func (*CompositeStore) GetContext ¶
GetContext returns the overlaid keyed view while propagating cancellation to the base store.
func (*CompositeStore) GetIdentity ¶
func (s *CompositeStore) GetIdentity(namespace, name string) (item any, found bool, err error)
func (*CompositeStore) GetRevision ¶
func (s *CompositeStore) GetRevision(keys ...string) Revision
func (*CompositeStore) GetSnapshot ¶
func (*CompositeStore) IdentityRevision ¶
func (s *CompositeStore) IdentityRevision(namespace, name string) Revision
func (*CompositeStore) IdentitySnapshot ¶
func (*CompositeStore) List ¶
func (s *CompositeStore) List() ([]any, error)
List returns all resources from the merged view.
func (*CompositeStore) ListCached ¶
func (s *CompositeStore) ListCached() ([]any, error)
ListCached returns the overlaid view of any warm base-store entries.
func (*CompositeStore) ListContext ¶
func (s *CompositeStore) ListContext(ctx context.Context) ([]any, error)
ListContext returns the overlaid full view while propagating cancellation to the base store.
func (*CompositeStore) ListRevision ¶
func (s *CompositeStore) ListRevision() Revision
func (*CompositeStore) ListSnapshot ¶
func (s *CompositeStore) ListSnapshot() (items []any, sequence uint64, err error)
func (*CompositeStore) Pin ¶
func (s *CompositeStore) Pin() (ReadSnapshot, error)
Pin delegates empty overlays and rejects overlays without projected index keys.
func (*CompositeStore) RevisionSource ¶
func (s *CompositeStore) RevisionSource() RevisionSource
type ContentOverlay ¶
type ContentOverlay interface {
// IsEmpty returns true if the overlay contains no pending changes.
IsEmpty() bool
}
ContentOverlay is a marker interface for overlay types.
Both K8s overlays (StoreOverlay) and HTTP overlays implement this interface, enabling unified handling in validation pipelines.
type ContextGetter ¶
ContextGetter is the optional cancellation-aware Get extension to Store.
type ContextLister ¶
ContextLister is the optional cancellation-aware List extension to Store.
type ContextReadSnapshot ¶
type ContextReadSnapshot interface {
ReadSnapshot
GetContext(ctx context.Context, keys ...string) ([]any, error)
ListContext(ctx context.Context) ([]any, error)
GetIdentityContext(ctx context.Context, namespace, name string) (item any, found bool, err error)
}
ContextReadSnapshot cancels reads that can perform external I/O.
type ExactRevisionJournal ¶
type ExactRevisionJournal interface {
RevisionJournal
ExactRevisionJournalSource() RevisionSource
}
ExactRevisionJournal guarantees that every retained change carries the exact identity and complete old/new index keys for the named revision source.
type ExactRevisionRangeJournal ¶
type ExactRevisionRangeJournal interface {
ExactRevisionJournal
ChangesBetween(from, through uint64) (changes []RevisionChange, complete bool)
}
ExactRevisionRangeJournal certifies both endpoints belong to the same retained history and returns every change between them, including atomic batches.
type ExactSnapshotDiffer ¶
type ExactSnapshotDiffer interface {
ReadSnapshot
ChangesFrom(ctx context.Context, previous ReadSnapshot) (changes []RevisionChange, complete bool, err error)
}
ExactSnapshotDiffer proves the complete identity and index-key difference between immutable roots, including divergent branches of one source.
type HTTPContentOverlay ¶
type HTTPContentOverlay interface {
ContentOverlay
// GetContent returns content for the given URL.
// Returns pending content if available, otherwise accepted content.
GetContent(url string) (string, bool)
// GetContentForSource returns content only for the matching source authority.
GetContentForSource(url, sourceIdentity string) (string, bool)
// PendingURLs returns the list of URLs with pending content.
PendingURLs() []string
// HasPendingURL returns true if the given URL has pending content.
HasPendingURL(url string) bool
}
HTTPContentOverlay represents HTTP content changes awaiting validation.
This interface abstracts the HTTP overlay to avoid circular imports between pkg/stores and pkg/httpstore. The httpstore.HTTPOverlay type implements this.
type IdentityGetter ¶
type IdentityGetter interface {
GetIdentity(namespace, name string) (resource any, found bool, err error)
}
IdentityGetter retrieves a resource without knowing its configured index keys.
type IdentityOrderedReadSnapshot ¶
type IdentityOrderedReadSnapshot interface {
ReadSnapshot
IdentityOrderSource() RevisionSource
}
IdentityOrderedReadSnapshot guarantees List and Get order solely by namespace/name.
type OverlayChange ¶
OverlayChange is one immutable proposed identity replacement or deletion.
type OverlayStoreProvider ¶
type OverlayStoreProvider struct {
// contains filtered or unexported fields
}
OverlayStoreProvider applies ValidationContext overlays to a base provider.
In addition to applying K8s overlays, this provider also exposes the HTTP overlay for use by the render service.
Usage:
ctx := NewValidationContext(k8sOverlays).WithHTTPOverlay(httpOverlay)
provider := NewOverlayStoreProvider(baseProvider, ctx)
// K8s stores automatically have overlays applied
store := provider.GetStore("ingress") // Returns CompositeStore if overlay exists
// HTTP overlay is accessible for render service
httpOverlay := provider.GetHTTPOverlay() // Returns HTTPContentOverlay
func NewOverlayStoreProvider ¶
func NewOverlayStoreProvider(base StoreProvider, validationContext *ValidationContext) *OverlayStoreProvider
NewOverlayStoreProvider creates a provider that applies ValidationContext overlays.
Parameters:
- base: The underlying store provider
- validationContext: ValidationContext containing K8s and/or HTTP overlays
If validationContext is nil, behaves identically to the base provider.
func (*OverlayStoreProvider) GetBaseStore ¶
func (p *OverlayStoreProvider) GetBaseStore(name string) Store
GetBaseStore returns the store beneath this request's scratch overlay.
func (*OverlayStoreProvider) GetHTTPOverlay ¶
func (p *OverlayStoreProvider) GetHTTPOverlay() HTTPContentOverlay
GetHTTPOverlay returns the HTTP content overlay from the ValidationContext.
Returns nil if:
- ValidationContext is nil
- No HTTP overlay was set
The render service uses this to determine whether to include pending HTTP content.
func (*OverlayStoreProvider) GetK8sOverlay ¶
func (p *OverlayStoreProvider) GetK8sOverlay(name string) *StoreOverlay
GetK8sOverlay returns the immutable scratch overlay for one store.
func (*OverlayStoreProvider) GetStore ¶
func (p *OverlayStoreProvider) GetStore(name string) Store
GetStore returns a store for the given name.
If a K8s overlay exists for this store in the ValidationContext, returns a CompositeStore that applies the overlay on top of the base store. Otherwise, returns the base store unchanged.
func (*OverlayStoreProvider) StoreNames ¶
func (p *OverlayStoreProvider) StoreNames() []string
StoreNames returns the names of all available stores.
func (*OverlayStoreProvider) Validate ¶
func (p *OverlayStoreProvider) Validate() error
Validate checks that all K8s overlays reference valid stores in the base provider.
type ReadOnlyStoreError ¶
type ReadOnlyStoreError struct {
Operation string
}
ReadOnlyStoreError indicates an attempt to modify a read-only store.
func (*ReadOnlyStoreError) Error ¶
func (e *ReadOnlyStoreError) Error() string
type ReadSnapshot ¶
type ReadSnapshot interface {
Revisioned
IdentityGetter
RevisionSource() RevisionSource
Sequence() uint64
Get(keys ...string) ([]any, error)
List() ([]any, error)
}
ReadSnapshot is one immutable store root. Reads return detached values, and every revision comes from the snapshot's fixed source and sequence.
func OverlayReadSnapshot ¶
func OverlayReadSnapshot(base ReadSnapshot, changes []SnapshotChange) (ReadSnapshot, error)
OverlayReadSnapshot composes projected changes over an immutable base snapshot.
func OverlayReadSnapshotContext ¶
func OverlayReadSnapshotContext( ctx context.Context, base ReadSnapshot, changes []SnapshotChange, ) (ReadSnapshot, error)
OverlayReadSnapshotContext composes an overlay without detaching external reads from ctx.
type RealStoreProvider ¶
type RealStoreProvider struct {
// contains filtered or unexported fields
}
RealStoreProvider provides access to actual (non-overlaid) stores.
This is the default implementation used during normal reconciliation.
func NewRealStoreProvider ¶
func NewRealStoreProvider(stores map[string]Store) *RealStoreProvider
NewRealStoreProvider creates a new RealStoreProvider with the given stores.
func (*RealStoreProvider) GetStore ¶
func (p *RealStoreProvider) GetStore(name string) Store
func (*RealStoreProvider) StoreNames ¶
func (p *RealStoreProvider) StoreNames() []string
type Revision ¶
type Revision string
Revision is a comparable token for one store read scope. An empty token is unsupported.
type RevisionChange ¶
type RevisionChange struct {
Sequence uint64
Namespace string
Name string
Deleted bool
OldKeys []string
NewKeys []string
}
RevisionChange describes one resource-agnostic store mutation.
type RevisionJournal ¶
type RevisionJournal interface {
ListSnapshot() (items []any, sequence uint64, err error)
ChangesSince(sequence uint64) (current uint64, changes []RevisionChange, complete bool)
}
RevisionJournal exposes an atomic baseline and bounded changes after it.
type RevisionSource ¶
type RevisionSource uint64
RevisionSource identifies one store instance for its lifetime. Zero is unsupported.
func ExactRevisionJournalSource ¶
func ExactRevisionJournalSource(store Store) RevisionSource
ExactRevisionJournalSource returns the source whose journal contract is exact.
type Revisioned ¶
type Revisioned interface {
ListRevision() Revision
GetRevision(keys ...string) Revision
IdentityRevision(namespace, name string) Revision
}
Revisioned exposes read-scope revisions without loading resource bodies.
type SnapshotChange ¶
type SnapshotChange struct {
Namespace string
Name string
Deleted bool
Value any
OldKeys []string
NewKeys []string
}
SnapshotChange is one identity replacement or deletion with its projected keys.
type SnapshotCommitFencer ¶
type SnapshotCommitMutex ¶
type SnapshotCommitMutex struct {
// contains filtered or unexported fields
}
func (*SnapshotCommitMutex) Acquire ¶
func (m *SnapshotCommitMutex) Acquire(ctx context.Context) (func(), error)
func (*SnapshotCommitMutex) Lock ¶
func (m *SnapshotCommitMutex) Lock()
func (*SnapshotCommitMutex) LockContext ¶
func (m *SnapshotCommitMutex) LockContext(ctx context.Context) error
func (*SnapshotCommitMutex) Unlock ¶
func (m *SnapshotCommitMutex) Unlock()
type SnapshotProvider ¶
type SnapshotProvider interface {
Pin() (ReadSnapshot, error)
}
SnapshotProvider pins an immutable store root without loading its resources.
type SnapshotReader ¶
type SnapshotReader interface {
RevisionSource() RevisionSource
GetSnapshot(keys ...string) (items []any, revision Revision, sequence uint64, err error)
IdentitySnapshot(namespace, name string) (
item any, found bool, revision Revision, sequence uint64, err error,
)
}
SnapshotReader binds exact read results to their revision and journal watermark.
type Store ¶
type Store interface {
// Get retrieves all resources matching the provided index keys.
Get(keys ...string) ([]any, error)
// List returns all resources in the store.
List() ([]any, error)
// Add inserts a new resource into the store with the provided index keys.
Add(resource any, keys []string) error
// Update modifies an existing resource in the store.
Update(resource any, keys []string) error
// Delete removes the single resource identified by namespace/name. Index
// keys need not be unique, so identity is authoritative and siblings remain.
Delete(namespace, name string, keys []string) error
// Clear removes all resources from the store.
Clear() error
}
Store defines the interface for storing and retrieving indexed resources.
This interface mirrors pkg/k8s/Store but is defined here to maintain package independence. Go's implicit interface satisfaction means any type implementing these methods (like k8s/Store) automatically satisfies this.
type StoreOverlay ¶
type StoreOverlay struct {
// Additions are new resources to add to the store.
Additions []runtime.Object
// Modifications are existing resources with updated content.
Modifications []runtime.Object
// Deletions are keys identifying resources to remove.
// Uses NamespacedName for consistent key format.
Deletions []ktypes.NamespacedName
// contains filtered or unexported fields
}
StoreOverlay represents proposed changes to a store.
This enables "what if" scenarios: validate configurations with proposed changes without modifying the actual store state.
Resources are pre-converted to template-friendly format (floats to ints) at construction time to avoid repeated conversion during Get()/List() calls.
func NewStoreOverlay ¶
func NewStoreOverlay() *StoreOverlay
NewStoreOverlay creates a new empty StoreOverlay.
func NewStoreOverlayForCreate ¶
func NewStoreOverlayForCreate(obj runtime.Object) *StoreOverlay
NewStoreOverlayForCreate creates a StoreOverlay for a CREATE operation. The resource is pre-converted to template-friendly format.
func NewStoreOverlayForDelete ¶
func NewStoreOverlayForDelete(namespace, name string) *StoreOverlay
NewStoreOverlayForDelete creates a StoreOverlay for a DELETE operation.
func NewStoreOverlayForUpdate ¶
func NewStoreOverlayForUpdate(obj runtime.Object) *StoreOverlay
NewStoreOverlayForUpdate creates a StoreOverlay for an UPDATE operation. The resource is pre-converted to template-friendly format.
func (*StoreOverlay) AddAddition ¶
func (o *StoreOverlay) AddAddition(obj runtime.Object)
AddAddition adds a resource to the additions list and pre-converts it. Use this method instead of directly modifying the Additions field to ensure the pre-converted slice stays in sync.
func (*StoreOverlay) AddModification ¶
func (o *StoreOverlay) AddModification(obj runtime.Object)
AddModification adds a resource to the modifications list and pre-converts it. Use this method instead of directly modifying the Modifications field to ensure the pre-converted slice stays in sync.
func (*StoreOverlay) IdentityChanges ¶
func (o *StoreOverlay) IdentityChanges() ([]OverlayChange, bool)
IdentityChanges returns a deterministic snapshot and false for ambiguous overlays.
func (*StoreOverlay) IsEmpty ¶
func (o *StoreOverlay) IsEmpty() bool
IsEmpty returns true if the overlay contains no changes.
type StoreProvider ¶
type StoreProvider interface {
// GetStore returns the store for the given name.
// Returns nil if no store exists with that name.
GetStore(name string) Store
// StoreNames returns the names of all available stores.
StoreNames() []string
}
StoreProvider provides access to stores by name.
This abstraction decouples consumers from how stores are obtained, enabling composition and overlaying of proposed changes.
type ValidationContext ¶
type ValidationContext struct {
// K8sOverlays maps store names to their proposed changes.
K8sOverlays map[string]*StoreOverlay
// HTTPOverlay contains pending HTTP content changes.
// Nil means no HTTP content changes to validate.
HTTPOverlay HTTPContentOverlay
}
ValidationContext is a unified container for all overlay types.
It holds both K8s store overlays and HTTP content overlays, enabling the render pipeline to apply proposed changes transparently during validation.
Usage:
// For K8s-only validation (webhook admission) ctx := NewValidationContext(k8sOverlays) // For HTTP content validation ctx := NewValidationContext(nil).WithHTTPOverlay(httpOverlay) // For combined validation ctx := NewValidationContext(k8sOverlays).WithHTTPOverlay(httpOverlay)
func NewValidationContext ¶
func NewValidationContext(overlays map[string]*StoreOverlay) *ValidationContext
NewValidationContext creates a ValidationContext with K8s overlays.
Parameters:
- overlays: Map of store name to proposed K8s changes (can be nil)
Returns a ValidationContext ready for use or further configuration.
func (*ValidationContext) IsEmpty ¶
func (c *ValidationContext) IsEmpty() bool
IsEmpty returns true if the context contains no overlays.
A context is empty if it has no K8s overlays AND no HTTP overlay.
func (*ValidationContext) WithHTTPOverlay ¶
func (c *ValidationContext) WithHTTPOverlay(overlay HTTPContentOverlay) *ValidationContext
WithHTTPOverlay adds an HTTP overlay to the validation context.
Returns the same ValidationContext for method chaining:
ctx := NewValidationContext(overlays).WithHTTPOverlay(httpOverlay)