plugin

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Jul 7, 2025 License: MIT Imports: 11 Imported by: 0

README

Plugin Package Documentation

Overview

The plugin package provides the foundation for Hockeypuck's plugin system. It has been restructured into logical components for better maintainability and now supports httprouter for improved performance.

File Structure

  • interface.go - Core plugin interfaces and contracts
  • types.go - Basic types, dependencies, and configuration structures
  • base.go - BasePlugin implementation for plugins to extend
  • registry.go - Plugin registration and discovery
  • lifecycle.go - Dependency resolution and initialization/shutdown ordering
  • manager.go - High-level plugin management and global registry
  • adapters.go - HTTP handler adapters for httprouter compatibility

HTTP Handler Migration

The plugin system now uses httprouter.Handle for better performance. If your plugin uses standard http.HandlerFunc handlers, you can easily adapt them using the provided adapters.

Using the Adapter
// Old way (no longer works directly)
host.RegisterHandler("/api/endpoint", p.handleRequest)

// New way with adapter
host.RegisterHandler("/api/endpoint", plugin.WrapStandardHandler(p.handleRequest))
Example Plugin Handler
// Your existing handler remains unchanged
func (p *MyPlugin) handleRequest(w http.ResponseWriter, r *http.Request) {
    // Handle the request
    w.Write([]byte("Hello from plugin"))
}

// In your Initialize method
func (p *MyPlugin) Initialize(ctx context.Context, host plugin.PluginHost, config map[string]interface{}) error {
    // Register handlers with the adapter
    host.RegisterHandler("/api/status", plugin.WrapStandardHandler(p.handleStatus))
    host.RegisterHandler("/api/data", plugin.WrapStandardHandler(p.handleData))
    
    return nil
}
Using URL Parameters

If you need access to httprouter's URL parameters, you can create handlers that use them directly:

// Handler that uses httprouter params
func (p *MyPlugin) handleUserRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    userID := ps.ByName("id")
    // Handle the request with the user ID
    w.Write([]byte("User: " + userID))
}

// Register it
host.RegisterHandler("/api/user/:id", plugin.HTTPHandlerWithParamsAdapter(p.handleUserRequest))

Creating a Plugin

Basic Plugin Structure
package myplugin

import (
    "context"
    "net/http"
    
    "github.com/dobrevit/hkp-plugin-core/pkg/plugin"
)

type MyPlugin struct {
    plugin.BasePlugin
    // Your plugin fields
}

func (p *MyPlugin) Initialize(ctx context.Context, host plugin.PluginHost, config map[string]interface{}) error {
    p.SetInfo("my-plugin", "1.0.0", "My awesome plugin")
    
    // Register HTTP handlers
    host.RegisterHandler("/my-plugin/status", plugin.WrapStandardHandler(p.handleStatus))
    
    // Register middleware
    host.RegisterMiddleware("/", p.authMiddleware)
    
    // Subscribe to events
    host.SubscribeEvent("security.threat", p.handleThreatEvent)
    
    p.SetInitialized(true)
    return nil
}

func (p *MyPlugin) handleStatus(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte(`{"status": "ok"}`))
}

func (p *MyPlugin) authMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Authentication logic
        next.ServeHTTP(w, r)
    })
}

func (p *MyPlugin) handleThreatEvent(event plugin.PluginEvent) error {
    // Handle security threat event
    return nil
}

Plugin Dependencies

Plugins can declare dependencies on other plugins:

func (p *MyPlugin) Dependencies() []plugin.PluginDependency {
    return []plugin.PluginDependency{
        {
            Name:     "base-security",
            Version:  "1.0.0",
            Type:     plugin.DependencyRequired,
        },
        {
            Name:     "advanced-features",
            Version:  "2.0.0",
            Type:     plugin.DependencyOptional,
            Optional: true,
        },
    }
}

Testing Plugins

Use the provided mock implementations for testing:

func TestMyPlugin(t *testing.T) {
    host := NewMockPluginHost()
    plugin := &MyPlugin{}
    
    config := map[string]interface{}{
        "setting": "value",
    }
    
    err := plugin.Initialize(context.Background(), host, config)
    if err != nil {
        t.Fatalf("Failed to initialize plugin: %v", err)
    }
    
    // Test your plugin functionality
}

Performance Considerations

The migration to httprouter provides:

  • Faster route matching with radix tree implementation
  • Lower memory allocation per request
  • Built-in support for URL parameters
  • Better performance under high load

Migration Guide

For existing plugins:

  1. Update handler registrations to use plugin.WrapStandardHandler()
  2. No changes needed to handler implementations
  3. Optional: Update handlers to use httprouter.Params for better URL parameter handling
  4. Test thoroughly to ensure compatibility

Best Practices

  1. Always use the BasePlugin for common functionality
  2. Properly handle initialization and shutdown
  3. Use the adapter functions for HTTP handler compatibility
  4. Declare dependencies explicitly
  5. Handle errors gracefully
  6. Use structured logging with appropriate log levels
  7. Write comprehensive tests for your plugin

Documentation

Overview

Package plugin adapters for compatibility

Package plugin base implementation

Package plugin lifecycle management

Package plugin manager implementation

Package plugin registry implementation

Package plugin types and configuration structures

Index

Constants

View Source
const (
	EventEndpointProtectionRequest = events.EventEndpointProtectionRequest
	EventEndpointProtectionUpdate  = events.EventEndpointProtectionUpdate
	EventEndpointAccessDenied      = events.EventEndpointAccessDenied
	EventEndpointAccessGranted     = events.EventEndpointAccessGranted
	EventSecurityThreatDetected    = events.EventSecurityThreatDetected
	EventSecurityAnomalyDetected   = events.EventSecurityAnomalyDetected
)

Legacy constants - use events package instead

Variables

This section is empty.

Functions

func HTTPHandlerAdapter added in v0.0.4

func HTTPHandlerAdapter(handler http.HandlerFunc) httprouter.Handle

HTTPHandlerAdapter adapts a standard http.HandlerFunc to httprouter.Handle This allows plugins to use standard http handlers with httprouter-based hosts

func HTTPHandlerWithParamsAdapter added in v0.0.4

func HTTPHandlerWithParamsAdapter(handler func(http.ResponseWriter, *http.Request, httprouter.Params)) httprouter.Handle

HTTPHandlerWithParamsAdapter adapts a handler that needs access to httprouter params Example usage:

host.RegisterHandler("/user/:id", HTTPHandlerWithParamsAdapter(func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
    userID := ps.ByName("id")
    // ... handle request
}))

func Register

func Register(plugin Plugin)

Register registers a plugin globally

func SetHost

func SetHost(host PluginHost)

SetHost sets the plugin host for the global registry

func WrapStandardHandler added in v0.0.4

func WrapStandardHandler(handler http.HandlerFunc) httprouter.Handle

WrapStandardHandler is a convenience method that wraps a standard http.HandlerFunc for use with httprouter-based plugin hosts

Types

type Alert

type Alert struct {
	Level       string                 `json:"level"`
	Title       string                 `json:"title"`
	Description string                 `json:"description"`
	Timestamp   time.Time              `json:"timestamp"`
	Tags        map[string]string      `json:"tags"`
	Data        map[string]interface{} `json:"data"`
}

Alert represents an alert

type AlertConfig

type AlertConfig struct {
	Provider string                 `json:"provider"`
	Webhook  string                 `json:"webhook"`
	Config   map[string]interface{} `json:"config"`
}

AlertConfig provides configuration for alert providers

type AlertProvider

type AlertProvider interface {
	SendAlert(alert Alert) error
}

AlertProvider interface for alerting

type AuditConfig

type AuditConfig struct {
	Level  string                 `json:"level"`
	Output string                 `json:"output"`
	Config map[string]interface{} `json:"config"`
}

AuditConfig provides configuration for audit logging

type AuditEvent

type AuditEvent struct {
	Timestamp time.Time              `json:"timestamp"`
	User      string                 `json:"user"`
	Action    string                 `json:"action"`
	Resource  string                 `json:"resource"`
	Result    string                 `json:"result"`
	Details   map[string]interface{} `json:"details"`
}

AuditEvent represents an audit event

type AuditLogger

type AuditLogger interface {
	LogEvent(event AuditEvent) error
}

AuditLogger interface for audit logging

type AuthConfig

type AuthConfig struct {
	Type     string                 `json:"type"`
	Provider string                 `json:"provider"`
	Config   map[string]interface{} `json:"config"`
}

AuthConfig provides configuration for authentication providers

type AuthProvider

type AuthProvider interface {
	Authenticate(username, password string) (bool, error)
	ValidateToken(token string) (bool, error)
}

AuthProvider interface for authentication providers

type BasePlugin

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

BasePlugin provides a base implementation for plugins

func (*BasePlugin) Dependencies

func (p *BasePlugin) Dependencies() []PluginDependency

Dependencies returns an empty dependency list by default

func (*BasePlugin) Description

func (p *BasePlugin) Description() string

Description returns the plugin description

func (*BasePlugin) IsInitialized

func (p *BasePlugin) IsInitialized() bool

IsInitialized returns whether the plugin is initialized

func (*BasePlugin) Name

func (p *BasePlugin) Name() string

Name returns the plugin name

func (*BasePlugin) SetInfo

func (p *BasePlugin) SetInfo(name, version, description string)

SetInfo sets the plugin information

func (*BasePlugin) SetInitialized

func (p *BasePlugin) SetInitialized(initialized bool)

SetInitialized sets the initialization status

func (*BasePlugin) Shutdown

func (p *BasePlugin) Shutdown(ctx context.Context) error

Default implementation of Shutdown

func (*BasePlugin) Version

func (p *BasePlugin) Version() string

Version returns the plugin version

type CoreExtensionPlugin

type CoreExtensionPlugin interface {
	Plugin

	// Extend server initialization
	ExtendServerInit(server *Server) error

	// Modify server configuration
	ModifyConfig(config *Settings) error

	// Register custom services
	RegisterServices(host PluginHost) error
}

CoreExtensionPlugin extends fundamental server capabilities

type DashboardConfig

type DashboardConfig struct {
	Type     string                 `json:"type"`
	Endpoint string                 `json:"endpoint"`
	Config   map[string]interface{} `json:"config"`
}

DashboardConfig provides configuration for dashboard providers

type DashboardProvider

type DashboardProvider interface {
	CreateDashboard(config DashboardConfig) error
	UpdateDashboard(id string, config DashboardConfig) error
}

DashboardProvider interface for dashboard providers

type DependencyGraph

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

DependencyGraph represents a dependency graph for plugins

func NewDependencyGraph

func NewDependencyGraph() *DependencyGraph

NewDependencyGraph creates a new dependency graph

func (*DependencyGraph) AddEdge

func (g *DependencyGraph) AddEdge(from, to string)

AddEdge adds an edge from 'from' to 'to'

func (*DependencyGraph) AddNode

func (g *DependencyGraph) AddNode(name string)

AddNode adds a node to the graph

func (*DependencyGraph) TopologicalSort

func (g *DependencyGraph) TopologicalSort() ([]string, error)

TopologicalSort returns a topologically sorted list of nodes

type DependencyType

type DependencyType string

DependencyType represents the type of dependency

const (
	DependencyRequired DependencyType = "required"
	DependencyOptional DependencyType = "optional"
	DependencyConflict DependencyType = "conflict"
)

type EncryptionConfig

type EncryptionConfig struct {
	Algorithm string                 `json:"algorithm"`
	KeySize   int                    `json:"key_size"`
	Config    map[string]interface{} `json:"config"`
}

EncryptionConfig provides configuration for encryption providers

type EncryptionProvider

type EncryptionProvider interface {
	Encrypt(data []byte) ([]byte, error)
	Decrypt(data []byte) ([]byte, error)
}

EncryptionProvider interface for encryption providers

type EndpointProtectionRequest

type EndpointProtectionRequest = events.EndpointProtectionRequest

type Logger

type Logger interface {
	Info(msg string, args ...interface{})
	Warn(msg string, args ...interface{})
	Error(msg string, args ...interface{})
	Debug(msg string, args ...interface{})
}

Logger interface for plugin logging

type MetricsCollector

type MetricsCollector interface {
	Collect() (map[string]interface{}, error)
	Name() string
}

MetricsCollector interface for custom metrics

type MetricsConfig

type MetricsConfig struct {
	Type     string                 `json:"type"`
	Endpoint string                 `json:"endpoint"`
	Config   map[string]interface{} `json:"config"`
}

MetricsConfig provides configuration for metrics collectors

type MiddlewareConfig

type MiddlewareConfig struct {
	Path     string                 `json:"path"`
	Priority int                    `json:"priority"`
	Config   map[string]interface{} `json:"config"`
}

MiddlewareConfig provides configuration for middleware creation

type MiddlewarePlugin

type MiddlewarePlugin interface {
	Plugin

	// Create middleware handler
	CreateMiddleware(config MiddlewareConfig) (func(http.Handler) http.Handler, error)

	// Middleware priority (lower numbers run first)
	Priority() int

	// Paths this middleware applies to
	ApplicablePaths() []string
}

MiddlewarePlugin provides HTTP request/response processing

type MonitoringPlugin

type MonitoringPlugin interface {
	Plugin

	// Custom metrics collectors
	CreateMetricsCollector(config MetricsConfig) (MetricsCollector, error)

	// Alert providers
	CreateAlertProvider(config AlertConfig) (AlertProvider, error)

	// Dashboard providers
	CreateDashboardProvider(config DashboardConfig) (DashboardProvider, error)
}

MonitoringPlugin provides observability enhancements

type Plugin

type Plugin interface {
	// Initialize the plugin with server context and configuration
	Initialize(ctx context.Context, server PluginHost, config map[string]interface{}) error

	// Name returns the unique plugin identifier
	Name() string

	// Version returns the plugin version
	Version() string

	// Description returns human-readable plugin description
	Description() string

	// Dependencies returns required plugin dependencies
	Dependencies() []PluginDependency

	// Shutdown gracefully stops the plugin
	Shutdown(ctx context.Context) error
}

Plugin represents a loadable module that extends Hockeypuck functionality

type PluginDependency

type PluginDependency struct {
	Name     string         `json:"name"`
	Version  string         `json:"version"`
	Type     DependencyType `json:"type"`
	Optional bool           `json:"optional"`
}

PluginDependency represents a plugin dependency

type PluginEvent

type PluginEvent = events.PluginEvent

Legacy types - use events package instead

type PluginEventHandler

type PluginEventHandler = events.PluginEventHandler

type PluginHost

type PluginHost interface {
	// Register middleware handlers (still uses http.Handler for interpose compatibility)
	RegisterMiddleware(path string, middleware func(http.Handler) http.Handler) error

	// Register API endpoints using httprouter.Handle
	RegisterHandler(pattern string, handler httprouter.Handle) error

	// Access storage backend
	Storage() hkpstorage.Storage

	// Access configuration
	Config() *config.Settings

	// Access metrics system
	Metrics() *metrics.Metrics

	// Access logger
	Logger() *log.Logger

	// Register periodic tasks
	RegisterTask(name string, interval time.Duration, task func(context.Context) error) error

	// Publish events to plugin system
	PublishEvent(event events.PluginEvent) error

	// Subscribe to plugin events
	SubscribeEvent(eventType string, handler events.PluginEventHandler) error

	// Subscribe to Hockeypuck-style key change notifications
	SubscribeKeyChanges(callback func(hkpstorage.KeyChange) error) error

	// Convenience methods for common events
	PublishThreatDetected(threat events.ThreatInfo) error
	PublishRateLimitViolation(violation events.RateLimitViolation) error
	PublishZTNAEvent(eventType string, ztnaEvent events.ZTNAEvent) error
}

PluginHost provides server context and services to plugins

type PluginLifecycle

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

PluginLifecycle manages plugin initialization and shutdown

func NewPluginLifecycle

func NewPluginLifecycle(registry *PluginRegistry) *PluginLifecycle

NewPluginLifecycle creates a new plugin lifecycle manager

func (*PluginLifecycle) Initialize

func (l *PluginLifecycle) Initialize(ctx context.Context, configs map[string]map[string]interface{}) error

Initialize initializes plugins in dependency order

func (*PluginLifecycle) Shutdown

func (l *PluginLifecycle) Shutdown(ctx context.Context) error

Shutdown shuts down plugins in reverse dependency order

type PluginManager

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

PluginManager manages the entire plugin system

func NewPluginManager

func NewPluginManager(host PluginHost, logger Logger) *PluginManager

NewPluginManager creates a new plugin manager

func (*PluginManager) GetPlugin

func (pm *PluginManager) GetPlugin(name string) (Plugin, bool)

GetPlugin gets a plugin by name

func (*PluginManager) GetRoutes

func (pm *PluginManager) GetRoutes() map[string]http.HandlerFunc

GetRoutes returns HTTP routes from all plugins

func (*PluginManager) Initialize

func (pm *PluginManager) Initialize(ctx context.Context, configs map[string]map[string]interface{}) error

Initialize initializes all registered plugins

func (*PluginManager) ListPlugins

func (pm *PluginManager) ListPlugins() []Plugin

ListPlugins lists all registered plugins

func (*PluginManager) LoadPlugin

func (pm *PluginManager) LoadPlugin(ctx context.Context, plugin Plugin, config map[string]interface{}) error

LoadPlugin loads and initializes a plugin

func (*PluginManager) Register

func (pm *PluginManager) Register(plugin Plugin) error

Register registers a plugin with the manager

func (*PluginManager) Shutdown

func (pm *PluginManager) Shutdown(ctx context.Context) error

Shutdown shuts down all plugins

type PluginRegistry

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

PluginRegistry manages plugins for a host system

func GetRegistry

func GetRegistry() *PluginRegistry

GetRegistry returns the global plugin registry

func NewPluginRegistry

func NewPluginRegistry(host PluginHost) *PluginRegistry

NewPluginRegistry creates a new plugin registry

func (*PluginRegistry) Get

func (r *PluginRegistry) Get(name string) (Plugin, bool)

Get retrieves a plugin by name

func (*PluginRegistry) Initialize

func (r *PluginRegistry) Initialize(ctx context.Context, configs map[string]map[string]interface{}) error

Initialize initializes all plugins

func (*PluginRegistry) List

func (r *PluginRegistry) List() []Plugin

List returns all registered plugins

func (*PluginRegistry) Register

func (r *PluginRegistry) Register(plugin Plugin) error

Register registers a plugin

func (*PluginRegistry) Shutdown

func (r *PluginRegistry) Shutdown(ctx context.Context) error

Shutdown shuts down all plugins

type SecurityPlugin

type SecurityPlugin interface {
	Plugin

	// Authentication providers
	CreateAuthProvider(config AuthConfig) (AuthProvider, error)

	// Audit logging enhancements
	CreateAuditLogger(config AuditConfig) (AuditLogger, error)

	// Encryption providers
	CreateEncryptionProvider(config EncryptionConfig) (EncryptionProvider, error)
}

SecurityPlugin provides security enhancements

type Server

type Server struct {
}

Server represents the Hockeypuck server (placeholder interface)

type Settings

type Settings = config.Settings

Legacy Settings type - deprecated, use config.Settings instead Kept for backward compatibility

type StorageConfig

type StorageConfig struct {
	Type   string                 `json:"type"`
	Config map[string]interface{} `json:"config"`
}

StorageConfig provides configuration for storage backend creation

type StoragePlugin

type StoragePlugin interface {
	Plugin

	// Create storage backend instance
	CreateStorage(config StorageConfig) (hkpstorage.Storage, error)

	// Backend type identifier
	BackendType() string

	// Required configuration schema
	ConfigSchema() map[string]interface{}
}

StoragePlugin provides custom storage implementations

Jump to

Keyboard shortcuts

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