Documentation
¶
Index ¶
- Variables
- func NewAPIServerHandler(params Params) (api.Handler, error)
- func NewCtrlManagerHandler(params Params) (api.Handler, error)
- func NewFakeAPIHandler(k8sClient ctrlRTClient.Client) api.Handler
- type APIHandlerBuilder
- func (b *APIHandlerBuilder) Build() (api.Handler, error)
- func (b *APIHandlerBuilder) WithBlobStorage(storage storage.BlobStorage) *APIHandlerBuilder
- func (b *APIHandlerBuilder) WithK8sClient(client ctrlRTClient.Client) *APIHandlerBuilder
- func (b *APIHandlerBuilder) WithLogger(logger logr.Logger) *APIHandlerBuilder
- func (b *APIHandlerBuilder) WithMetadataStorage(storage storage.MetadataStorage, config storage.MetadataStorageConfig) *APIHandlerBuilder
- func (b *APIHandlerBuilder) WithMetrics(scope tally.Scope) *APIHandlerBuilder
- func (b *APIHandlerBuilder) WithZapLogger(logger *zap.Logger) *APIHandlerBuilder
- type BlobHandler
- type BlobHandlerImpl
- type Factory
- type K8sHandler
- type K8sHandlerImpl
- func (k *K8sHandlerImpl) Create(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.CreateOptions) error
- func (k *K8sHandlerImpl) Delete(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.DeleteOptions) error
- func (k *K8sHandlerImpl) DeleteCollection(ctx context.Context, objType ctrlRTClient.Object, namespace string, ...) error
- func (k *K8sHandlerImpl) Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
- func (k *K8sHandlerImpl) List(ctx context.Context, namespace string, opts *metav1.ListOptions, ...) error
- func (k *K8sHandlerImpl) Update(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.UpdateOptions) error
- func (k *K8sHandlerImpl) UpdateStatus(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.UpdateOptions) error
- type MetadataHandler
- type MetadataHandlerImpl
- func (m *MetadataHandlerImpl) Delete(ctx context.Context, obj ctrlRTClient.Object) error
- func (m *MetadataHandlerImpl) Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
- func (m *MetadataHandlerImpl) List(ctx context.Context, namespace string, opts *metav1.ListOptions, ...) error
- func (m *MetadataHandlerImpl) Update(ctx context.Context, obj ctrlRTClient.Object) error
- type NullBlobHandler
- type NullMetadataHandler
- func (n *NullMetadataHandler) Delete(ctx context.Context, obj ctrlRTClient.Object) error
- func (n *NullMetadataHandler) Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
- func (n *NullMetadataHandler) List(ctx context.Context, namespace string, opts *metav1.ListOptions, ...) error
- func (n *NullMetadataHandler) Update(ctx context.Context, obj ctrlRTClient.Object) error
- type Params
- type Result
- type ValidationHandler
- type ValidationHandlerImpl
Constants ¶
This section is empty.
Variables ¶
var APIServerModule = fx.Options( fx.Provide(NewAPIServerHandler))
APIServerModule provides the API Handler module for Michelangelo API Server.
var CtrlMgrModule = fx.Options( fx.Provide(NewCtrlManagerHandler, NewAPIHandlerFactory))
CtrlMgrModule provides the API Handler module for Michelangelo Controller Manager.
Functions ¶
func NewAPIServerHandler ¶
NewAPIServerHandler creates an API handler for the API server component. This replaces the legacy newAPIServerHandler function with builder-based construction.
func NewCtrlManagerHandler ¶
NewCtrlManagerHandler creates an API handler for the controller manager component. This replaces the legacy newCtrlManagerHandler function with builder-based construction.
func NewFakeAPIHandler ¶
func NewFakeAPIHandler(k8sClient ctrlRTClient.Client) api.Handler
NewFakeAPIHandler creates an API handler with the provided k8s client. This is used for unit test only.
Types ¶
type APIHandlerBuilder ¶
type APIHandlerBuilder struct {
// contains filtered or unexported fields
}
APIHandlerBuilder builds API handlers using the builder pattern.
This builder provides a fluent interface for configuring API handlers with optional dependencies, replacing factory pattern anti-patterns with clean composition. The design is inspired by Kubernetes REST client builders and Flyte's configuration patterns.
Example usage:
handler, err := NewAPIHandlerBuilder().
WithK8sClient(client).
WithMetadataStorage(storage, config).
WithZapLogger(logger).
Build()
if err != nil {
return fmt.Errorf("failed to build handler: %w", err)
}
func NewAPIHandlerBuilder ¶
func NewAPIHandlerBuilder() *APIHandlerBuilder
NewAPIHandlerBuilder creates a new API handler builder with sensible defaults. The builder is configured with no-op logger and metrics scope by default, requiring only a Kubernetes client to produce a functional handler.
func (*APIHandlerBuilder) Build ¶
func (b *APIHandlerBuilder) Build() (api.Handler, error)
Build creates the API handler with focused, composed handlers. Returns an error if required dependencies are missing or invalid. The returned handler is ready for use and thread-safe.
func (*APIHandlerBuilder) WithBlobStorage ¶
func (b *APIHandlerBuilder) WithBlobStorage(storage storage.BlobStorage) *APIHandlerBuilder
WithBlobStorage enables and configures blob storage.
func (*APIHandlerBuilder) WithK8sClient ¶
func (b *APIHandlerBuilder) WithK8sClient(client ctrlRTClient.Client) *APIHandlerBuilder
WithK8sClient sets the Kubernetes client (required). The client must be properly configured with the appropriate scheme and credentials.
func (*APIHandlerBuilder) WithLogger ¶
func (b *APIHandlerBuilder) WithLogger(logger logr.Logger) *APIHandlerBuilder
WithLogger sets the logger for structured logging.
func (*APIHandlerBuilder) WithMetadataStorage ¶
func (b *APIHandlerBuilder) WithMetadataStorage(storage storage.MetadataStorage, config storage.MetadataStorageConfig) *APIHandlerBuilder
WithMetadataStorage enables and configures metadata storage. Both storage implementation and config must be provided when metadata storage is enabled.
func (*APIHandlerBuilder) WithMetrics ¶
func (b *APIHandlerBuilder) WithMetrics(scope tally.Scope) *APIHandlerBuilder
WithMetrics enables metrics collection with the provided scope.
func (*APIHandlerBuilder) WithZapLogger ¶
func (b *APIHandlerBuilder) WithZapLogger(logger *zap.Logger) *APIHandlerBuilder
WithZapLogger sets a zap logger (convenience method).
type BlobHandler ¶
type BlobHandler interface {
// IsObjectInteresting determines if an object should be stored in blob storage.
// This typically checks object size, type, or annotations to make the decision.
IsObjectInteresting(obj ctrlRTClient.Object) bool
// MergeWithExternalBlob retrieves blob data and merges it with the object.
// This is used during object retrieval to reconstitute the complete object.
MergeWithExternalBlob(ctx context.Context, obj ctrlRTClient.Object) error
// DeleteFromBlobStorage removes blob data associated with an object.
// This is called during object deletion to prevent storage leaks.
DeleteFromBlobStorage(ctx context.Context, obj ctrlRTClient.Object) error
}
BlobHandler abstracts blob storage operations for large object data.
This interface supports storing large objects separately from metadata using backends like S3 or GCS, following patterns used by Kubernetes for objects that exceed etcd size limits or require specialized storage characteristics.
Example usage:
handler := NewBlobHandler(storage)
if handler.IsObjectInteresting(obj) {
if err := handler.MergeWithExternalBlob(ctx, obj); err != nil {
return fmt.Errorf("failed to merge blob data: %w", err)
}
}
func NewBlobHandler ¶
func NewBlobHandler(storage storage.BlobStorage) BlobHandler
NewBlobHandler creates a new BlobHandler implementation. If storage is nil, returns a NullBlobHandler that provides safe no-op behavior.
type BlobHandlerImpl ¶
type BlobHandlerImpl struct {
// contains filtered or unexported fields
}
BlobHandlerImpl implements the BlobHandler interface by delegating to the configured blob storage backend. This provides a consistent abstraction layer for blob operations while supporting different storage implementations.
func (*BlobHandlerImpl) DeleteFromBlobStorage ¶
func (b *BlobHandlerImpl) DeleteFromBlobStorage(ctx context.Context, obj ctrlRTClient.Object) error
DeleteFromBlobStorage implements BlobHandler.DeleteFromBlobStorage by delegating to the storage backend.
func (*BlobHandlerImpl) IsObjectInteresting ¶
func (b *BlobHandlerImpl) IsObjectInteresting(obj ctrlRTClient.Object) bool
IsObjectInteresting implements BlobHandler.IsObjectInteresting by delegating to the storage backend.
func (*BlobHandlerImpl) MergeWithExternalBlob ¶
func (b *BlobHandlerImpl) MergeWithExternalBlob(ctx context.Context, obj ctrlRTClient.Object) error
MergeWithExternalBlob implements BlobHandler.MergeWithExternalBlob by delegating to the storage backend.
type Factory ¶
type Factory interface {
GetAPIHandler(client ctrlRTClient.Client) (api.Handler, error)
}
Factory interface that controllers can use to create handlers with different K8s clients
func NewAPIHandlerFactory ¶
NewAPIHandlerFactory creates a factory that controllers can use to build handlers This provides the same interface as the old factory pattern but uses the builder internally
type K8sHandler ¶
type K8sHandler interface {
// Create creates a new object in the Kubernetes cluster.
// Returns an error if the object already exists or creation fails.
Create(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.CreateOptions) error
// Get retrieves an object from the Kubernetes cluster by namespace and name.
// Returns NotFound error if the object doesn't exist.
Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
// Update updates an existing object in the Kubernetes cluster.
// Uses optimistic concurrency control based on resourceVersion.
Update(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.UpdateOptions) error
// UpdateStatus updates only the status subresource of an object.
// This is separated from spec updates to avoid conflicts in controllers.
UpdateStatus(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.UpdateOptions) error
// Delete removes an object from the Kubernetes cluster.
// Supports graceful deletion with configurable grace periods.
Delete(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.DeleteOptions) error
// List retrieves a list of objects matching the given criteria.
// Supports field and label selectors, pagination, and namespace scoping.
List(ctx context.Context, namespace string, opts *metav1.ListOptions, list ctrlRTClient.ObjectList) error
// DeleteCollection removes multiple objects matching the given criteria.
// Combines listing and deletion operations with proper error handling.
DeleteCollection(ctx context.Context, objType ctrlRTClient.Object, namespace string, deleteOpts *metav1.DeleteOptions, listOpts *metav1.ListOptions) error
}
K8sHandler abstracts Kubernetes API operations for improved testability and separation of concerns.
This interface follows the adapter pattern commonly used in Kubernetes operators and maintains the same semantics as controller-runtime client.Client. All operations support standard Kubernetes features like optimistic concurrency, field/label selectors, and graceful deletion.
Example usage:
handler := NewK8sHandler(client)
if err := handler.Create(ctx, obj, &metav1.CreateOptions{}); err != nil {
return fmt.Errorf("failed to create object: %w", err)
}
func NewK8sHandler ¶
func NewK8sHandler(client ctrlRTClient.Client) K8sHandler
NewK8sHandler creates a new K8sHandler implementation. The provided client should be properly configured with the appropriate scheme and authentication for the target Kubernetes cluster.
type K8sHandlerImpl ¶
type K8sHandlerImpl struct {
// contains filtered or unexported fields
}
K8sHandlerImpl implements the K8sHandler interface by delegating to a controller-runtime client. This provides a clean abstraction layer for Kubernetes operations while maintaining full compatibility with the controller-runtime ecosystem.
func (*K8sHandlerImpl) Create ¶
func (k *K8sHandlerImpl) Create(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.CreateOptions) error
Create implements K8sHandler.Create by delegating to the controller-runtime client.
func (*K8sHandlerImpl) Delete ¶
func (k *K8sHandlerImpl) Delete(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.DeleteOptions) error
Delete implements K8sHandler.Delete by delegating to the controller-runtime client.
func (*K8sHandlerImpl) DeleteCollection ¶
func (k *K8sHandlerImpl) DeleteCollection(ctx context.Context, objType ctrlRTClient.Object, namespace string, deleteOpts *metav1.DeleteOptions, listOpts *metav1.ListOptions) error
DeleteCollection implements K8sHandler.DeleteCollection by delegating to the controller-runtime client.
func (*K8sHandlerImpl) Get ¶
func (k *K8sHandlerImpl) Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
Get implements K8sHandler.Get by delegating to the controller-runtime client.
func (*K8sHandlerImpl) List ¶
func (k *K8sHandlerImpl) List(ctx context.Context, namespace string, opts *metav1.ListOptions, list ctrlRTClient.ObjectList) error
List implements K8sHandler.List by delegating to the controller-runtime client.
func (*K8sHandlerImpl) Update ¶
func (k *K8sHandlerImpl) Update(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.UpdateOptions) error
Update implements K8sHandler.Update by delegating to the controller-runtime client.
func (*K8sHandlerImpl) UpdateStatus ¶
func (k *K8sHandlerImpl) UpdateStatus(ctx context.Context, obj ctrlRTClient.Object, opts *metav1.UpdateOptions) error
UpdateStatus implements K8sHandler.UpdateStatus by delegating to the status writer.
type MetadataHandler ¶
type MetadataHandler interface {
// Get retrieves an object from the metadata storage by namespace and name.
// This is typically used as a fallback when objects are not found in Kubernetes.
Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
// Update persists or updates an object in the metadata storage.
// This operation is idempotent and handles both creation and updates.
Update(ctx context.Context, obj ctrlRTClient.Object) error
// Delete removes an object from the metadata storage.
// This may also trigger cleanup of associated blob storage if configured.
Delete(ctx context.Context, obj ctrlRTClient.Object) error
// List retrieves objects from metadata storage matching the given criteria.
// Supports the same filtering options as the Kubernetes API, with optional extended options.
List(ctx context.Context, namespace string, opts *metav1.ListOptions, listOptionsExt *apipb.ListOptionsExt, list ctrlRTClient.ObjectList) error
}
MetadataHandler abstracts metadata storage operations for pluggable storage backends.
This interface enables persisting object metadata beyond the Kubernetes API server lifecycle, supporting features like soft deletion and extended retention policies. The storage layer maintains consistency with Kubernetes API semantics.
Example usage:
handler := NewMetadataHandler(storage, blobStorage, logger)
if err := handler.Update(ctx, obj); err != nil {
return fmt.Errorf("failed to persist metadata: %w", err)
}
func NewMetadataHandler ¶
func NewMetadataHandler(storage storage.MetadataStorage, blobStorage storage.BlobStorage, logger logr.Logger) MetadataHandler
NewMetadataHandler creates a new MetadataHandler implementation. If storage is nil, returns a NullMetadataHandler that provides safe no-op behavior. The blobStorage and logger are used for integrated blob operations and observability.
type MetadataHandlerImpl ¶
type MetadataHandlerImpl struct {
// contains filtered or unexported fields
}
MetadataHandlerImpl implements the MetadataHandler interface by delegating to the configured metadata storage backend. This provides a consistent abstraction layer for metadata operations while supporting different storage implementations.
func (*MetadataHandlerImpl) Delete ¶
func (m *MetadataHandlerImpl) Delete(ctx context.Context, obj ctrlRTClient.Object) error
Delete implements MetadataHandler.Delete by delegating to the handleDelete function.
func (*MetadataHandlerImpl) Get ¶
func (m *MetadataHandlerImpl) Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
Get implements MetadataHandler.Get by delegating to the storage backend.
func (*MetadataHandlerImpl) List ¶
func (m *MetadataHandlerImpl) List(ctx context.Context, namespace string, opts *metav1.ListOptions, listOptionsExt *apipb.ListOptionsExt, list ctrlRTClient.ObjectList) error
List implements MetadataHandler.List by delegating to the storage backend.
func (*MetadataHandlerImpl) Update ¶
func (m *MetadataHandlerImpl) Update(ctx context.Context, obj ctrlRTClient.Object) error
Update implements MetadataHandler.Update by delegating to the handleUpdate function.
type NullBlobHandler ¶
type NullBlobHandler struct{}
NullBlobHandler provides a safe no-op implementation of BlobHandler. This is used when blob storage is disabled, ensuring that the system continues to function while gracefully handling the absence of blob storage.
func (*NullBlobHandler) DeleteFromBlobStorage ¶
func (n *NullBlobHandler) DeleteFromBlobStorage(ctx context.Context, obj ctrlRTClient.Object) error
DeleteFromBlobStorage implements BlobHandler.DeleteFromBlobStorage as a no-op when blob storage is disabled.
func (*NullBlobHandler) IsObjectInteresting ¶
func (n *NullBlobHandler) IsObjectInteresting(obj ctrlRTClient.Object) bool
IsObjectInteresting implements BlobHandler.IsObjectInteresting by always returning false. When blob storage is disabled, no objects are considered interesting for blob storage.
func (*NullBlobHandler) MergeWithExternalBlob ¶
func (n *NullBlobHandler) MergeWithExternalBlob(ctx context.Context, obj ctrlRTClient.Object) error
MergeWithExternalBlob implements BlobHandler.MergeWithExternalBlob as a no-op when blob storage is disabled.
type NullMetadataHandler ¶
type NullMetadataHandler struct{}
NullMetadataHandler provides a safe no-op implementation of MetadataHandler. This is used when metadata storage is disabled, ensuring that the system continues to function while gracefully handling the absence of metadata storage.
func (*NullMetadataHandler) Delete ¶
func (n *NullMetadataHandler) Delete(ctx context.Context, obj ctrlRTClient.Object) error
Delete implements MetadataHandler.Delete as a no-op when metadata storage is disabled.
func (*NullMetadataHandler) Get ¶
func (n *NullMetadataHandler) Get(ctx context.Context, namespace, name string, obj ctrlRTClient.Object) error
Get implements MetadataHandler.Get by returning a NotFound error. This maintains API consistency when metadata storage is disabled.
func (*NullMetadataHandler) List ¶
func (n *NullMetadataHandler) List(ctx context.Context, namespace string, opts *metav1.ListOptions, listOptionsExt *apipb.ListOptionsExt, list ctrlRTClient.ObjectList) error
List implements MetadataHandler.List by returning a NotFound error. This maintains API consistency when metadata storage is disabled.
func (*NullMetadataHandler) Update ¶
func (n *NullMetadataHandler) Update(ctx context.Context, obj ctrlRTClient.Object) error
Update implements MetadataHandler.Update as a no-op when metadata storage is disabled.
type Params ¶
type Params struct {
fx.In
Manager ctrl.Manager `optional:"true"`
K8sRestConfig *rest.Config
Scheme *runtime.Scheme
StorageConfig storage.MetadataStorageConfig
MetadataStorage storage.MetadataStorage `optional:"true"`
BlobStorage storage.BlobStorage `optional:"true"`
Logger *zap.Logger
Metrics tally.Scope
}
Params are the dependencies to build API handler library
type Result ¶
type Result struct {
fx.Out
Scheme *runtime.Scheme
GroupVersion runtime.GroupVersioner
IndexMaps []map[schema.GroupVersionKind]map[string]string `group:"indexMaps,flatten"`
}
Result provides the CRD scheme related dependencies generated by GetCRDScheme
type ValidationHandler ¶
type ValidationHandler interface {
// ValidateCreate validates an object before creation.
// This includes schema validation, business rules, and resource constraints.
ValidateCreate(obj ctrlRTClient.Object) error
// ValidateUpdate validates an object before updates.
// This may include additional checks for immutable fields and state transitions.
ValidateUpdate(obj ctrlRTClient.Object) error
// ValidateDelete validates whether an object can be safely deleted.
// This may check for dependencies, finalizers, or business constraints.
ValidateDelete(obj ctrlRTClient.Object) error
}
ValidationHandler abstracts object validation operations for consistent validation logic.
This interface centralizes validation across API operations, following patterns used by Kubernetes admission controllers. Validation ensures data integrity and business rule compliance before persisting objects.
Example usage:
handler := NewValidationHandler()
if err := handler.ValidateCreate(obj); err != nil {
return fmt.Errorf("validation failed: %w", err)
}
func NewValidationHandler ¶
func NewValidationHandler() ValidationHandler
NewValidationHandler creates a new ValidationHandler implementation. The implementation is stateless and safe for concurrent use.
type ValidationHandlerImpl ¶
type ValidationHandlerImpl struct{}
ValidationHandlerImpl implements the ValidationHandler interface by delegating to the existing validation functions. This provides a consistent abstraction layer for validation operations while maintaining compatibility with existing validation logic.
func (*ValidationHandlerImpl) ValidateCreate ¶
func (v *ValidationHandlerImpl) ValidateCreate(obj ctrlRTClient.Object) error
ValidateCreate implements ValidationHandler.ValidateCreate by delegating to the api.Validate function.
func (*ValidationHandlerImpl) ValidateDelete ¶
func (v *ValidationHandlerImpl) ValidateDelete(obj ctrlRTClient.Object) error
ValidateDelete implements ValidationHandler.ValidateDelete as a no-op. Currently no specific delete validation is required, but this provides a hook for future validation requirements.
func (*ValidationHandlerImpl) ValidateUpdate ¶
func (v *ValidationHandlerImpl) ValidateUpdate(obj ctrlRTClient.Object) error
ValidateUpdate implements ValidationHandler.ValidateUpdate by delegating to the api.Validate function.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package handlermocks is a generated GoMock package.
|
Package handlermocks is a generated GoMock package. |