plugin

package
v1.10.0 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package plugin defines the CloudMock plugin system.

Plugins can be either in-process (Go) or out-of-process (any language via gRPC). Both kinds implement the same Plugin interface. The Manager discovers, loads, and routes requests to the appropriate plugin.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoadExternalPlugins

func LoadExternalPlugins(ctx context.Context, mgr *Manager, dir string, logger *slog.Logger) error

LoadExternalPlugins discovers and starts plugin binaries from the given directory. Each executable file in the directory is treated as a plugin.

Types

type AuthContext

type AuthContext struct {
	UserID      string
	AccountID   string
	ARN         string
	AccessKeyID string
	IsRoot      bool
	Roles       []string
	Claims      map[string]string
}

AuthContext carries the authenticated caller identity.

type Descriptor

type Descriptor struct {
	Name     string            // e.g., "s3", "kubernetes", "argocd"
	Version  string            // semver
	Protocol string            // "aws-json", "aws-query", "k8s-api", "argocd-api"
	Actions  []string          // supported operations
	APIPaths []string          // URL path patterns for path-based routing
	Metadata map[string]string // arbitrary metadata
}

Descriptor describes a plugin's identity and routing rules.

type ExternalPlugin

type ExternalPlugin struct {
	// contains filtered or unexported fields
}

ExternalPlugin wraps an external plugin process that communicates via HTTP. The plugin binary is launched as a subprocess and communicates its listen address via stdout (PLUGIN_ADDR=host:port).

func (*ExternalPlugin) Describe

func (ep *ExternalPlugin) Describe(_ context.Context) (*Descriptor, error)

func (*ExternalPlugin) HandleRequest

func (ep *ExternalPlugin) HandleRequest(_ context.Context, req *Request) (*Response, error)

func (*ExternalPlugin) HealthCheck

func (ep *ExternalPlugin) HealthCheck(_ context.Context) (HealthStatus, string, error)

func (*ExternalPlugin) Init

func (ep *ExternalPlugin) Init(_ context.Context, _ []byte, _ string, _ string) error

func (*ExternalPlugin) Shutdown

func (ep *ExternalPlugin) Shutdown(_ context.Context) error

type GRPCBridge

type GRPCBridge struct {
	// contains filtered or unexported fields
}

GRPCBridge manages an external plugin process that communicates via gRPC.

func NewGRPCBridge

func NewGRPCBridge(cfg GRPCBridgeConfig) *GRPCBridge

NewGRPCBridge creates a bridge to an external plugin. The plugin binary must implement the ServicePlugin gRPC service.

func (*GRPCBridge) Close

func (b *GRPCBridge) Close() error

Close shuts down the gRPC connection and kills the plugin process.

func (*GRPCBridge) Conn

func (b *GRPCBridge) Conn() *grpc.ClientConn

Conn returns the underlying gRPC connection. Returns nil if not connected.

func (*GRPCBridge) Connect

func (b *GRPCBridge) Connect(ctx context.Context, addr string) error

Connect establishes a gRPC connection to the plugin process. Call this after the plugin process has started and is listening.

type GRPCBridgeConfig

type GRPCBridgeConfig struct {
	// BinaryPath is the path to the plugin executable.
	BinaryPath string
	// Args are additional command-line arguments.
	Args []string
	// Addr is the address the plugin will listen on (e.g., "localhost:0" for auto-assign).
	// If empty, the bridge will use a Unix socket.
	Addr string
}

GRPCBridgeConfig holds configuration for launching an external plugin.

type HealthCheckResult

type HealthCheckResult struct {
	Name    string       `json:"name"`
	Status  HealthStatus `json:"status"`
	Message string       `json:"message,omitempty"`
}

HealthCheckResult holds the result of a single plugin health check.

type HealthStatus

type HealthStatus int

HealthStatus represents the health state of a plugin.

const (
	HealthUnknown   HealthStatus = 0
	HealthHealthy   HealthStatus = 1
	HealthDegraded  HealthStatus = 2
	HealthUnhealthy HealthStatus = 3
)

func (HealthStatus) String

func (h HealthStatus) String() string

String returns a human-readable representation of the health status.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager discovers, loads, and manages plugin lifecycle.

func NewManager

func NewManager(logger *slog.Logger) *Manager

NewManager creates a plugin manager.

func (*Manager) HealthCheckAll

func (m *Manager) HealthCheckAll(ctx context.Context) map[string]HealthCheckResult

HealthCheckAll runs health checks on all registered plugins and updates their status.

func (*Manager) List

func (m *Manager) List() []PluginInfo

List returns info about all registered plugins.

func (*Manager) Lookup

func (m *Manager) Lookup(name string) (Plugin, error)

Lookup returns the plugin registered under the given name.

func (*Manager) LookupByPath

func (m *Manager) LookupByPath(path string) (Plugin, error)

LookupByPath finds the plugin whose api_paths best match the given URL path. Returns nil if no path-based plugin matches.

func (*Manager) Names

func (m *Manager) Names() []string

Names returns the names of all registered plugins.

func (*Manager) RegisterInProcess

func (m *Manager) RegisterInProcess(ctx context.Context, p Plugin) error

RegisterInProcess registers a Plugin that runs in-process (Go).

func (*Manager) RegisterServiceAdapter

func (m *Manager) RegisterServiceAdapter(ctx context.Context, adapter *ServiceAdapter) error

RegisterServiceAdapter wraps a service.Service and registers it as an in-process plugin. This is the primary migration path for existing AWS services.

func (*Manager) ShutdownAll

func (m *Manager) ShutdownAll(ctx context.Context)

ShutdownAll shuts down all registered plugins.

type Plugin

type Plugin interface {
	// Init is called once when the plugin is loaded.
	Init(ctx context.Context, config []byte, dataDir string, logLevel string) error

	// Shutdown is called when the core is stopping.
	Shutdown(ctx context.Context) error

	// HealthCheck returns the plugin's current health status.
	HealthCheck(ctx context.Context) (HealthStatus, string, error)

	// Describe returns the plugin's metadata and routing rules.
	Describe(ctx context.Context) (*Descriptor, error)

	// HandleRequest processes a single request.
	HandleRequest(ctx context.Context, req *Request) (*Response, error)
}

Plugin is the interface that all CloudMock plugins implement.

type PluginInfo

type PluginInfo struct {
	Name      string            `json:"name"`
	Version   string            `json:"version"`
	Protocol  string            `json:"protocol"`
	Mode      string            `json:"mode"`
	Healthy   bool              `json:"healthy"`
	Actions   []string          `json:"actions"`
	APIPaths  []string          `json:"api_paths,omitempty"`
	Metadata  map[string]string `json:"metadata,omitempty"`
	LastCheck time.Time         `json:"last_check"`
}

PluginInfo holds metadata about a loaded plugin for the admin API.

type PluginMode

type PluginMode int

PluginMode indicates how a plugin is loaded.

const (
	ModeInProcess    PluginMode = iota // Go plugin loaded in-process
	ModeExternalGRPC                   // External binary via gRPC over stdio
)

func (PluginMode) String

func (m PluginMode) String() string

String returns a human-readable name for the mode.

type Request

type Request struct {
	Action      string
	Body        []byte
	Headers     map[string]string
	QueryParams map[string]string
	Path        string
	Method      string
	Auth        *AuthContext
}

Request carries an incoming HTTP request from the core to a plugin.

type Response

type Response struct {
	StatusCode int
	Body       []byte
	Headers    map[string]string
}

Response carries a plugin's response back to the core.

type ServiceAdapter

type ServiceAdapter struct {
	// contains filtered or unexported fields
}

ServiceAdapter wraps an existing service.Service to implement the Plugin interface. This enables gradual migration: existing Go services work as plugins without rewriting.

func NewServiceAdapter

func NewServiceAdapter(svc service.Service, region, accountID string) *ServiceAdapter

NewServiceAdapter wraps a legacy service.Service as a Plugin.

func (*ServiceAdapter) Describe

func (a *ServiceAdapter) Describe(_ context.Context) (*Descriptor, error)

func (*ServiceAdapter) HandleRequest

func (a *ServiceAdapter) HandleRequest(ctx context.Context, req *Request) (*Response, error)

func (*ServiceAdapter) HealthCheck

func (a *ServiceAdapter) HealthCheck(_ context.Context) (HealthStatus, string, error)

func (*ServiceAdapter) Init

func (a *ServiceAdapter) Init(_ context.Context, _ []byte, _ string, _ string) error

func (*ServiceAdapter) Shutdown

func (a *ServiceAdapter) Shutdown(_ context.Context) error

func (*ServiceAdapter) Unwrap

func (a *ServiceAdapter) Unwrap() service.Service

Unwrap returns the underlying service.Service. This is useful for the registry to access the original service for backward compatibility.

type StreamingPlugin

type StreamingPlugin interface {
	Plugin
	// StreamRequest processes a request that produces multiple responses.
	StreamRequest(ctx context.Context, req *Request, send func(*Response) error) error
}

StreamingPlugin is an optional interface for plugins that support streaming responses (e.g., Kubernetes watch).

Jump to

Keyboard shortcuts

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