provider

package
v1.5.1 Latest Latest
Warning

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

Go to latest
Published: Jun 1, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Overview

Package provider defines the unified interface for infrastructure operations. Each cloud provider and orchestrator (Kubernetes, Nomad, AWS ECS, Docker, Fly.io, etc.) implements the Provider interface, giving library consumers a single API for all infrastructure operations.

Index

Constants

This section is empty.

Variables

View Source
var ErrProviderNotFound = errors.New("ctrlplane: provider not registered")

ErrProviderNotFound indicates the named provider is not registered.

Functions

func HasCapability

func HasCapability(p Provider, capability Capability) bool

HasCapability checks whether the provider supports a given capability.

Types

type Capability

type Capability string

Capability declares what a provider supports. Consumers can query capabilities before calling unsupported methods.

const (
	// CapProvision indicates the provider can create infrastructure.
	CapProvision Capability = "provision"

	// CapDeploy indicates the provider can deploy releases.
	CapDeploy Capability = "deploy"

	// CapScale indicates the provider can adjust resources.
	CapScale Capability = "scale"

	// CapLogs indicates the provider can stream logs.
	CapLogs Capability = "logs"

	// CapExec indicates the provider can execute commands in instances.
	CapExec Capability = "exec"

	// CapVolumes indicates the provider supports persistent volumes.
	CapVolumes Capability = "volumes"

	// CapGPU indicates the provider supports GPU workloads.
	CapGPU Capability = "gpu"

	// CapBlueGreen indicates the provider supports blue-green deployments.
	CapBlueGreen Capability = "strategy:blue-green"

	// CapCanary indicates the provider supports canary deployments.
	CapCanary Capability = "strategy:canary"

	// CapRolling indicates the provider supports rolling deployments.
	CapRolling Capability = "strategy:rolling"

	// CapAutoScale indicates the provider supports autoscaling.
	CapAutoScale Capability = "autoscale"

	// CapCustomDomains indicates the provider supports custom domains.
	CapCustomDomains Capability = "custom-domains"

	// CapTLS indicates the provider supports TLS termination.
	CapTLS Capability = "tls"
)

type ConfigFile added in v1.5.1

type ConfigFile struct {
	Name    string `db:"name"    json:"name"`    // e.g. "app-config"
	Path    string `db:"path"    json:"path"`    // mount path, e.g. "/etc/app/config.yaml"
	Format  string `db:"format"  json:"format"`  // "json", "yaml", "env", "text"
	Content string `db:"content" json:"content"` // file content (stored in vault at deploy time)
}

ConfigFile defines a configuration file (JSON/YAML/env/text) that is stored in the vault and mounted into the container at deploy time.

type DeployRequest

type DeployRequest struct {
	InstanceID id.ID               `json:"instance_id"`
	ReleaseID  id.ID               `json:"release_id"`
	Services   []ServiceDeploySpec `json:"services"`
	Strategy   string              `json:"strategy"`
}

DeployRequest describes a deployment operation. Services lists only the services being changed in this rollout — services not listed are left at their previous version (the new Release inherits their snapshots from the prior Release).

type DeployResult

type DeployResult struct {
	ProviderRef string `json:"provider_ref"`
	Status      string `json:"status"`
}

DeployResult holds the result of a deploy operation.

type Endpoint

type Endpoint struct {
	ServiceName string `json:"service_name,omitempty"`
	URL         string `json:"url"`
	Port        int    `json:"port"`
	Protocol    string `json:"protocol"`
	Public      bool   `json:"public"`
}

Endpoint describes an accessible endpoint for an instance.

ServiceName names the service inside the instance that owns this endpoint — empty for legacy single-service instances. Routes can target a specific service via its name.

type ExecRequest

type ExecRequest struct {
	Command []string  `json:"command"`
	Stdin   io.Reader `json:"-"`
	TTY     bool      `json:"tty"`
}

ExecRequest describes a command to run inside an instance.

type ExecResult

type ExecResult struct {
	ExitCode int    `json:"exit_code"`
	Stdout   []byte `json:"stdout"`
	Stderr   []byte `json:"stderr"`
}

ExecResult holds the result of an exec operation.

type HealthCheckSpec

type HealthCheckSpec struct {
	Path     string        `json:"path,omitempty"`
	Port     int           `json:"port"`
	Interval time.Duration `json:"interval"`
	Timeout  time.Duration `json:"timeout"`
	Retries  int           `json:"retries"`
}

HealthCheckSpec configures health checking during deployment.

type HealthChecker added in v1.3.0

type HealthChecker interface {
	// HealthCheck tests connectivity and returns a health status.
	HealthCheck(ctx context.Context) (*HealthStatus, error)
}

HealthChecker is an optional interface that providers can implement to support health and connectivity testing from the dashboard.

type HealthStatus added in v1.3.0

type HealthStatus struct {
	Healthy   bool          `db:"healthy"    json:"healthy"`
	Message   string        `db:"message"    json:"message"`
	Latency   time.Duration `db:"latency"    json:"latency"`
	CheckedAt time.Time     `db:"checked_at" json:"checked_at"`
}

HealthStatus reports provider health after a connectivity test.

type InstanceState

type InstanceState string

InstanceState represents the lifecycle state of an instance.

const (
	// StateProvisioning indicates the instance is being provisioned.
	StateProvisioning InstanceState = "provisioning"

	// StateStarting indicates the instance is starting up.
	StateStarting InstanceState = "starting"

	// StateRunning indicates the instance is running and healthy.
	StateRunning InstanceState = "running"

	// StateStopping indicates the instance is shutting down.
	StateStopping InstanceState = "stopping"

	// StateStopped indicates the instance is stopped.
	StateStopped InstanceState = "stopped"

	// StateFailed indicates the instance is in a failed state.
	StateFailed InstanceState = "failed"

	// StateDestroying indicates the instance is being torn down.
	StateDestroying InstanceState = "destroying"

	// StateDestroyed indicates the instance has been fully removed.
	StateDestroyed InstanceState = "destroyed"
)

type InstanceStatus

type InstanceStatus struct {
	State     InstanceState            `json:"state"`
	Ready     bool                     `json:"ready"`
	Restarts  int                      `json:"restarts"` // sum across services
	StartedAt *time.Time               `json:"started_at,omitempty"`
	Message   string                   `json:"message,omitempty"`
	Endpoints []Endpoint               `json:"endpoints"`
	Services  map[string]ServiceStatus `json:"services,omitempty"`
	Metadata  map[string]string        `json:"metadata,omitempty"`
}

InstanceStatus describes the current runtime state of an instance. State and Ready aggregate across all services (worst-of); per-service detail is in Services keyed by ServiceSpec.Name.

type Location added in v1.5.1

type Location struct {
	Latitude  float64 `json:"latitude,omitempty"`
	Longitude float64 `json:"longitude,omitempty"`
	Country   string  `json:"country,omitempty"`
	City      string  `json:"city,omitempty"`
}

Location holds geographic metadata for a provider's region. Same shape as datacenter.Location but defined here so the provider package doesn't depend on datacenter — keeps the import graph pointing one way.

type LogOptions

type LogOptions struct {
	ServiceName string    `json:"service_name,omitempty"`
	Follow      bool      `json:"follow"`
	Since       time.Time `json:"since,omitzero"`
	Tail        int       `json:"tail,omitempty"`
}

LogOptions configures log streaming.

ServiceName picks one service inside the instance to stream from — empty defaults to the Main service. Single-container providers ignore this field.

type PortSpec

type PortSpec struct {
	Container int    `json:"container"`
	Host      int    `json:"host,omitempty"`
	Protocol  string `json:"protocol"`
}

PortSpec declares a port mapping for an instance.

type Provider

type Provider interface {
	// Info returns metadata about this provider.
	Info() ProviderInfo

	// Capabilities returns what this provider supports.
	Capabilities() []Capability

	// Provision creates infrastructure resources for an instance.
	Provision(ctx context.Context, req ProvisionRequest) (*ProvisionResult, error)

	// Deprovision tears down all resources for an instance.
	Deprovision(ctx context.Context, instanceID id.ID) error

	// Start starts a stopped instance.
	Start(ctx context.Context, instanceID id.ID) error

	// Stop gracefully stops a running instance.
	Stop(ctx context.Context, instanceID id.ID) error

	// Restart performs a stop+start cycle.
	Restart(ctx context.Context, instanceID id.ID) error

	// Status returns the current runtime status.
	Status(ctx context.Context, instanceID id.ID) (*InstanceStatus, error)

	// Deploy pushes a new release to the instance.
	Deploy(ctx context.Context, req DeployRequest) (*DeployResult, error)

	// Rollback reverts to a previous release.
	Rollback(ctx context.Context, instanceID id.ID, releaseID id.ID) error

	// Scale adjusts the instance's resource allocation.
	Scale(ctx context.Context, instanceID id.ID, spec ResourceSpec) error

	// Resources returns current resource utilization.
	Resources(ctx context.Context, instanceID id.ID) (*ResourceUsage, error)

	// Logs streams logs for the instance.
	Logs(ctx context.Context, instanceID id.ID, opts LogOptions) (io.ReadCloser, error)

	// Exec runs a command inside the instance.
	Exec(ctx context.Context, instanceID id.ID, cmd ExecRequest) (*ExecResult, error)
}

Provider is the unified interface for infrastructure operations. Each cloud/orchestrator (K8s, Nomad, AWS ECS, Docker, etc.) implements this.

type ProviderInfo

type ProviderInfo struct {
	Name     string    `json:"name"`
	Version  string    `json:"version"`
	Region   string    `json:"region"`
	Location *Location `json:"location,omitempty"`
}

ProviderInfo holds metadata about a provider. Location is optional — providers that don't know where they are (e.g. a generic SaaS API driver with no geographic identity) leave it nil.

type ProvisionRequest

type ProvisionRequest struct {
	InstanceID id.ID             `json:"instance_id"`
	TenantID   string            `json:"tenant_id"`
	Name       string            `json:"name"`
	Kind       WorkloadKind      `json:"kind"` // deployment | stateful_set
	Services   []ServiceSpec     `json:"services"`
	Labels     map[string]string `json:"labels,omitempty"` // workload-level, applied to all services
}

ProvisionRequest describes what resources to create for an instance. One ProvisionRequest produces one unit of co-scheduling — a k8s Pod, a Nomad TaskGroup allocation, or a Docker Compose project — containing every entry in Services.

type ProvisionResult

type ProvisionResult struct {
	// ProviderRef is the workload-level handle (Pod name on k8s,
	// Job ID on Nomad, Compose project name on Docker).
	ProviderRef string `json:"provider_ref"`

	// ServiceRefs maps a service's Name to the provider-specific
	// per-container/task ref (container ID on Docker, container name
	// within the Pod on k8s, Task name on Nomad). Used for per-service
	// log/exec/restart operations.
	ServiceRefs map[string]string `json:"service_refs,omitempty"`

	Endpoints []Endpoint        `json:"endpoints"`
	Metadata  map[string]string `json:"metadata,omitempty"`
}

ProvisionResult holds the result of a provision operation.

type Registry

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

Registry manages named providers. Thread-safe.

func NewRegistry

func NewRegistry() *Registry

NewRegistry creates an empty provider registry.

func (*Registry) All

func (r *Registry) All() map[string]Provider

All returns a snapshot of all registered providers.

func (*Registry) Default

func (r *Registry) Default() (Provider, error)

Default returns the fallback provider.

func (*Registry) Get

func (r *Registry) Get(name string) (Provider, error)

Get retrieves a provider by name.

func (*Registry) List

func (r *Registry) List() []string

List returns all registered provider names.

func (*Registry) Register

func (r *Registry) Register(name string, p Provider)

Register adds a provider under the given name.

func (*Registry) SetDefault

func (r *Registry) SetDefault(name string)

SetDefault sets the fallback provider name.

type ResourceSpec

type ResourceSpec struct {
	CPUMillis int    `json:"cpu_millis"`
	MemoryMB  int    `json:"memory_mb"`
	DiskMB    int    `json:"disk_mb,omitempty"`
	Replicas  int    `json:"replicas"`
	GPU       string `json:"gpu,omitempty"`
}

ResourceSpec declares desired resources for an instance.

type ResourceUsage

type ResourceUsage struct {
	CPUPercent    float64 `json:"cpu_percent"`
	MemoryUsedMB  int     `json:"memory_used_mb"`
	MemoryLimitMB int     `json:"memory_limit_mb"`
	DiskUsedMB    int     `json:"disk_used_mb,omitempty"`
	NetworkInMB   float64 `json:"network_in_mb"`
	NetworkOutMB  float64 `json:"network_out_mb"`
}

ResourceUsage reports actual resource utilization.

type SecretRef added in v1.5.1

type SecretRef struct {
	Key  string             `db:"key"  json:"key"`
	Type secrets.SecretType `db:"type" json:"type"`
}

SecretRef is a lightweight reference to a secret needed at deploy time. The secret value itself is fetched from the vault by Key when a Workload is deployed; specs only carry the reference, never the value.

Lives in the provider package so ServiceSpec can embed it without creating a template ↔ provider import cycle.

type ServiceDeploySpec added in v1.5.1

type ServiceDeploySpec struct {
	Name        string            `json:"name"                   validate:"required"`
	Image       string            `json:"image"                  validate:"required"`
	Env         map[string]string `json:"env,omitempty"`
	HealthCheck *HealthCheckSpec  `json:"health_check,omitempty"`
}

ServiceDeploySpec is a per-service slice of a Deploy operation. A Deploy carries Services []ServiceDeploySpec — partial deploys leave services not listed here untouched.

type ServiceRole added in v1.5.1

type ServiceRole string

ServiceRole categorises a service inside a Workload by lifecycle.

  • RoleMain: long-lived process; the workload's primary container. Every workload must have exactly one Main service. Workload health defaults to the Main service's readiness.
  • RoleSidecar: long-lived process that runs alongside Main inside the same co-scheduling unit (k8s Pod, Nomad TaskGroup, Docker Compose project). Examples: log-forwarding agent, envoy proxy, metrics shipper. Started after Main in dependency order.
  • RoleInit: run-once before Main and Sidecars start. The Main/Sidecars do not start until every Init has exited successfully. An Init failure marks the Instance as Failed.
const (
	RoleMain    ServiceRole = "main"
	RoleSidecar ServiceRole = "sidecar"
	RoleInit    ServiceRole = "init"
)

type ServiceSnapshot added in v1.5.1

type ServiceSnapshot struct {
	Name  string            `json:"name"`
	Image string            `json:"image"`
	Env   map[string]string `json:"env,omitempty"`
}

ServiceSnapshot is the per-service slice of a Release. Releases are always self-contained — partial deploys produce a new Release whose non-targeted services are inherited from the prior Release.

type ServiceSpec added in v1.5.1

type ServiceSpec struct {
	// Name is the service's identifier within the workload. Must be
	// unique among the workload's services and DNS-safe (lowercase
	// alphanumerics + hyphens) so providers can use it as a network
	// alias for service-to-service discovery.
	Name string `json:"name" validate:"required"`

	// Image is the container image reference, e.g. "nginx:1.25".
	Image string `json:"image" validate:"required"`

	// Role determines lifecycle (Main / Sidecar / Init). Defaults to
	// Main when empty; validation enforces exactly one Main per workload.
	Role ServiceRole `json:"role,omitempty"`

	// DependsOn lists service names that must reach Running before this
	// service starts. Used for ordering Sidecars relative to Main and
	// for chaining Inits. A cycle is a validation error.
	DependsOn []string `json:"depends_on,omitempty"`

	// Resources / Env / Ports / Volumes / HealthCheck are per-service.
	// Two services in the same workload can request different CPU/memory
	// or expose different ports.
	Resources   ResourceSpec      `json:"resources"`
	Env         map[string]string `json:"env,omitempty"`
	Ports       []PortSpec        `json:"ports,omitempty"`
	Volumes     []VolumeSpec      `json:"volumes,omitempty"`
	HealthCheck *HealthCheckSpec  `json:"health_check,omitempty"`

	// Secrets references env-injected secrets resolved against the
	// vault at deploy time. Per-service so a sidecar can have its own
	// credentials without leaking them to the main container.
	Secrets []SecretRef `json:"secrets,omitempty"`

	// ConfigFiles describes vault-backed files mounted into this
	// service's filesystem at deploy time.
	ConfigFiles []ConfigFile `json:"config_files,omitempty"`

	// Annotations is per-service free-form metadata (e.g. k8s
	// container annotations). Workload-level metadata lives on the
	// Workload's Labels map.
	Annotations map[string]string `json:"annotations,omitempty"`

	// Command and Args optionally override the container image's
	// ENTRYPOINT and CMD respectively. Empty leaves the image
	// defaults in place.
	Command []string `json:"command,omitempty"`
	Args    []string `json:"args,omitempty"`
}

ServiceSpec is the per-service slice of a Workload's spec. A Workload is `Services []ServiceSpec` plus workload-level fields (Replicas, Kind, Labels). Each entry produces one container/task within the replica's co-scheduling unit.

SecretRef and ConfigFile are spec-level descriptors of vault-backed data the provider mounts at provision time; they live in this package (rather than template/) so this struct can embed them without a cycle.

type ServiceStatus added in v1.5.1

type ServiceStatus struct {
	State       InstanceState `json:"state"`
	Ready       bool          `json:"ready"`
	Restarts    int           `json:"restarts"`
	ProviderRef string        `json:"provider_ref,omitempty"`
	Message     string        `json:"message,omitempty"`
}

ServiceStatus is the per-service runtime state reported back from the provider. InstanceStatus.Services map keys these by ServiceSpec.Name.

type VolumeSpec

type VolumeSpec struct {
	Name      string `json:"name"`
	MountPath string `json:"mount_path"`
	SizeMB    int    `json:"size_mb"`
	Type      string `json:"type"`
}

VolumeSpec declares a volume mount for an instance.

type WorkloadKind added in v1.5.1

type WorkloadKind string

WorkloadKind picks the runtime topology a workload deploys as.

  • KindDeployment: stateless replicas. On Kubernetes this becomes a Deployment; on Nomad a Job/TaskGroup; on Docker N independent Compose projects. Volumes are shared/ephemeral by default.
  • KindStatefulSet: replicas with stable per-replica identity and storage. On Kubernetes this becomes a StatefulSet + headless Service with volumeClaimTemplates; on Docker per-replica named volumes give equivalent semantics.
const (
	KindDeployment  WorkloadKind = "deployment"
	KindStatefulSet WorkloadKind = "stateful_set"
)

Directories

Path Synopsis
Package docker is a Docker-backed provider.Provider.
Package docker is a Docker-backed provider.Provider.
Package kubernetes implements a Kubernetes-based infrastructure provider for the ctrlplane.
Package kubernetes implements a Kubernetes-based infrastructure provider for the ctrlplane.
Package nomad is a HashiCorp Nomad-backed provider.Provider.
Package nomad is a HashiCorp Nomad-backed provider.Provider.

Jump to

Keyboard shortcuts

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