Documentation
¶
Overview ¶
Package cloudiac defines the engine contract for cloud provisioning. It holds types only: nothing runs until an implementation is wired in.
Index ¶
- Constants
- Variables
- func FetchLimitsFrom(get func() SettingsReader) func() FetchLimits
- func FreeBytes(dir string) (int64, error)
- func InstallInto(enabled bool, planner iac.CloudPlanner, policy iac.PolicyChecker) bool
- func IsIAMType(t string) bool
- func IsProtectedType(t string) bool
- func LiveSandbox(get func() SettingsReader, runtime string) func(TofuConfig) TofuConfig
- func LoadSigstoreTrustedRoot(cacheDir string) (*root.TrustedRoot, error)
- func PlanHash(plan []byte) string
- func RedactLog(log string, secrets ...string) string
- func RedactStepOutput(out string, limit int, credRedact func(string) string, sensitive []string, ...) string
- func RefusalsError(rs []Refusal) error
- func SensitiveValues(raws ...[]byte) []string
- func StackName(source string) string
- func StepArgs(step Step) ([]string, error)
- type AccountInfo
- type AccountResolver
- type ApplyRequest
- type BinaryEnsurer
- type BucketSpec
- type Change
- type CloudPlannerAdapter
- func (a CloudPlannerAdapter) ApplyCloud(ctx context.Context, req iac.CloudApplyRequest) (iac.CloudApplyResult, error)
- func (a CloudPlannerAdapter) CloudReady() bool
- func (a CloudPlannerAdapter) PlanCloud(ctx context.Context, r iac.CloudResource) (iac.CloudDiff, error)
- func (a CloudPlannerAdapter) PlanCloudStack(ctx context.Context, stack string, rs []iac.CloudResource) []iac.CloudOutcome
- type ConnectionAccounts
- type ConnectionGetter
- type CostEstimate
- type CostPolicy
- type CredentialFile
- type CredentialHandle
- type DetailedPlanner
- type Engine
- type Error
- type ErrorKind
- type ExecRunner
- type FetchConfig
- type FetchLimits
- type Fetcher
- type InstanceSpec
- type KeyDeriver
- type LiveFetcher
- type MaterialSource
- type ModuleSpec
- type Mount
- type NetworkPolicy
- type NetworkSpec
- type OCISpec
- type OracleResolver
- type PlanAttr
- type PlanChange
- type PlanResult
- type Policy
- type PolicyAdapter
- type PriceTable
- type Refusal
- type ReleaseMaterial
- type ReleaseVerifier
- type ResourceChange
- type Result
- type RunDir
- type RunOutput
- type Runner
- type SandboxInput
- type SandboxLimits
- type SandboxSpec
- type SavedPlan
- type SavedPlanRunner
- type SettingsReader
- type SignatureVerifier
- type StateDB
- type StateLocker
- type StateQuarantine
- type StateStore
- func (s *StateStore) DropPlan(ctx context.Context, account, stack, hash string) error
- func (s *StateStore) Load(ctx context.Context, account, stack string) ([]byte, int64, error)
- func (s *StateStore) LoadPlan(ctx context.Context, account, stack string) (SavedPlan, error)
- func (s *StateStore) OpenQuarantine(q store.CloudStateQuarantine) ([]byte, error)
- func (s *StateStore) Quarantine(ctx context.Context, account, stack string, fence int64, reason string, ...) (int64, error)
- func (s *StateStore) Quarantined(ctx context.Context, account, stack string) ([]store.CloudStateQuarantine, error)
- func (s *StateStore) Save(ctx context.Context, lock store.CloudStateLock, expectVersion int64, ...) (int64, error)
- func (s *StateStore) SavePlan(ctx context.Context, account, stack string, p SavedPlan) (string, error)
- type StaticPrices
- type Step
- type StringSettings
- type Tmpfs
- type TofuConfig
- type TofuDeps
- type TofuEngine
- func (e *TofuEngine) Apply(ctx context.Context, req ApplyRequest) (Result, error)
- func (e *TofuEngine) Destroy(ctx context.Context, req ApplyRequest) (Result, error)
- func (e *TofuEngine) Plan(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (Result, error)
- func (e *TofuEngine) PlanDestroy(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (PlanResult, error)
- func (e *TofuEngine) PlanDetailed(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (PlanResult, error)
Constants ¶
const ( CodeIAMForbidden = "cloud_iam_forbidden" CodeProtectedDelete = "cloud_protected_delete" CodeDestroyCap = "cloud_destroy_cap" CodeCostUnpriced = "cloud_cost_unpriced" CodeCostLimit = "cloud_cost_limit" )
Stable refusal codes for cloud policy and cost guards.
const ( ActionCreate = "create" ActionUpdate = "update" ActionDelete = "delete" ActionReplace = "replace" ActionNoop = "no-op" )
Resource change actions as reported by a rendered plan.
const ( RunWorkSubdir = "work" RunStateSubdir = "state" )
Layout of the private per-run directory. Only Shared is mounted, read-write, into steps.
const ( SandboxModuleDir = "/module" SandboxWorkDir = "/work" SandboxStateDir = "/state" SandboxTofuPath = "/opt/tofu/tofu" SandboxPluginDir = "/opt/tofu/plugins" SandboxCredentialDir = "/run/lr-cred" //nolint:gosec // a mount path, not a credential )
Fixed paths inside the step container.
const DefaultStack = "default"
DefaultStack names the module when an apply source carries no name.
const MainFile = "main.tf.json"
MainFile is the one configuration file a rendered module carries.
const StatePurpose = "cloud-state"
StatePurpose names the master derived key that wraps every per record state key.
const TofuVersion = "1.13.2"
TofuVersion is the OpenTofu release this Levelrail release pins.
Variables ¶
var ( ErrFetchConfig error = &unavailableError{msg: "cloudiac: fetch is not configured, check the cloud.fetch_* settings"} ErrUnpinnedVersion = errors.New("cloudiac: OpenTofu version has no compiled checksum") ErrUnsupportedPlatform = errors.New("cloudiac: no compiled checksum for this platform") ErrPlaceholderDigest = errors.New("cloudiac: compiled checksum is a placeholder, refusing to run") ErrSignatureUnverified = errors.New("cloudiac: release signature verification is not available") ErrLowDisk = errors.New("cloudiac: not enough free disk for the OpenTofu download") ErrTooLarge = errors.New("cloudiac: OpenTofu download exceeds the size cap") ErrChecksumMismatch = errors.New("cloudiac: OpenTofu checksum mismatch") ErrBadArchive = errors.New("cloudiac: OpenTofu archive is malformed") ErrFreeSpaceUnsupported = errors.New("cloudiac: free space probe is not supported on this platform") )
Fetch errors. Every one is a hard stop: there is no retry with another URL.
var ( ErrStateConfig = errors.New("cloudiac: state store is not configured") ErrStateTooLarge = errors.New("cloudiac: state exceeds the size cap") ErrStateTampered = errors.New("cloudiac: sealed state failed authentication") )
State errors. Messages never carry state bytes or key material.
var ( ErrStateLocked = errors.New("cloudiac: cloud state is locked by another run") ErrNotImplemented = errors.New("cloudiac: step is not implemented yet") ErrPlanMismatch = errors.New("cloudiac: the saved plan does not match the approved plan hash") ErrPlanExpired = errors.New("cloudiac: the saved plan is older than cloud.plan_max_age_minutes") ErrPlanStale = errors.New("cloudiac: the state changed after the plan was made") ErrDestroyNotConfirmed = errors.New("cloudiac: destroy needs an explicit confirmation") ErrStateWriteRejected = errors.New("cloudiac: state write was rejected, the cloud and the stored state may differ") // ErrStateQuarantined fails closed: a plan against stale state could recreate resources that exist. ErrStateQuarantined = errors.New("cloudiac: the stack has quarantined state that must be recovered first") )
Sentinels callers match with errors.Is.
var ErrChecksumNotListed = errors.New("cloudiac: archive is not listed in the signed checksum file")
ErrChecksumNotListed means the signed checksum file has no line for the downloaded archive.
var ErrNotConfigured error = &unavailableError{msg: "cloudiac: no engine configured"}
ErrNotConfigured is returned when no engine implementation is wired in.
var ErrPlanNotFound = errors.New("cloudiac: no saved plan for this stack")
ErrPlanNotFound means the stack has no saved plan to apply.
var ErrSandboxSpec = errors.New("cloudiac: unsafe sandbox spec")
ErrSandboxSpec marks a step spec the builder refuses to produce.
Functions ¶
func FetchLimitsFrom ¶
func FetchLimitsFrom(get func() SettingsReader) func() FetchLimits
FetchLimitsFrom reads the fetch limits per call; a nil reader yields zeros, which NewFetcher refuses.
func InstallInto ¶
func InstallInto(enabled bool, planner iac.CloudPlanner, policy iac.PolicyChecker) bool
InstallInto wires the planner and policy into iac only when the cloud flag is on. With it off nothing is installed and cloud documents keep failing loudly.
func IsProtectedType ¶
IsProtectedType reports whether deleting a resource type needs an opt in.
func LiveSandbox ¶
func LiveSandbox(get func() SettingsReader, runtime string) func(TofuConfig) TofuConfig
LiveSandbox returns a TofuConfig.Live that reads image, user, network and limits per run. An empty image or network leaves the field empty, so the plan fails as not configured.
func LoadSigstoreTrustedRoot ¶
func LoadSigstoreTrustedRoot(cacheDir string) (*root.TrustedRoot, error)
LoadSigstoreTrustedRoot fetches the public Sigstore trust root over TUF, caching it under cacheDir.
func RedactLog ¶
RedactLog masks every secret in a step log, including each line of a multi-line key. Short fragments are skipped so ordinary words are not blanked out.
func RedactStepOutput ¶
func RedactStepOutput(out string, limit int, credRedact func(string) string, sensitive []string, state []byte) string
RedactStepOutput masks credential lines, the whole state blob and each sensitive value, then keeps the tail within limit. Masking runs first so a cut never exposes half a secret.
func RefusalsError ¶
RefusalsError joins refusals into one error, or returns nil when empty.
func SensitiveValues ¶
SensitiveValues collects every string under an attribute that plan or state JSON marks sensitive.
Types ¶
type AccountInfo ¶
type AccountInfo struct {
Region string
CompartmentOCID string
Namespace string
Credential CredentialHandle
}
AccountInfo is what a CloudAccount document resolves to; secrets stay behind the handle.
type AccountResolver ¶
type AccountResolver interface {
ResolveAccount(ctx context.Context, name string) (AccountInfo, error)
}
AccountResolver looks up a CloudAccount by name.
type ApplyRequest ¶
type ApplyRequest struct {
Spec ModuleSpec
Cred CredentialHandle
PlanHash string
// ConfirmDestroy must be set to run a destroy plan.
ConfirmDestroy bool
}
ApplyRequest names the approved saved plan. The module must be the one the plan was made from.
type BinaryEnsurer ¶
BinaryEnsurer returns a verified OpenTofu binary path; *Fetcher implements it.
type BucketSpec ¶
BucketSpec is an object storage bucket in its object storage namespace. Buckets are protected from destroy unless Unprotected is set.
type CloudPlannerAdapter ¶
type CloudPlannerAdapter struct {
Engine DetailedPlanner
Accounts AccountResolver
}
CloudPlannerAdapter implements iac.CloudStackPlanner: every cloud document of one Levelrail stack and account is rendered into one module with one sealed state.
func (CloudPlannerAdapter) ApplyCloud ¶
func (a CloudPlannerAdapter) ApplyCloud(ctx context.Context, req iac.CloudApplyRequest) (iac.CloudApplyResult, error)
ApplyCloud re-renders the account group of the target exactly as planned and runs the saved plan the approval names; the engine refuses any other hash.
func (CloudPlannerAdapter) CloudReady ¶
func (a CloudPlannerAdapter) CloudReady() bool
CloudReady reports false until both the engine and the account resolver are set, so even record-only kinds fail as unavailable instead of reporting unchanged.
func (CloudPlannerAdapter) PlanCloud ¶
func (a CloudPlannerAdapter) PlanCloud(ctx context.Context, r iac.CloudResource) (iac.CloudDiff, error)
PlanCloud plans one document as a stack of its own; apply uses PlanCloudStack.
func (CloudPlannerAdapter) PlanCloudStack ¶
func (a CloudPlannerAdapter) PlanCloudStack(ctx context.Context, stack string, rs []iac.CloudResource) []iac.CloudOutcome
PlanCloudStack groups the documents by account, plans one module per group and splits the changes back to the documents by resource address.
type ConnectionAccounts ¶
type ConnectionAccounts struct {
Conns ConnectionGetter
Sealed cloudconn.SealedReader
}
ConnectionAccounts maps a CloudAccount name to the stored connection of the same name, and opens that connection's sealed credential only when a step needs it.
func (ConnectionAccounts) ResolveAccount ¶
func (c ConnectionAccounts) ResolveAccount(ctx context.Context, name string) (AccountInfo, error)
ResolveAccount implements AccountResolver.
func (ConnectionAccounts) ResolveOracle ¶
func (c ConnectionAccounts) ResolveOracle(ctx context.Context, h CredentialHandle) (cloudconn.OracleCredential, error)
ResolveOracle implements OracleResolver; the handle id is the connection name.
type ConnectionGetter ¶
type ConnectionGetter interface {
Get(ctx context.Context, name string) (cloudconn.Connection, error)
}
ConnectionGetter loads a stored cloud connection by name; *cloudconn.Service implements it.
type CostEstimate ¶
CostEstimate is the outcome of pricing a change set.
func (CostEstimate) Allowed ¶
func (e CostEstimate) Allowed() bool
Allowed reports whether the estimate has no refusals.
type CostPolicy ¶
type CostPolicy struct {
// MonthlyLimitMicros is the account limit. Zero means nothing billable is allowed.
MonthlyLimitMicros int64
// AllowUnpriced lets resources without a price through, not estimated.
AllowUnpriced bool
}
CostPolicy bounds the estimated monthly spend of one account.
func NewCostPolicy ¶
func NewCostPolicy(limitMicros int64, requireFullEstimate bool) CostPolicy
NewCostPolicy builds a cost policy from runtime setting values read by the caller. requireFullEstimate true blocks resources without a price.
func (CostPolicy) Estimate ¶
func (c CostPolicy) Estimate(table PriceTable, changes []ResourceChange, existingMicros int64) CostEstimate
Estimate prices the resources a change set leaves in place plus the existing monthly spend, and returns the verdict against the account limit.
type CredentialFile ¶
type CredentialFile struct {
// HostPath is a file on a host tmpfs, written for this step and removed after it.
HostPath string
// EnvName names the variable that tells the provider where the file is.
EnvName string
}
CredentialFile is the one short-lived credential file of a step. Only its path enters the spec.
type CredentialHandle ¶
CredentialHandle refers to a short-lived credential for one step. The engine resolves it at run time so secrets never sit in specs or results.
type DetailedPlanner ¶
type DetailedPlanner interface {
PlanDetailed(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (PlanResult, error)
}
DetailedPlanner is the engine surface the adapter needs; TofuEngine implements it.
type Engine ¶
type Engine interface {
Plan(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (Result, error)
Apply(ctx context.Context, req ApplyRequest) (Result, error)
Destroy(ctx context.Context, req ApplyRequest) (Result, error)
}
Engine runs provisioning steps. Other engines can implement it later.
type ErrorKind ¶
type ErrorKind string
ErrorKind classifies a step failure so callers can react without parsing text.
const ( ErrInvalidSpec ErrorKind = "invalid_spec" ErrCredential ErrorKind = "credential" ErrProvider ErrorKind = "provider" ErrCanceled ErrorKind = "canceled" // ErrTimeout matches iac.CodePlanTimeout so a job can report it without parsing text. ErrTimeout ErrorKind = "plan_timeout" ErrInternal ErrorKind = "internal" )
The failure classes an engine reports.
const ( ErrLockHeld ErrorKind = "lock_held" ErrPolicyRefused ErrorKind = "policy_refused" ErrUnsupported ErrorKind = "not_implemented" // ErrPlanRejected means the saved plan is missing, does not match the approved hash, expired or is stale. ErrPlanRejected ErrorKind = "plan_rejected" // ErrStateDiverged means apply ran but its state could not be written under the fence. ErrStateDiverged ErrorKind = "state_diverged" // ErrQuarantineHeld means the stack has unrecovered quarantined state, so no run may start. ErrQuarantineHeld ErrorKind = "state_quarantined" )
Extra failure classes of the OpenTofu engine.
type ExecRunner ¶
type ExecRunner struct {
// MaxBytes caps each stream; zero uses the env seeded default.
MaxBytes int64
// contains filtered or unexported fields
}
ExecRunner shells to docker or podman with the argv BuildSandboxSpec produced.
func (ExecRunner) Run ¶
func (r ExecRunner) Run(ctx context.Context, spec SandboxSpec) (RunOutput, error)
Run starts the container and waits; the caller's context carries the timeout. A cancelled step is interrupted, killed after the wait delay, and its named container removed.
type FetchConfig ¶
type FetchConfig struct {
DataDir string
Version string
MaxBytes int64
MinFreeBytes int64
Timeout time.Duration
// FreeBytes reports free space under DataDir; the caller supplies it per platform.
FreeBytes func(dir string) (int64, error)
HTTPClient *http.Client
BaseURL string
Verifier SignatureVerifier
// AllowChecksumOnly accepts a release without a signature check. Default off.
AllowChecksumOnly bool
GOOS, GOARCH string
}
FetchConfig holds the fetch limits. Values come from runtime settings; zero values refuse.
func (*FetchConfig) ApplyLimits ¶
func (c *FetchConfig) ApplyLimits(l FetchLimits)
ApplyLimits copies the runtime settings into the config and installs the platform free space probe.
type FetchLimits ¶
FetchLimits are the runtime settings that bound a fetch; NewFetcher refuses zero values.
type Fetcher ¶
type Fetcher struct {
// contains filtered or unexported fields
}
Fetcher downloads and caches the pinned OpenTofu binary. It does no I/O until Ensure.
func NewFetcher ¶
func NewFetcher(cfg FetchConfig) (*Fetcher, error)
NewFetcher validates the config without touching the network or disk.
type InstanceSpec ¶
type InstanceSpec struct {
Name string
Network string
Shape string
OCPUs int
MemoryGB int
AvailabilityDomain string
ImageOCID string
}
InstanceSpec is a compute instance placed in a rendered network.
type KeyDeriver ¶
KeyDeriver is the part of secrets.Manager the state store needs.
type LiveFetcher ¶
type LiveFetcher struct {
Base FetchConfig
Limits func() FetchLimits
// contains filtered or unexported fields
}
LiveFetcher builds a Fetcher per call so changed fetch settings apply to the next download.
type MaterialSource ¶
type MaterialSource func(ctx context.Context, version string) (ReleaseMaterial, error)
MaterialSource loads the release material for a version, for example from a fetched bundle.
type ModuleSpec ¶
type ModuleSpec struct {
Name string
Provider string
Files map[string][]byte
Variables map[string]string
}
ModuleSpec is a rendered module the engine runs, never raw user input.
func RenderOCI ¶
func RenderOCI(s OCISpec) (ModuleSpec, error)
RenderOCI renders the spec to a ModuleSpec holding Terraform JSON configuration. Output is deterministic and never carries credentials.
type NetworkPolicy ¶
NetworkPolicy is the egress rule set for step containers, applied to a pre-created network.
func NewNetworkPolicy ¶
func NewNetworkPolicy(network string, controlPlane []string) (NetworkPolicy, error)
NewNetworkPolicy adds the control plane addresses to the builtin deny list. The network itself is created and firewalled outside this package from DenyCIDRs.
func (NetworkPolicy) Denies ¶
func (p NetworkPolicy) Denies(addr string) bool
Denies reports whether addr falls in the deny list; the firewall step and tests share it.
func (NetworkPolicy) RunFlags ¶
func (p NetworkPolicy) RunFlags() []string
RunFlags returns the container flags that attach a step to the policy network.
type NetworkSpec ¶
NetworkSpec is a VCN with one public subnet.
type OCISpec ¶
type OCISpec struct {
Name string
Region string
CompartmentOCID string
Networks []NetworkSpec
Buckets []BucketSpec
Instances []InstanceSpec
}
OCISpec is every cloud resource of one stack, rendered as one module so references resolve inside it. Provider credentials are not part of it; the engine supplies them per step.
type OracleResolver ¶
type OracleResolver interface {
ResolveOracle(ctx context.Context, h CredentialHandle) (cloudconn.OracleCredential, error)
}
OracleResolver turns a credential handle into the materializable Oracle credential.
type PlanChange ¶
PlanChange is one managed resource change from the saved plan.
type PlanResult ¶
type PlanResult struct {
Changes []PlanChange
Cost CostEstimate
Warnings []string
Hash string
}
PlanResult is the typed plan with its cost verdict and the hash a reviewer approves.
func (PlanResult) Summary ¶
func (p PlanResult) Summary() string
Summary is a one line count that never carries values.
type Policy ¶
type Policy struct {
// MaxDestroys is the number of destroys allowed without an override.
MaxDestroys int
// AllowProtectedDelete is the explicit opt in to delete data resources.
AllowProtectedDelete bool
}
Policy holds the knobs for the change set checks.
func NewPolicy ¶
NewPolicy builds a policy from runtime setting values read by the caller. A negative cap is treated as zero so a bad value stays strict.
func (Policy) Check ¶
func (p Policy) Check(changes []ResourceChange) []Refusal
Check returns every refusal for the change set, ordered by address then code.
type PolicyAdapter ¶
type PolicyAdapter struct {
Policy func() Policy
}
PolicyAdapter exposes Policy.Check as an iac.PolicyChecker, reading the policy per call.
func (PolicyAdapter) CheckCloud ¶
func (p PolicyAdapter) CheckCloud(changes []iac.CloudChange) []iac.CloudRefusal
CheckCloud implements iac.PolicyChecker. A nil policy func stays strict.
type PriceTable ¶
type PriceTable interface {
// Monthly returns the monthly price for one resource and whether it is priced.
Monthly(resourceType string) (micros int64, ok bool)
// AsOf names the table version date shown next to every estimate.
AsOf() string
}
PriceTable maps a resource type to a monthly list price in micro units. Implementations are static: no network lookups.
type ReleaseMaterial ¶
type ReleaseMaterial struct {
Sums []byte
Entity verify.SignedEntity
}
ReleaseMaterial is the checksum file of one release plus its Sigstore bundle. A bare .sig and .pem pair carries no transparency log proof, so a bundle is required.
func ParseReleaseBundle ¶
func ParseReleaseBundle(sums, bundleJSON []byte) (ReleaseMaterial, error)
ParseReleaseBundle pairs the checksum file with a Sigstore bundle in its JSON form.
type ReleaseVerifier ¶
type ReleaseVerifier struct {
// contains filtered or unexported fields
}
ReleaseVerifier checks the keyless signature of the OpenTofu checksum file and then the archive against it.
func NewReleaseVerifier ¶
func NewReleaseVerifier(version string, trusted root.TrustedMaterial, material MaterialSource) *ReleaseVerifier
NewReleaseVerifier binds the verifier to the pinned version, whose minor branch fixes the signing identity.
type ResourceChange ¶
ResourceChange is one entry of a rendered change set.
type Result ¶
type Result struct {
Step Step
Changes []Change
Outputs map[string]string
Log string
// PlanHash names the saved plan a plan produced or an apply ran.
PlanHash string
// StateVersion is the stored state version after the step.
StateVersion int64
// Partial means the apply failed but the state it reached was stored.
Partial bool
// Diverged means the new state could not be stored under the fence.
Diverged bool
}
Result is the typed outcome of a step. Output is already redacted.
type RunDir ¶
RunDir is the private host directory of one engine run. It holds the module, the plaintext state copy, the credential files and the plan; all of it lives on the host only for the run.
func NewRunDir ¶
NewRunDir creates a 0700 run dir under base and hands the shared subdirs to the step user.
func (*RunDir) Cleanup ¶
func (r *RunDir) Cleanup()
Cleanup overwrites every regular file best effort, then removes the tree.
type Runner ¶
type Runner interface {
Run(ctx context.Context, spec SandboxSpec) (RunOutput, error)
}
Runner executes one sandboxed step. Tests swap in a fake so no container, binary or cloud is ever touched.
type SandboxInput ¶
type SandboxInput struct {
Runtime string
Image string
User string
Name string
Step Step
ModuleDir string
// RunDir is the private per-run host directory; its work and state subdirs are shared by every step.
RunDir string
TofuBinary string
PluginDir string
Credential CredentialFile
Network NetworkPolicy
Limits SandboxLimits
Env map[string]string
}
SandboxInput describes one step. Nothing in it may carry a secret value.
type SandboxLimits ¶
SandboxLimits bound one step. Values come from runtime settings; zero refuses. WorkTmpMB is the free space the run directory filesystem must have; StateTmpMB sizes /tmp.
type SandboxSpec ¶
type SandboxSpec struct {
Runtime string
Image string
Name string
User string
ReadOnlyRoot bool
CapDrop []string
SecurityOpt []string
PidsLimit int
MemoryMB int
CPUs string
NetworkFlags []string
Mounts []Mount
Tmpfs []Tmpfs
Env []string
Workdir string
Entrypoint string
Args []string
}
SandboxSpec is the typed run spec for one step container.
func BuildSandboxSpec ¶
func BuildSandboxSpec(in SandboxInput) (SandboxSpec, error)
BuildSandboxSpec validates the input and returns the hardened run spec.
func (SandboxSpec) Argv ¶
func (s SandboxSpec) Argv() []string
Argv returns the full container command line, starting with the runtime binary.
type SavedPlan ¶
type SavedPlan struct {
Hash string `json:"-"`
Plan []byte `json:"plan"`
Changes []ResourceChange `json:"changes"`
StateVersion int64 `json:"state_version"`
Destroy bool `json:"destroy"`
CreatedAt time.Time `json:"-"`
}
SavedPlan is the reviewed plan of one stack. Changes are kept beside the bytes, sealed with them, so policy and cost are re-checked before any step runs.
type SavedPlanRunner ¶
type SavedPlanRunner interface {
Apply(ctx context.Context, req ApplyRequest) (Result, error)
Destroy(ctx context.Context, req ApplyRequest) (Result, error)
}
SavedPlanRunner runs an approved saved plan; TofuEngine implements it.
type SettingsReader ¶
type SettingsReader interface {
Int(ctx context.Context, key string) int
Bool(ctx context.Context, key string) bool
}
SettingsReader is the runtime settings surface the engine reads per run.
type SignatureVerifier ¶
type SignatureVerifier interface {
Verify(ctx context.Context, archiveName, archivePath string) error
}
SignatureVerifier checks the release signature of a downloaded archive.
type StateDB ¶
type StateDB interface {
GetCloudState(ctx context.Context, account, stack string) (store.CloudState, error)
PutCloudState(ctx context.Context, lock store.CloudStateLock, expectVersion int64, sealed []byte, now time.Time) (int64, error)
PutCloudPlan(ctx context.Context, p store.CloudPlan) error
GetCloudPlan(ctx context.Context, account, stack string) (store.CloudPlan, error)
DeleteCloudPlan(ctx context.Context, account, stack, hash string) error
InsertCloudStateQuarantine(ctx context.Context, q store.CloudStateQuarantine) (int64, error)
ListCloudStateQuarantine(ctx context.Context, account, stack string) ([]store.CloudStateQuarantine, error)
}
StateDB is the part of the store the state store needs.
type StateLocker ¶
type StateLocker interface {
AcquireCloudStateLock(ctx context.Context, account, stack, holder string, ttl time.Duration, now time.Time) (store.CloudStateLock, error)
ReleaseCloudStateLock(ctx context.Context, lock store.CloudStateLock) error
}
StateLocker is the fenced lease part of the store.
type StateQuarantine ¶
type StateQuarantine struct{ ID int64 }
StateQuarantine carries the id of the quarantine row an apply wrote; match it with errors.As.
func (*StateQuarantine) Error ¶
func (q *StateQuarantine) Error() string
type StateStore ¶
type StateStore struct {
// contains filtered or unexported fields
}
StateStore seals state before it reaches the DB. It never logs and has no method that serves state over an API.
func NewStateStore ¶
func NewStateStore(db StateDB, keys KeyDeriver, maxBytes int64) (*StateStore, error)
NewStateStore needs the size cap from runtime settings; zero refuses.
func (*StateStore) DropPlan ¶
func (s *StateStore) DropPlan(ctx context.Context, account, stack, hash string) error
DropPlan removes the saved plan if it is still the one with this hash.
func (*StateStore) Load ¶
Load returns the plaintext state and its version. A stack with no state yet returns nil and version 0.
func (*StateStore) LoadPlan ¶
LoadPlan opens the saved plan and checks its bytes still match the recorded hash.
func (*StateStore) OpenQuarantine ¶
func (s *StateStore) OpenQuarantine(q store.CloudStateQuarantine) ([]byte, error)
OpenQuarantine returns the plaintext of a quarantine row for an operator recovery step.
func (*StateStore) Quarantine ¶
func (s *StateStore) Quarantine(ctx context.Context, account, stack string, fence int64, reason string, state []byte) (int64, error)
Quarantine seals state that could not be stored live and returns the row id. It takes no lease and no size cap, since the blob describes real resources and losing it would orphan them.
func (*StateStore) Quarantined ¶
func (s *StateStore) Quarantined(ctx context.Context, account, stack string) ([]store.CloudStateQuarantine, error)
Quarantined lists the unresolved quarantine rows of a stack; any row means the stack must not run.
type StaticPrices ¶
StaticPrices is an in-memory PriceTable.
type StringSettings ¶
StringSettings is the string part of the runtime settings service.
type TofuConfig ¶
type TofuConfig struct {
Runtime string
Image string
User string
PluginDir string
// WorkBase holds the private run dirs; prefer a tmpfs, since the plaintext state and plan
// sit there for the run. A disk backed base is allowed but reported as a plan warning.
WorkBase string
// Live refreshes the sandbox knobs from runtime settings at the start of every run.
Live func(TofuConfig) TofuConfig
Holder string
Network NetworkPolicy
Limits SandboxLimits
Timeout func() time.Duration
// PlanMaxAge caps how old a saved plan may be when it is applied; zero refuses every apply.
PlanMaxAge func() time.Duration
Policy func() Policy
Cost func() CostPolicy
Prices PriceTable
// ExistingSpend reports the account's current monthly micros; nil means zero.
ExistingSpend func(ctx context.Context, account string) int64
}
TofuConfig holds the engine knobs. Funcs are read per run so runtime settings apply live.
func SettingsConfig ¶
func SettingsConfig(cfg TofuConfig, get func() SettingsReader) TofuConfig
SettingsConfig fills the live knobs of a TofuConfig from runtime settings. A nil reader keeps every guard at its strictest value.
type TofuDeps ¶
type TofuDeps struct {
Runner Runner
Binary BinaryEnsurer
Locks StateLocker
State *StateStore
Creds OracleResolver
}
TofuDeps are the collaborators; any nil one makes Plan fail with ErrNotConfigured.
type TofuEngine ¶
type TofuEngine struct {
// contains filtered or unexported fields
}
TofuEngine is the OpenTofu Engine. Apply and destroy only ever run a saved, approved plan.
func NewTofuEngine ¶
func NewTofuEngine(cfg TofuConfig, deps TofuDeps) *TofuEngine
NewTofuEngine builds the engine; missing pieces surface at run time, not here.
func (*TofuEngine) Apply ¶
func (e *TofuEngine) Apply(ctx context.Context, req ApplyRequest) (Result, error)
Apply runs the saved plan whose hash the caller approved, never a fresh diff.
func (*TofuEngine) Destroy ¶
func (e *TofuEngine) Destroy(ctx context.Context, req ApplyRequest) (Result, error)
Destroy runs a saved destroy plan; it needs the explicit confirmation and passes the destroy cap.
func (*TofuEngine) Plan ¶
func (e *TofuEngine) Plan(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (Result, error)
Plan implements Engine.
func (*TofuEngine) PlanDestroy ¶
func (e *TofuEngine) PlanDestroy(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (PlanResult, error)
PlanDestroy saves a destroy plan; only Destroy with an explicit confirmation can run it.
func (*TofuEngine) PlanDetailed ¶
func (e *TofuEngine) PlanDetailed(ctx context.Context, spec ModuleSpec, cred CredentialHandle) (PlanResult, error)
PlanDetailed runs init, plan and show under the state lease, saves the sealed plan and returns it typed. The account is the credential handle id and the stack is the module name.