environment

package
v2.8.1 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: BSD-3-Clause Imports: 55 Imported by: 0

Documentation

Overview

Package environment owns environment persistence, remote runtime state, pairing, synchronization, and its HTTP and stream surfaces.

Index

Constants

View Source
const (
	ErrEnvironmentAccessTokenRequired = errors.Sentinel("environment access token required")
	ErrInvalidEnvironmentAccessToken  = errors.Sentinel("invalid environment access token")
)
View Source
const LocalEnvironmentID = "0"

LocalEnvironmentID is the reserved ID of the environment Arcane manages directly.

Variables

This section is empty.

Functions

func ApplyEnvironmentRuntimeState

func ApplyEnvironmentRuntimeState(env *environment.Environment)

ApplyEnvironmentRuntimeState normalizes edge environment runtime status using in-memory tunnel and poll registries without mutating persisted state.

func DisplayName

func DisplayName(environmentID, storedName string) string

DisplayName returns the stored environment name or its readable fallback.

func RegisterEnvironments

func RegisterEnvironments(api huma.API, h *EnvironmentHandler)

RegisterEnvironments registers all environment management endpoints.

Types

type CreateEnvironmentInput

type CreateEnvironmentInput struct {
	Body environment.Create
}

type CreateEnvironmentOutput

type CreateEnvironmentOutput struct {
	Body base.ApiResponse[EnvironmentWithApiKey]
}

type DeleteEnvironmentInput

type DeleteEnvironmentInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type DeleteEnvironmentOutput

type DeleteEnvironmentOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type Dependencies

type Dependencies struct {
	Settings *settings.SettingsService
	ApiKey   *apikey.ApiKeyService
	Event    *event.EventService
	Config   *config.Config
}

type DeploymentSnippet

type DeploymentSnippet struct {
	DockerRun     string                 `json:"dockerRun" doc:"Docker run command snippet"`
	DockerCompose string                 `json:"dockerCompose" doc:"Docker compose YAML snippet"`
	MTLS          *DeploymentSnippetMTLS `json:"mtls,omitempty" doc:"Optional Arcane-generated mTLS deployment assets for edge agents"`
}

type DeploymentSnippetFile

type DeploymentSnippetFile struct {
	Name          string `json:"name" doc:"Suggested filename"`
	Content       string `json:"content,omitempty" doc:"PEM file contents. Omitted for sensitive files such as private keys; use downloadUrl instead."`
	DownloadURL   string `json:"downloadUrl,omitempty" doc:"Pairing-permission endpoint to download this file when content is withheld"`
	Sensitive     bool   `json:"sensitive,omitempty" doc:"True when this file is sensitive and must be fetched via downloadUrl"`
	ContainerPath string `json:"containerPath" doc:"Container mount path expected by the mTLS snippet"`
	Permissions   string `json:"permissions" doc:"Suggested file mode"`
}

type DeploymentSnippetMTLS

type DeploymentSnippetMTLS struct {
	DockerRun     string                  `json:"dockerRun" doc:"Docker run snippet using Arcane-generated mTLS assets"`
	DockerCompose string                  `json:"dockerCompose" doc:"Docker compose snippet using Arcane-generated mTLS assets"`
	Files         []DeploymentSnippetFile `json:"files" doc:"Generated PEM files to place on the edge host"`
	HostDirHint   string                  `json:"hostDirHint" doc:"Suggested host directory containing the generated PEM files"`
}

type DeploymentSnippets

type DeploymentSnippets struct {
	DockerRun     string
	DockerCompose string
	MTLS          *DeploymentSnippetMTLS
}

DeploymentSnippets contains deployment configuration snippets for an environment.

type DownloadEdgeMTLSCAInput

type DownloadEdgeMTLSCAInput struct{}

type DownloadEnvironmentMTLSBundleInput

type DownloadEnvironmentMTLSBundleInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type DownloadEnvironmentMTLSFileInput

type DownloadEnvironmentMTLSFileInput struct {
	ID       string `path:"id" doc:"Environment ID"`
	FileName string `path:"fileName" doc:"mTLS asset filename"`
}

type Environment added in v2.8.1

type Environment struct {
	database.BaseModel

	Name                string     `json:"name" sortable:"true"`
	ApiUrl              string     `json:"apiUrl" gorm:"column:api_url" sortable:"true"`
	Status              string     `json:"status" sortable:"true"`
	Enabled             bool       `json:"enabled" sortable:"true"`
	IsEdge              bool       `json:"isEdge" gorm:"column:is_edge;default:false"`
	Hidden              bool       `json:"hidden" gorm:"column:hidden;default:false"`
	LastSeen            *time.Time `json:"lastSeen" gorm:"column:last_seen"`
	LastEdgeTransport   *string    `json:"lastEdgeTransport" gorm:"column:last_edge_transport"`
	AccessToken         *string    `json:"-" gorm:"column:access_token"`
	ApiKeyID            *string    `json:"-" gorm:"column:api_key_id"`
	ParentEnvironmentID *string    `json:"-" gorm:"column:parent_environment_id"`
	SwarmNodeID         *string    `json:"-" gorm:"column:swarm_node_id"`
}

func (Environment) TableName added in v2.8.1

func (Environment) TableName() string

type EnvironmentHandler

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

EnvironmentHandler handles environment management endpoints.

func NewHandler

func NewHandler(environmentService *EnvironmentService, settingsService *settings.SettingsService, apiKeyService *apikey.ApiKeyService, eventService *event.EventService, cfg *config.Config) *EnvironmentHandler

NewHandler builds the environment HTTP handler and its stream producer.

func (*EnvironmentHandler) CreateEnvironment

CreateEnvironment creates a new environment.

func (*EnvironmentHandler) DeleteEnvironment

DeleteEnvironment deletes an environment.

func (*EnvironmentHandler) DownloadEdgeMTLSCA

DownloadEdgeMTLSCA downloads the Arcane-managed edge mTLS CA certificate.

func (*EnvironmentHandler) DownloadEnvironmentMTLSBundle

func (h *EnvironmentHandler) DownloadEnvironmentMTLSBundle(ctx context.Context, input *DownloadEnvironmentMTLSBundleInput) (*huma.StreamResponse, error)

func (*EnvironmentHandler) DownloadEnvironmentMTLSFile

func (h *EnvironmentHandler) DownloadEnvironmentMTLSFile(ctx context.Context, input *DownloadEnvironmentMTLSFileInput) (*huma.StreamResponse, error)

func (*EnvironmentHandler) GetDeploymentSnippets

GetDeploymentSnippets returns deployment snippets for an environment.

func (*EnvironmentHandler) GetEnvironment

GetEnvironment returns an environment by ID.

func (*EnvironmentHandler) GetEnvironmentVersion

GetEnvironmentVersion returns the version of a remote environment.

func (*EnvironmentHandler) ListEnvironments

ListEnvironments returns a paginated list of environments.

func (*EnvironmentHandler) PairAgent

func (h *EnvironmentHandler) PairAgent(ctx context.Context, input *PairAgentInput) (*PairAgentOutput, error)

PairAgent generates or rotates the local agent pairing token.

func (*EnvironmentHandler) PairEnvironment

PairEnvironment handles agent pairing callback with API key.

func (*EnvironmentHandler) RunStreamProducer

func (h *EnvironmentHandler) RunStreamProducer(ctx context.Context, ps *authz.PermissionSet, events chan<- environment.StreamEvent)

func (*EnvironmentHandler) SyncEnvironment

SyncEnvironment syncs container registries and git repositories to an environment.

func (*EnvironmentHandler) TestConnection

TestConnection tests connectivity to an environment.

func (*EnvironmentHandler) UpdateEnvironment

UpdateEnvironment updates an environment.

func (*EnvironmentHandler) UpdateHeartbeat

UpdateHeartbeat updates the heartbeat for an environment.

type EnvironmentService

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

func NewEnvironmentService

func NewEnvironmentService(db *database.DB, httpClient *http.Client, dockerService *docker.DockerClientService, eventService *event.EventService, settingsService *settings.SettingsService, apiKeyService *apikey.ApiKeyService) *EnvironmentService

func (*EnvironmentService) BindSwarmNodeEnvironment

func (s *EnvironmentService) BindSwarmNodeEnvironment(
	ctx context.Context,
	parentEnvironmentID, nodeID, environmentID string,
	rebind bool,
) (*Environment, error)

BindSwarmNodeEnvironment binds an existing visible environment to a swarm node without modifying its connection details or agent token.

func (*EnvironmentService) CreateEnvironment

func (s *EnvironmentService) CreateEnvironment(ctx context.Context, environment *Environment, userID, username *string) (*Environment, error)

func (*EnvironmentService) DeleteEnvironment

func (s *EnvironmentService) DeleteEnvironment(ctx context.Context, id string, userID, username *string) error

func (*EnvironmentService) DeleteSwarmNodeAgentDeployment

func (s *EnvironmentService) DeleteSwarmNodeAgentDeployment(ctx context.Context, parentEnvironmentID, nodeID string, userID, username *string) error

DeleteSwarmNodeAgentDeployment removes a dedicated hidden agent registration while leaving visible remote environments untouched.

func (*EnvironmentService) DetachSwarmNodeEnvironment

func (s *EnvironmentService) DetachSwarmNodeEnvironment(ctx context.Context, parentEnvironmentID, nodeID string) error

DetachSwarmNodeEnvironment clears a visible environment binding from a node.

func (*EnvironmentService) EnsureLocalEnvironment

func (s *EnvironmentService) EnsureLocalEnvironment(ctx context.Context, appUrl string) error

func (*EnvironmentService) EnsureSwarmNodeAgentEnvironment

func (s *EnvironmentService) EnsureSwarmNodeAgentEnvironment(
	ctx context.Context,
	parentEnvironmentID, nodeID, hostname, userID, username string,
	rotate bool,
) (*Environment, string, error)

func (*EnvironmentService) ExecuteRemoteRequest

func (s *EnvironmentService) ExecuteRemoteRequest(ctx context.Context, envID string, method string, path string, body []byte) (*remenv.Response, error)

func (*EnvironmentService) GenerateDeploymentSnippets

func (s *EnvironmentService) GenerateDeploymentSnippets(ctx context.Context, envID string, envAddress string, apiKey string) (*DeploymentSnippets, error)

GenerateDeploymentSnippets generates Docker deployment snippets for an environment.

func (*EnvironmentService) GenerateEdgeDeploymentSnippets

func (s *EnvironmentService) GenerateEdgeDeploymentSnippets(ctx context.Context, envID string, managerURL string, apiKey string, edgeCfg *edge.Config) (*DeploymentSnippets, error)

GenerateEdgeDeploymentSnippets generates Docker deployment snippets for an edge agent. Edge agents connect outbound to the manager and don't require exposed ports.

func (*EnvironmentService) GetActiveRemoteEnvironmentSnapshot

func (s *EnvironmentService) GetActiveRemoteEnvironmentSnapshot(environmentID string) mo.Option[Environment]

GetActiveRemoteEnvironmentSnapshot returns the latest in-process snapshot for an enabled, visible, non-local remote environment.

func (*EnvironmentService) GetDB

func (s *EnvironmentService) GetDB() *database.DB

func (*EnvironmentService) GetEnabledRegistryCredentials

func (s *EnvironmentService) GetEnabledRegistryCredentials(ctx context.Context) ([]containerregistry.Credential, error)

func (*EnvironmentService) GetEnvironmentByID

func (s *EnvironmentService) GetEnvironmentByID(ctx context.Context, id string) (*Environment, error)

func (*EnvironmentService) ListEnabledEnvironmentIDs

func (s *EnvironmentService) ListEnabledEnvironmentIDs(ctx context.Context) ([]string, error)

func (*EnvironmentService) ListEnvironmentsPaginated

func (s *EnvironmentService) ListEnvironmentsPaginated(ctx context.Context, params pagination.QueryParams, accessibleEnvIDs []string) ([]environment.Environment, pagination.Response, error)

func (*EnvironmentService) ListRemoteEnvironmentIDs

func (s *EnvironmentService) ListRemoteEnvironmentIDs(ctx context.Context) ([]string, error)

ListRemoteEnvironmentIDs returns the IDs of enabled remote environments; it satisfies agg.RemoteEnvironmentLister for aggregated stream handlers.

func (*EnvironmentService) ListRemoteEnvironments

func (s *EnvironmentService) ListRemoteEnvironments(ctx context.Context) ([]Environment, error)

ListRemoteEnvironments returns all non-local, enabled environments for syncing purposes.

func (*EnvironmentService) ListSwarmNodeAgentEnvironments

func (s *EnvironmentService) ListSwarmNodeAgentEnvironments(ctx context.Context, parentEnvironmentID string) ([]Environment, error)

func (*EnvironmentService) ListSwarmNodeCandidateEnvironments

func (s *EnvironmentService) ListSwarmNodeCandidateEnvironments(ctx context.Context) ([]Environment, error)

ListSwarmNodeCandidateEnvironments returns enabled visible environments that can provide swarm-node coverage for a manager environment.

func (*EnvironmentService) ListVisibleEnvironments

func (s *EnvironmentService) ListVisibleEnvironments(ctx context.Context) ([]environment.Environment, error)

func (*EnvironmentService) NotifyRuntimeStateChanged

func (s *EnvironmentService) NotifyRuntimeStateChanged()

NotifyRuntimeStateChanged wakes every runtime watcher.

func (*EnvironmentService) ProxyJSONRequest

func (s *EnvironmentService) ProxyJSONRequest(ctx context.Context, envID string, method string, path string, body []byte, out any) error

func (*EnvironmentService) ProxyJSONRequestForEnvironment

func (s *EnvironmentService) ProxyJSONRequestForEnvironment(ctx context.Context, environment Environment, method string, path string, body []byte, out any) error

ProxyJSONRequestForEnvironment sends a JSON request using an already-loaded environment row, avoiding an extra environment lookup on hot stream paths.

func (*EnvironmentService) ProxyRequest

func (s *EnvironmentService) ProxyRequest(ctx context.Context, envID string, method string, path string, body []byte) ([]byte, int, error)

ProxyRequest sends a request to a remote environment's API.

func (*EnvironmentService) ReconcileEdgeStatusesOnStartup

func (s *EnvironmentService) ReconcileEdgeStatusesOnStartup(ctx context.Context) error

ReconcileEdgeStatusesOnStartup resets edge environments to offline when the manager starts. Live edge tunnels are process-local runtime state, so persisted "online" flags can be stale after a restart until agents reconnect. Pending environments are left untouched.

func (*EnvironmentService) RegenerateEnvironmentApiKey

func (s *EnvironmentService) RegenerateEnvironmentApiKey(ctx context.Context, envID string, newApiKeyID string, apiKey string, userID, username string, envName string) error

func (*EnvironmentService) RegisterHealthJobsOnStartup

func (s *EnvironmentService) RegisterHealthJobsOnStartup(ctx context.Context)

RegisterHealthJobsOnStartup registers a health-check job for every enabled environment. Replaces the old global environment-health job.

func (*EnvironmentService) RescheduleHealthJobs

func (s *EnvironmentService) RescheduleHealthJobs(ctx context.Context)

RescheduleHealthJobs re-registers all enabled environments' health jobs, picking up a changed global interval. Wired from the Jobs UI via job.JobService.

func (*EnvironmentService) ResolveEdgeEnvironmentByToken

func (s *EnvironmentService) ResolveEdgeEnvironmentByToken(ctx context.Context, token string) (string, error)

func (*EnvironmentService) ResolveEnvironmentByAccessToken

func (s *EnvironmentService) ResolveEnvironmentByAccessToken(ctx context.Context, token string) (*Environment, error)

func (*EnvironmentService) ResolveEnvironmentName

func (s *EnvironmentService) ResolveEnvironmentName(ctx context.Context, environmentID string) string

ResolveEnvironmentName looks up an environment and returns the label to show for it. Use this instead of hardcoding a name for a known ID: names are user-editable, so even the local environment's is not fixed.

func (*EnvironmentService) RunHealthChecksNow

func (s *EnvironmentService) RunHealthChecksNow(ctx context.Context) error

RunHealthChecksNow runs every enabled environment's health check synchronously. Backs the "run now" button for the environment-health job in the Jobs UI.

func (*EnvironmentService) SetScheduler

func (s *EnvironmentService) SetScheduler(ctx context.Context, scheduler schedulertypes.DynamicScheduler, admissionGate *actors.Gate[actors.AdmissionKey]) error

SetScheduler injects the job scheduler and app lifecycle context. Called during bootstrap on the manager only (agent mode leaves scheduler nil, so all health-job registration becomes a no-op).

func (*EnvironmentService) SetVariableSyncer

func (s *EnvironmentService) SetVariableSyncer(syncer VariableSyncer)

SetVariableSyncer injects the global-variable syncer. Called during bootstrap on the manager only; agents leave it nil.

func (*EnvironmentService) SubscribeRuntimeChanges

func (s *EnvironmentService) SubscribeRuntimeChanges() (<-chan struct{}, func())

SubscribeRuntimeChanges returns a channel that receives a coalesced wake-up whenever environment liveness may have changed, plus a function to release it.

func (*EnvironmentService) SyncRegistriesToEnvironment

func (s *EnvironmentService) SyncRegistriesToEnvironment(ctx context.Context, environmentID string) error

SyncRegistriesToEnvironment syncs all registries from this manager to a remote environment

func (*EnvironmentService) SyncRegistriesToRemoteEnvironments

func (s *EnvironmentService) SyncRegistriesToRemoteEnvironments(ctx context.Context) error

SyncRegistriesToRemoteEnvironments syncs container registries to all eligible remote environments. Eligibility requires a non-local, enabled environment with a configured access token.

func (*EnvironmentService) SyncRepositoriesToEnvironment

func (s *EnvironmentService) SyncRepositoriesToEnvironment(ctx context.Context, environmentID string) error

SyncRepositoriesToEnvironment syncs all git repositories from this manager to a remote environment

func (*EnvironmentService) TestConnection

func (s *EnvironmentService) TestConnection(ctx context.Context, id string, customApiUrl *string) (string, error)

func (*EnvironmentService) UpdateEnvironment

func (s *EnvironmentService) UpdateEnvironment(ctx context.Context, id string, updates map[string]any, userID, username *string) (*Environment, error)

func (*EnvironmentService) UpdateEnvironmentConnectionState

func (s *EnvironmentService) UpdateEnvironmentConnectionState(ctx context.Context, id string, connected bool) error

UpdateEnvironmentConnectionState updates runtime connectivity status without creating a generic "environment updated" event. This is used for edge tunnel connect/disconnect.

func (*EnvironmentService) UpdateEnvironmentHeartbeat

func (s *EnvironmentService) UpdateEnvironmentHeartbeat(ctx context.Context, id string) error

func (*EnvironmentService) UpdateSwarmNodeIdentity

func (s *EnvironmentService) UpdateSwarmNodeIdentity(ctx context.Context, envID, swarmNodeID string) error

type EnvironmentStatus added in v2.8.1

type EnvironmentStatus string
const (
	EnvironmentStatusOnline  EnvironmentStatus = "online"
	EnvironmentStatusStandby EnvironmentStatus = "standby"
	EnvironmentStatusOffline EnvironmentStatus = "offline"
	EnvironmentStatusError   EnvironmentStatus = "error"
	EnvironmentStatusPending EnvironmentStatus = "pending"
)

type EnvironmentWithApiKey

type EnvironmentWithApiKey struct {
	environment.Environment

	ApiKey *string `json:"apiKey,omitempty" doc:"API key for pairing (only shown once during creation)"`
}

type GetDeploymentSnippetsInput

type GetDeploymentSnippetsInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type GetDeploymentSnippetsOutput

type GetDeploymentSnippetsOutput struct {
	Body base.ApiResponse[DeploymentSnippet]
}

type GetEnvironmentInput

type GetEnvironmentInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type GetEnvironmentOutput

type GetEnvironmentOutput struct {
	Body base.ApiResponse[environment.Environment]
}

type GetEnvironmentVersionInput

type GetEnvironmentVersionInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type GetEnvironmentVersionOutput

type GetEnvironmentVersionOutput struct {
	Body base.ApiResponse[version.Info]
}

type ListEnvironmentsInput

type ListEnvironmentsInput struct {
	Search string `query:"search" doc:"Search query for filtering by name or API URL"`
	Sort   string `query:"sort" doc:"Column to sort by"`
	Order  string `query:"order" default:"asc" doc:"Sort direction (asc or desc)"`
	Start  int    `query:"start" default:"0" doc:"Start index for pagination"`
	Limit  int    `query:"limit" default:"20" doc:"Items per page"`
	Type   string `query:"type" doc:"Filter by environment type (comma-separated: http,edge,websocket,grpc,polling)"`
}

type ListEnvironmentsOutput

type ListEnvironmentsOutput struct {
	Body base.Paginated[environment.Environment]
}

type Module

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

func New

func New(service *EnvironmentService, deps Dependencies) *Module

func (*Module) Handler

func (m *Module) Handler() *EnvironmentHandler

func (*Module) RegisterRoutes

func (m *Module) RegisterRoutes(api huma.API)

func (*Module) Service

func (m *Module) Service() *EnvironmentService

type PairAgentInput

type PairAgentInput struct {
	ID   string                        `path:"id" doc:"Environment ID (must be 0 for local)"`
	Body *environment.AgentPairRequest `json:"body,omitempty"`
}

type PairAgentOutput

type PairAgentOutput struct {
	Body base.ApiResponse[environment.AgentPairResponse]
}

type PairEnvironmentInput

type PairEnvironmentInput struct {
	XAPIKey string `header:"X-API-Key" doc:"API key for environment pairing"`
}

type PairEnvironmentOutput

type PairEnvironmentOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type SyncEnvironmentInput

type SyncEnvironmentInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type SyncEnvironmentOutput

type SyncEnvironmentOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type TestConnectionInput

type TestConnectionInput struct {
	ID   string                             `path:"id" doc:"Environment ID"`
	Body *environment.TestConnectionRequest `json:"body,omitempty"`
}

type TestConnectionOutput

type TestConnectionOutput struct {
	Body base.ApiResponse[environment.Test]
}

type UpdateEnvironmentInput

type UpdateEnvironmentInput struct {
	ID   string `path:"id" doc:"Environment ID"`
	Body environment.Update
}

type UpdateEnvironmentOutput

type UpdateEnvironmentOutput struct {
	Body base.ApiResponse[environment.Environment]
}

type UpdateHeartbeatInput

type UpdateHeartbeatInput struct {
	ID string `path:"id" doc:"Environment ID"`
}

type UpdateHeartbeatOutput

type UpdateHeartbeatOutput struct {
	Body base.ApiResponse[base.MessageResponse]
}

type VariableSyncer

type VariableSyncer interface {
	SyncEnvironment(ctx context.Context, envID string) error
}

VariableSyncer pushes the effective global-variable set to one environment. Implemented by variable.VariableService.

Jump to

Keyboard shortcuts

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