handler

package
v0.0.0-...-06cb93a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 8, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var APIServerModule = fx.Options(
	fx.Provide(NewAPIServerHandler))

APIServerModule provides the API Handler module for Michelangelo API Server.

CtrlMgrModule provides the API Handler module for Michelangelo Controller Manager.

Functions

func NewAPIServerHandler

func NewAPIServerHandler(params Params) (api.Handler, error)

NewAPIServerHandler creates an API handler for the API server component. This replaces the legacy newAPIServerHandler function with builder-based construction.

func NewCtrlManagerHandler

func NewCtrlManagerHandler(params Params) (api.Handler, error)

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

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

func NewAPIHandlerFactory(params Params) Factory

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

Create implements K8sHandler.Create by delegating to the controller-runtime client.

func (*K8sHandlerImpl) Delete

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

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

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

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

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

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.

Directories

Path Synopsis
Package handlermocks is a generated GoMock package.
Package handlermocks is a generated GoMock package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL