Documentation
¶
Overview ¶
Package apply is the imperative, one-shot sibling of GitOps. It turns a bundle of miabi.io/v1 manifests into a plan (dry run) or converges the workspace to them, by diffing desired state against a live snapshot and driving the existing application/storage/database services. GitOps reuses this same engine, so "apply once" and "stay in sync" share one code path.
Index ¶
- Constants
- Variables
- type Failure
- type NodeStatus
- type Options
- type Result
- type Service
- func (s *Service) Apply(ctx context.Context, workspaceID uint, manifests []byte, opts Options) (*Result, error)
- func (s *Service) Delete(ctx context.Context, workspaceID uint, manifests []byte, dryRun bool) (*Result, error)
- func (s *Service) LiveStatus(workspaceID uint) map[string]string
- func (s *Service) LiveTopology(ctx context.Context, workspaceID uint, syncError string) (*Topology, error)
- func (s *Service) Plan(ctx context.Context, workspaceID uint, manifests []byte, opts Options) (*declarative.Plan, *declarative.ResourceSet, error)
- func (s *Service) SetPortExposure(extConfig func() route.ExternalConfig, bindings *portbinding.Service)
- func (s *Service) Teardown(ctx context.Context, workspaceID uint, sourceID string) (*Result, error)
- func (s *Service) Topology(ctx context.Context, workspaceID uint, manifests []byte, opts Options) (*Topology, error)
- type Topology
- type TopologyNode
Constants ¶
const ManagedByGitOps = "gitops"
ManagedByGitOps marks resources created/managed by the declarative apply engine (GitOps or one-shot apply). Prune only ever deletes these.
const MetaDigest = "miabi.io/digest"
MetaDigest records, on a converged application, the image digest the apply engine last reconciled to. It lets the live snapshot report the running digest so a digest-pinned manifest converges instead of perpetually drifting.
Variables ¶
var ( // ErrInvalidManifest signals a parse/validation failure (HTTP 400). ErrInvalidManifest = errors.New("invalid manifest") // ErrUnsupportedKind is returned when a plan needs a mutation the v1 executor // does not perform. The plan still lists the change. ErrUnsupportedKind = errors.New("kind not yet supported by apply") )
Functions ¶
This section is empty.
Types ¶
type Failure ¶
type Failure struct {
Kind string `json:"kind"`
Name string `json:"name"`
Action string `json:"action"`
Error string `json:"error"`
}
Failure records one change that could not be applied.
type NodeStatus ¶
type NodeStatus string
NodeStatus is a resource's sync state relative to the desired manifests, derived from the convergence plan.
const ( NodeSynced NodeStatus = "synced" // live state matches desired (noop) NodeOutOfSync NodeStatus = "out_of_sync" // exists but drifted (update) NodeMissing NodeStatus = "missing" // declared but not yet created (create) NodeOrphaned NodeStatus = "orphaned" // live + GitOps-owned but absent from desired (delete) )
type Options ¶
type Options struct {
Prune bool
// OwnerSource, when set, is the GitOps project id that owns this apply. Every
// resource created/updated in the run is labeled with it (miabi.io/gitops-source)
// so the project's resources can later be listed or torn down on their own.
OwnerSource string
}
Options tunes a plan/apply.
type Result ¶
type Result struct {
Plan *declarative.Plan `json:"plan"`
Applied int `json:"applied"`
DryRun bool `json:"dry_run"`
Failures []Failure `json:"failures,omitempty"`
WorkspaceID uint `json:"workspace_id"`
}
Result is the outcome of an apply run.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service computes and executes declarative plans for a workspace.
func NewService ¶
func NewService(apps *application.Service, storage *storage.Service, dbs *database.Service, stacks *stack.Service, secrets *secret.Service, routes *route.Service, domains *domain.Service) *Service
NewService wires the apply engine over the existing resource services.
func (*Service) Apply ¶
func (s *Service) Apply(ctx context.Context, workspaceID uint, manifests []byte, opts Options) (*Result, error)
Apply computes the plan and executes it. A change that fails is recorded in Result.Failures; the run continues so independent resources still converge.
func (*Service) Delete ¶
func (s *Service) Delete(ctx context.Context, workspaceID uint, manifests []byte, dryRun bool) (*Result, error)
Delete removes exactly the resources a manifest bundle names — the inverse of Apply (`delete -f`). It matches each manifest entry against the live workspace by kind+name and deletes the matches in dependency-safe order (dependents before their dependencies); entries that do not exist are skipped. Unlike a pruning Apply, it deletes a matched resource regardless of which subsystem owns it, since the caller named it explicitly. dryRun returns the plan only.
func (*Service) LiveStatus ¶
LiveStatus returns the current runtime status of the workspace's stateful resources (applications and databases), keyed by topology node key ("<Kind>/<slug>"). It is cheap — no git clone and no container inspection — so the detail page can poll it to keep node health live between full (cloning) topology loads.
func (*Service) LiveTopology ¶
func (s *Service) LiveTopology(ctx context.Context, workspaceID uint, syncError string) (*Topology, error)
LiveTopology builds the graph from live (deployed) state only, used as a graceful fallback when the desired manifests cannot be loaded or parsed (a broken commit, an unreachable repo). It shows the GitOps-owned resources that are still running — the last successful sync — and surfaces syncError so the view explains why it is degraded instead of going blank. Edges are derived from live specs (structural links like route→app survive; env-template links do not, since live env is already resolved).
func (*Service) Plan ¶
func (s *Service) Plan(ctx context.Context, workspaceID uint, manifests []byte, opts Options) (*declarative.Plan, *declarative.ResourceSet, error)
Plan parses the manifests and diffs them against live state, returning the convergence plan without mutating anything.
func (*Service) SetPortExposure ¶
func (s *Service) SetPortExposure(extConfig func() route.ExternalConfig, bindings *portbinding.Service)
SetPortExposure wires the reconcilers for an Application's per-port exposure: externalAccess (reverse-proxy URLs) and publish/hostPort (host-port bindings). Nil-safe: when unset, those manifest fields are ignored.
func (*Service) Teardown ¶
Teardown deletes every resource owned by a single GitOps source — those tagged with its gitops-source label — in dependency-safe order. Used when a project is deleted with the cascade option, so one project's resources can be removed without touching another's (unlike a workspace-wide prune). Resources created before per-source labeling existed carry no label and are left untouched.
func (*Service) Topology ¶
func (s *Service) Topology(ctx context.Context, workspaceID uint, manifests []byte, opts Options) (*Topology, error)
Topology parses the manifests, diffs them against live state, and returns the resource graph for the project-detail view: every declared resource as a node (with its sync status and a link to the live resource), plus the dependency edges between them. Orphaned GitOps-owned resources (present live but dropped from the manifests) are included so the graph shows prune candidates too.
type Topology ¶
type Topology struct {
Nodes []TopologyNode `json:"nodes"`
Edges []declarative.Edge `json:"edges"`
Counts map[NodeStatus]int `json:"counts"`
// Error, when set, means the desired manifests could not be loaded or parsed
// (e.g. a broken commit). Nodes/Edges then reflect the last-known live
// (deployed) state instead of the desired graph, so the view degrades to
// "what is still running, plus why the latest sync failed" rather than going
// blank. Empty on a healthy response.
Error string `json:"error,omitempty"`
// Live is true when Nodes/Edges came from the live fallback rather than the
// desired manifests, so the UI can label statuses as last-known rather than
// authoritative.
Live bool `json:"live,omitempty"`
}
Topology is the resource graph of a manifest bundle: the nodes (resources) and the directed edges (dependencies) between them, plus a per-status tally.
type TopologyNode ¶
type TopologyNode struct {
Key string `json:"key"` // "<Kind>/<name>" — stable node id, matches edge endpoints
Kind string `json:"kind"` // Application, Database, Volume, Route, Stack, Secret, Domain
Name string `json:"name"`
Status NodeStatus `json:"status"`
// LiveID/Slug point at the live resource so the UI can deep-link to its detail
// page. LiveID is 0 when the resource is not yet created (missing).
LiveID uint `json:"live_id,omitempty"`
Slug string `json:"slug,omitempty"`
// Health is a kind-specific runtime status (e.g. an application's "running"),
// empty when the kind has no meaningful runtime state or is not live yet.
Health string `json:"health,omitempty"`
// URL is the public address a resource is reachable at, when it has one (a
// Route's host/path with its scheme). Empty for kinds with no public URL.
URL string `json:"url,omitempty"`
}
TopologyNode is one resource in the project graph: its declarative identity, sync status, a link to the live resource (when it exists), and an optional runtime health string.