Documentation
¶
Overview ¶
Package plugincontrol contains the Control-side runtime boundary for officially signed packages. The kernel owns admission and authorization; this package only executes an already admitted, version-bound request.
Index ¶
- Constants
- Variables
- func QueueDependencyLifecyclePlan(tx *gorm.DB, request DependencyLifecyclePlanRequest) (*model.KernelOperation, error)
- type ArtifactRefResolver
- type ConfigurationValidator
- type DependencyLifecyclePlanRequest
- type Executor
- type GostMeshExecutor
- func (e *GostMeshExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
- func (e *GostMeshExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
- func (e *GostMeshExecutor) PluginID() string
- func (e *GostMeshExecutor) ValidateConfiguration(ctx context.Context, raw json.RawMessage) error
- func (e *GostMeshExecutor) Version() string
- type GostMeshStatus
- type GostMeshSummary
- type GostMeshTunnelStatus
- type HostLifecycleDispatcher
- type LifecycleDispatcher
- type LifecycleRequest
- type MachineTelemetryExecutor
- func (e *MachineTelemetryExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
- func (e *MachineTelemetryExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
- func (e *MachineTelemetryExecutor) PluginID() string
- func (e *MachineTelemetryExecutor) Version() string
- type MachineTelemetryNode
- type MachineTelemetryStatus
- type MachineTelemetrySummary
- type NatEgressExecutor
- func (e *NatEgressExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
- func (e *NatEgressExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
- func (e *NatEgressExecutor) PluginID() string
- func (e *NatEgressExecutor) Version() string
- type NatEgressExitStatus
- type NatEgressStatus
- type NatEgressSummary
- type NftablesForwardExecutor
- func (e *NftablesForwardExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
- func (e *NftablesForwardExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
- func (e *NftablesForwardExecutor) PluginID() string
- func (e *NftablesForwardExecutor) ValidateConfiguration(ctx context.Context, raw json.RawMessage) error
- func (e *NftablesForwardExecutor) Version() string
- type NftablesForwardRuleStatus
- type NftablesForwardStatus
- type NftablesForwardSummary
- type OperationWorker
- type Registry
- func (r *Registry) ExecuteLifecycle(ctx context.Context, pluginID, version string, request LifecycleRequest) (json.RawMessage, error)
- func (r *Registry) ExecuteRoute(ctx context.Context, pluginID, version string, request RouteRequest) (RouteResponse, error)
- func (r *Registry) Lookup(pluginID, version string) (Executor, bool)
- func (r *Registry) Register(executor Executor) error
- func (r *Registry) ValidateConfiguration(ctx context.Context, pluginID, version string, config json.RawMessage) error
- type RouteRequest
- type RouteResponse
Constants ¶
const ( GostMeshPluginID = "gost-mesh" GostMeshVersion = "1.0.0" GostMeshStatusRoute = "/api/v3/plugins/gost-mesh/status" )
const ( MachineTelemetryPluginID = "machine-telemetry" MachineTelemetryVersion = "1.1.0" MachineTelemetryLegacyVersion = "1.0.0" MachineTelemetryStatusRoute = "/api/v3/plugins/machine-telemetry/status" )
const ( NatEgressPluginID = "nat-egress" NatEgressVersion = "1.0.0" NatEgressStatusRoute = "/api/v3/plugins/nat-egress/status" )
const ( NftablesForwardPluginID = "nftables-forward" NftablesForwardVersion = "1.2.0" NftablesForwardLegacyVersion = "1.0.0" NftablesForwardStatusRoute = "/api/v3/plugins/nftables-forward/status" )
Variables ¶
var ( ErrExecutorNotFound = errors.New("control plugin executor is not installed") ErrConfigurationValidatorNotFound = errors.New("control plugin configuration validator is not installed for this version") ErrRouteNotFound = errors.New("control plugin route is not implemented by the executor") ErrMethodNotAllowed = errors.New("control plugin route does not allow this method") ErrInvalidPluginInput = errors.New("control plugin request is invalid") )
Functions ¶
func QueueDependencyLifecyclePlan ¶
func QueueDependencyLifecyclePlan(tx *gorm.DB, request DependencyLifecyclePlanRequest) (*model.KernelOperation, error)
QueueDependencyLifecyclePlan converts a recursive dependency closure into durable Control operations. It is intentionally called only while holding the target lock in the HTTP handler. The returned operation is the root's final lifecycle action, so existing operation APIs continue to represent the user-visible request while the plan retains its dependent work.
Types ¶
type ArtifactRefResolver ¶
type ArtifactRefResolver func(context.Context, string, string) (pluginhost.ArtifactRef, error)
ArtifactRefResolver supplies the immutable materialized host files for an installed package. Task 4 owns resolving the v2 manifest entrypoint fields; without one, lifecycle execution deliberately fails closed.
type ConfigurationValidator ¶
type ConfigurationValidator interface {
ValidateConfiguration(context.Context, json.RawMessage) error
}
ConfigurationValidator is optional. Registries only invoke it for the exact executor version selected by the signed installation release.
type DependencyLifecyclePlanRequest ¶
type DependencyLifecyclePlanRequest struct {
RootInstallation model.PluginInstallation
PreviousRootInstallation *model.PluginInstallation
RootRelease model.PluginRelease
RootKind string
IdempotencyKey string
DeadlineAt time.Time
}
DependencyLifecyclePlanRequest describes one Control-target root action. RootInstallation has already been persisted with the requested intent. The pre-mutation copy is retained so a failed closure can restore exact desired state without purging package data.
type Executor ¶
type Executor interface {
PluginID() string
Version() string
HandleRoute(context.Context, RouteRequest) (RouteResponse, error)
ExecuteLifecycle(context.Context, LifecycleRequest) (json.RawMessage, error)
}
Executor is the smallest Control package runtime contract. A package may expose no backend route, but lifecycle operations are always version-bound.
type GostMeshExecutor ¶
type GostMeshExecutor struct {
// contains filtered or unexported fields
}
func NewGostMeshExecutor ¶
func NewGostMeshExecutor(db *gorm.DB) *GostMeshExecutor
func (*GostMeshExecutor) ExecuteLifecycle ¶
func (e *GostMeshExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
func (*GostMeshExecutor) HandleRoute ¶
func (e *GostMeshExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
func (*GostMeshExecutor) PluginID ¶
func (e *GostMeshExecutor) PluginID() string
func (*GostMeshExecutor) ValidateConfiguration ¶
func (e *GostMeshExecutor) ValidateConfiguration(ctx context.Context, raw json.RawMessage) error
func (*GostMeshExecutor) Version ¶
func (e *GostMeshExecutor) Version() string
type GostMeshStatus ¶
type GostMeshStatus struct {
PluginID string `json:"plugin_id"`
Version string `json:"version"`
GeneratedAt time.Time `json:"generated_at"`
Summary GostMeshSummary `json:"summary"`
Tunnels []GostMeshTunnelStatus `json:"tunnels"`
}
type GostMeshSummary ¶
type GostMeshTunnelStatus ¶
type GostMeshTunnelStatus struct {
ID string `json:"id"`
Name string `json:"name"`
NodeID uint `json:"node_id"`
Role string `json:"role"`
EntryNode string `json:"entry_node,omitempty"`
ExitNode string `json:"exit_node,omitempty"`
Transport string `json:"transport,omitempty"`
Listen string `json:"listen,omitempty"`
Upstream string `json:"upstream,omitempty"`
DesiredVersion string `json:"desired_version,omitempty"`
ObservedVersion string `json:"observed_version,omitempty"`
DesiredRevision int64 `json:"desired_revision"`
ObservedRevision int64 `json:"observed_revision"`
Health string `json:"health"`
Ready bool `json:"ready"`
Reconciling bool `json:"reconciling"`
CleanupPending bool `json:"cleanup_pending"`
RollbackRequired bool `json:"rollback_required"`
LastError string `json:"last_error,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
}
type HostLifecycleDispatcher ¶
type HostLifecycleDispatcher struct {
// contains filtered or unexported fields
}
HostLifecycleDispatcher maps the existing durable lifecycle operations onto the narrow host manager API. It never looks up or falls back to Registry.
func NewHostLifecycleDispatcher ¶
func NewHostLifecycleDispatcher(hosts pluginhost.Manager, artifacts ArtifactRefResolver) *HostLifecycleDispatcher
func (*HostLifecycleDispatcher) ExecuteLifecycle ¶
func (d *HostLifecycleDispatcher) ExecuteLifecycle(ctx context.Context, pluginID, version string, request LifecycleRequest) (json.RawMessage, error)
type LifecycleDispatcher ¶
type LifecycleDispatcher interface {
ExecuteLifecycle(context.Context, string, string, LifecycleRequest) (json.RawMessage, error)
}
LifecycleDispatcher is the durable-operation execution boundary. Registry remains an implementation for fixtures during the transition, while the production server injects HostLifecycleDispatcher.
type LifecycleRequest ¶
type LifecycleRequest struct {
OperationID string
Kind string
Target string
Generation uint64
Config json.RawMessage
}
LifecycleRequest is the durable-operation input shared by Control package executors. Config is canonical JSON and OperationID is stable across retry.
type MachineTelemetryExecutor ¶
type MachineTelemetryExecutor struct {
// contains filtered or unexported fields
}
MachineTelemetryExecutor is the first complete Control-side reference package. It is intentionally read-only: metrics come from the existing node heartbeat table, so enabling it cannot alter proxy or forwarding traffic.
func NewMachineTelemetryExecutor ¶
func NewMachineTelemetryExecutor(db *gorm.DB) *MachineTelemetryExecutor
func NewMachineTelemetryExecutorVersion ¶
func NewMachineTelemetryExecutorVersion(db *gorm.DB, version string) *MachineTelemetryExecutor
func (*MachineTelemetryExecutor) ExecuteLifecycle ¶
func (e *MachineTelemetryExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
func (*MachineTelemetryExecutor) HandleRoute ¶
func (e *MachineTelemetryExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
func (*MachineTelemetryExecutor) PluginID ¶
func (e *MachineTelemetryExecutor) PluginID() string
func (*MachineTelemetryExecutor) Version ¶
func (e *MachineTelemetryExecutor) Version() string
type MachineTelemetryNode ¶
type MachineTelemetryNode struct {
ID uint `json:"id"`
Name string `json:"name"`
Host string `json:"host"`
Status model.NodeStatus `json:"status"`
Online bool `json:"online"`
RuntimeHealthy bool `json:"runtime_healthy"`
RuntimeError string `json:"runtime_error,omitempty"`
CPUUsage float64 `json:"cpu_usage"`
MemoryUsage float64 `json:"memory_usage"`
DiskUsage float64 `json:"disk_usage"`
Uptime int64 `json:"uptime"`
OnlineUsers int `json:"online_users"`
LastCheckAt *int64 `json:"last_check_at,omitempty"`
UpdatedAt time.Time `json:"updated_at"`
TelemetryAvailable bool `json:"telemetry_available"`
TelemetryStale bool `json:"telemetry_stale"`
TelemetrySource string `json:"telemetry_source"`
TelemetryObservedAt *time.Time `json:"telemetry_observed_at,omitempty"`
TelemetryError string `json:"telemetry_error,omitempty"`
}
type MachineTelemetryStatus ¶
type MachineTelemetryStatus struct {
PluginID string `json:"plugin_id"`
Version string `json:"version"`
GeneratedAt time.Time `json:"generated_at"`
Summary MachineTelemetrySummary `json:"summary"`
Nodes []MachineTelemetryNode `json:"nodes"`
}
type MachineTelemetrySummary ¶
type NatEgressExecutor ¶
type NatEgressExecutor struct {
// contains filtered or unexported fields
}
func NewNatEgressExecutor ¶
func NewNatEgressExecutor(db *gorm.DB) *NatEgressExecutor
func (*NatEgressExecutor) ExecuteLifecycle ¶
func (e *NatEgressExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
func (*NatEgressExecutor) HandleRoute ¶
func (e *NatEgressExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
func (*NatEgressExecutor) PluginID ¶
func (e *NatEgressExecutor) PluginID() string
func (*NatEgressExecutor) Version ¶
func (e *NatEgressExecutor) Version() string
type NatEgressExitStatus ¶
type NatEgressExitStatus struct {
ID string `json:"id"`
Name string `json:"name"`
NodeID uint `json:"node_id"`
NodeName string `json:"node_name"`
EgressInterface string `json:"egress_interface,omitempty"`
PublicIP string `json:"public_ip,omitempty"`
PolicyTable int `json:"policy_table,omitempty"`
Health string `json:"health"`
Ready bool `json:"ready"`
Degraded bool `json:"degraded"`
CleanupPending bool `json:"cleanup_pending"`
RollbackRequired bool `json:"rollback_required"`
DesiredRevision int64 `json:"desired_revision"`
ObservedRevision int64 `json:"observed_revision"`
LastError string `json:"last_error,omitempty"`
}
type NatEgressStatus ¶
type NatEgressStatus struct {
PluginID string `json:"plugin_id"`
Version string `json:"version"`
GeneratedAt time.Time `json:"generated_at"`
Summary NatEgressSummary `json:"summary"`
Exits []NatEgressExitStatus `json:"exits"`
}
type NatEgressSummary ¶
type NftablesForwardExecutor ¶
type NftablesForwardExecutor struct {
// contains filtered or unexported fields
}
func NewNftablesForwardExecutor ¶
func NewNftablesForwardExecutor(db *gorm.DB) *NftablesForwardExecutor
func NewNftablesForwardExecutorVersion ¶
func NewNftablesForwardExecutorVersion(db *gorm.DB, version string) *NftablesForwardExecutor
func (*NftablesForwardExecutor) ExecuteLifecycle ¶
func (e *NftablesForwardExecutor) ExecuteLifecycle(ctx context.Context, request LifecycleRequest) (json.RawMessage, error)
func (*NftablesForwardExecutor) HandleRoute ¶
func (e *NftablesForwardExecutor) HandleRoute(_ context.Context, request RouteRequest) (RouteResponse, error)
func (*NftablesForwardExecutor) PluginID ¶
func (e *NftablesForwardExecutor) PluginID() string
func (*NftablesForwardExecutor) ValidateConfiguration ¶
func (e *NftablesForwardExecutor) ValidateConfiguration(ctx context.Context, raw json.RawMessage) error
ValidateConfiguration is the Control-side semantic gate for the 1.2 package. JSON Schema checks shape; this method checks the nftables/runtime invariants that must hold before an Agent operation is admitted.
func (*NftablesForwardExecutor) Version ¶
func (e *NftablesForwardExecutor) Version() string
type NftablesForwardRuleStatus ¶
type NftablesForwardRuleStatus struct {
ID string `json:"id"`
Name string `json:"name"`
NodeID uint `json:"node_id"`
NodeName string `json:"node_name"`
Topology string `json:"topology,omitempty"`
Protocol string `json:"protocol"`
Listen string `json:"listen,omitempty"`
Target string `json:"target,omitempty"`
DesiredRevision int64 `json:"desired_revision"`
ObservedRevision int64 `json:"observed_revision"`
Enabled bool `json:"enabled"`
Ready bool `json:"ready"`
Reconciling bool `json:"reconciling"`
Degraded bool `json:"degraded"`
RollbackRequired bool `json:"rollback_required"`
RuntimeHealth string `json:"runtime_health,omitempty"`
RulesetSHA256 string `json:"ruleset_sha256,omitempty"`
Packets uint64 `json:"packets"`
Bytes uint64 `json:"bytes"`
ObservedAt *time.Time `json:"observed_at,omitempty"`
LastError string `json:"last_error,omitempty"`
}
type NftablesForwardStatus ¶
type NftablesForwardStatus struct {
PluginID string `json:"plugin_id"`
Version string `json:"version"`
GeneratedAt time.Time `json:"generated_at"`
Summary NftablesForwardSummary `json:"summary"`
Rules []NftablesForwardRuleStatus `json:"rules"`
}
type NftablesForwardSummary ¶
type OperationWorker ¶
type OperationWorker struct {
// contains filtered or unexported fields
}
OperationWorker executes durable Control-target operations. Node-target operations remain owned by KernelOperationBridge and the Agent stream.
func NewOperationWorker ¶
func NewOperationWorker(db *gorm.DB, dispatcher LifecycleDispatcher) (*OperationWorker, error)
func (*OperationWorker) QueueReconciliation ¶
func (w *OperationWorker) QueueReconciliation(bootID string) (int, error)
QueueReconciliation records one enable operation per currently enabled Control package for this boot. Calling it again with the same boot ID is idempotent; a new Control process uses a new boot ID and therefore proves restart reconciliation with a new durable operation.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
func DefaultRegistry ¶
DefaultRegistry returns the process-wide first-party executor set. The HTTP gateway and lifecycle worker must share executor instances because future Control packages may own an isolated subprocess or other runtime state.
func NewRegistry ¶
func (*Registry) ExecuteLifecycle ¶
func (r *Registry) ExecuteLifecycle(ctx context.Context, pluginID, version string, request LifecycleRequest) (json.RawMessage, error)
func (*Registry) ExecuteRoute ¶
func (r *Registry) ExecuteRoute(ctx context.Context, pluginID, version string, request RouteRequest) (RouteResponse, error)
func (*Registry) ValidateConfiguration ¶
func (r *Registry) ValidateConfiguration(ctx context.Context, pluginID, version string, config json.RawMessage) error
ValidateConfiguration applies package-specific semantics after the kernel has verified the signed JSON Schema. Plugins without a registered validator remain schema-only. Once a plugin opts in, unknown versions fail closed so a validator for one release can never be reused for another release.
type RouteRequest ¶
RouteRequest deliberately contains only request data that a package API is allowed to consume. Authentication and authorization have already been completed by the kernel gateway; credentials are never forwarded to a package executor.
type RouteResponse ¶
RouteResponse is a controlled JSON response. Package code cannot select an arbitrary status outside the HTTP range or write directly to the Gin response writer.