Documentation
¶
Overview ¶
Package statebackend provides S3-compatible IaC state storage backends for the DigitalOcean plugin. The store is ported from workflow's module/iac_state_spaces.go and serves the `spaces` backend over the pb.IaCStateBackend gRPC contract — each plugin owns its own copy of the store (no shared workflow/module import).
Index ¶
- type IaCState
- type IaCStateStore
- type SpacesIaCStateStore
- func (s *SpacesIaCStateStore) DeleteState(ctx context.Context, resourceID string) error
- func (s *SpacesIaCStateStore) GetState(ctx context.Context, resourceID string) (*IaCState, error)
- func (s *SpacesIaCStateStore) ListStates(ctx context.Context, filter map[string]string) ([]*IaCState, error)
- func (s *SpacesIaCStateStore) Lock(ctx context.Context, resourceID string) error
- func (s *SpacesIaCStateStore) SaveState(ctx context.Context, state *IaCState) error
- func (s *SpacesIaCStateStore) Unlock(ctx context.Context, resourceID string) error
- type SpacesS3Client
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type IaCState ¶
type IaCState struct {
ResourceID string `json:"resource_id"`
ResourceType string `json:"resource_type"` // e.g. "kubernetes", "ecs"
Provider string `json:"provider"` // e.g. "aws", "gcp", "local"
ProviderRef string `json:"provider_ref,omitempty"`
ProviderID string `json:"provider_id,omitempty"`
ConfigHash string `json:"config_hash,omitempty"`
Status string `json:"status"` // planned, provisioning, active, destroying, destroyed, error
Outputs map[string]any `json:"outputs"` // provider-specific outputs
Config map[string]any `json:"config"` // the config used to provision
Dependencies []string `json:"dependencies,omitempty"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
Error string `json:"error,omitempty"`
}
IaCState tracks the state of an infrastructure resource. It mirrors the proto IaCState message (plugin/external/proto/iac.proto) and workflow's module.IaCState — fields are kept identical so JSON round-trips with the engine. The free-form Outputs / Config maps are serialised as JSON.
type IaCStateStore ¶
type IaCStateStore interface {
// GetState retrieves a state record by resource ID. Returns nil, nil when not found.
GetState(ctx context.Context, resourceID string) (*IaCState, error)
// SaveState inserts or replaces a state record.
SaveState(ctx context.Context, state *IaCState) error
// ListStates returns all state records matching the provided key=value filter.
// Pass a nil or empty map to return all records — both are treated as "no
// filter" (ranging over a nil map is valid Go, and most call sites pass nil).
ListStates(ctx context.Context, filter map[string]string) ([]*IaCState, error)
// DeleteState removes a state record by resource ID.
DeleteState(ctx context.Context, resourceID string) error
// Lock acquires an exclusive lock for the given resource ID.
// Returns an error if the resource is already locked.
Lock(ctx context.Context, resourceID string) error
// Unlock releases the lock for the given resource ID.
Unlock(ctx context.Context, resourceID string) error
}
IaCStateStore is the interface for IaC state persistence backends.
type SpacesIaCStateStore ¶
type SpacesIaCStateStore struct {
// contains filtered or unexported fields
}
SpacesIaCStateStore persists IaC state as JSON objects in a DigitalOcean Spaces bucket (or any S3-compatible store). Lock objects are used for advisory locking.
func NewSpacesIaCStateStore ¶
func NewSpacesIaCStateStore(region, bucket, prefix, accessKey, secretKey, endpoint string) (*SpacesIaCStateStore, error)
NewSpacesIaCStateStore creates a Spaces/S3-compatible state store.
Parameters:
- region: DO region (e.g. "nyc3"); used to construct the endpoint https://<region>.digitaloceanspaces.com unless endpoint is set.
- bucket: Spaces bucket name (required).
- prefix: optional key prefix (default "iac-state/").
- accessKey: Spaces access key; falls back to DO_SPACES_ACCESS_KEY env var.
- secretKey: Spaces secret key; falls back to DO_SPACES_SECRET_KEY env var.
- endpoint: optional custom endpoint override.
func NewSpacesIaCStateStoreWithClient ¶
func NewSpacesIaCStateStoreWithClient(client SpacesS3Client, bucket, prefix string) *SpacesIaCStateStore
NewSpacesIaCStateStoreWithClient creates a store with an injected client (for testing).
func (*SpacesIaCStateStore) DeleteState ¶
func (s *SpacesIaCStateStore) DeleteState(ctx context.Context, resourceID string) error
DeleteState removes the state object for resourceID.
func (*SpacesIaCStateStore) GetState ¶
GetState retrieves a state record by resource ID. Returns nil, nil when not found.
func (*SpacesIaCStateStore) ListStates ¶
func (s *SpacesIaCStateStore) ListStates(ctx context.Context, filter map[string]string) ([]*IaCState, error)
ListStates lists all state objects under the prefix and returns those matching filter. Supported filter keys: "resource_type", "provider", "status".
func (*SpacesIaCStateStore) Lock ¶
func (s *SpacesIaCStateStore) Lock(ctx context.Context, resourceID string) error
Lock creates a lock object for resourceID using S3 conditional writes (If-None-Match: *) for atomic, race-free lock acquisition. Fails if the lock already exists.
type SpacesS3Client ¶
type SpacesS3Client interface {
GetObject(ctx context.Context, input *s3.GetObjectInput, opts ...func(*s3.Options)) (*s3.GetObjectOutput, error)
PutObject(ctx context.Context, input *s3.PutObjectInput, opts ...func(*s3.Options)) (*s3.PutObjectOutput, error)
DeleteObject(ctx context.Context, input *s3.DeleteObjectInput, opts ...func(*s3.Options)) (*s3.DeleteObjectOutput, error)
ListObjectsV2(ctx context.Context, input *s3.ListObjectsV2Input, opts ...func(*s3.Options)) (*s3.ListObjectsV2Output, error)
HeadObject(ctx context.Context, input *s3.HeadObjectInput, opts ...func(*s3.Options)) (*s3.HeadObjectOutput, error)
}
SpacesS3Client abstracts the S3 API methods used by SpacesIaCStateStore, allowing a mock to be injected for testing.