Documentation
¶
Overview ¶
Package playbook turns a multi-step operational procedure into a typed resource that Flynn can run: provision the command-line tools it needs, run them, verify the outcome, and register what it produced as a supervised Service. A playbook is the outcome-level companion to an integration: an integration spec says how to call one API operation, a playbook spec says how to accomplish a goal by composing many steps.
A playbook is data. Its body is a declarative flow (the same interpreter an integration uses, extended with the dependency, exec, and assert ops), so the stored spec is exactly what runs, and a runtime-authored playbook has no path to arbitrary code: every effect goes through a port the runner wires (a sandboxed command runner, the dependency manager, the resource store), never an ambient capability.
Index ¶
- Constants
- Variables
- func RegisterKind(reg *resource.Registry) error
- func Reserved(name string) bool
- func Sync(ctx context.Context, store *Store) (int, error)
- type CredentialSink
- type Entry
- type ManagerResolver
- type Playbook
- type Result
- type Runner
- type RunnerOption
- type SandboxExecer
- type ServiceBlock
- type Spec
- type Store
Constants ¶
const ( // GroupVersion is the Playbook kind's API group and version. GroupVersion = "playbook.ionagent.io/v1alpha1" // Kind is the resource kind name playbooks are stored under. Kind = "Playbook" )
Variables ¶
var ErrNotFound = errors.New("playbook: not found")
ErrNotFound is returned when a playbook does not exist.
var KindDef = resource.Kind{ APIVersion: GroupVersion, Name: Kind, Schema: specSchema, Singular: "playbook", Plural: "playbooks", }
KindDef is the Playbook kind definition registered with a resource registry.
Functions ¶
func RegisterKind ¶
RegisterKind registers the Playbook kind so a store admits playbooks. It is idempotent.
Types ¶
type CredentialSink ¶
type CredentialSink struct {
// contains filtered or unexported fields
}
CredentialSink implements flow.CredentialSink: it resolves a secret by reference through the secret source (the origin) and materializes it into a hosting provider's secret store by driving the provider's CLI in the sandbox. The value is read from the source and delivered to the provider on standard input, so it never appears on a command line, in the flow's data, in the step output, or in a log. It is the provision-direction counterpart of secret.Source: Source resolves a credential for the agent to use; this sink hands a credential to a workload the agent is standing up.
func NewCredentialSink ¶
func NewCredentialSink(src secret.Source, sb sandbox.Sandbox) *CredentialSink
NewCredentialSink builds a sink over the secret source that resolves references and the sandbox that runs the provider CLI. With either missing, every materialization fails closed.
type Entry ¶
type Entry struct {
Name string
Spec Spec
Raw json.RawMessage
}
Entry is one official playbook from the embedded catalog.
type ManagerResolver ¶
type ManagerResolver struct {
// contains filtered or unexported fields
}
ManagerResolver adapts the dependency manager to the flow's DependencyResolver port, so a playbook's dependency steps ensure a program is present and yield the path to run it.
func NewManagerResolver ¶
func NewManagerResolver(mgr *dependency.Manager) ManagerResolver
NewManagerResolver wraps a dependency manager as a flow dependency resolver.
type Result ¶
Result is the outcome of a playbook run: the flow's return value, and the supervised Service the run registered (nil when the playbook declares none or the result carried no workload to track).
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner executes a playbook's flow with the effect ports wired and, on success, registers the supervised Service the playbook declares. It holds no playbook knowledge: it runs whatever flow the spec carries, and the only things it can do are the ones its ports allow (run a command in the sandbox, resolve a dependency, write a service record).
func NewRunner ¶
func NewRunner(exec flow.Execer, deps flow.DependencyResolver, svc *service.Store, opts ...RunnerOption) *Runner
NewRunner builds a playbook runner. exec runs the flow's exec steps (through the sandbox); deps resolves its dependency steps (through the dependency manager); svc is the service store a successful run registers its workload in (nil disables registration).
func (*Runner) Run ¶
Run executes the playbook's flow with config exposed to it, then registers the declared supervised Service from the flow's result. A flow failure is returned as-is; the service is registered only after the flow succeeds, so a failed run never records a workload it did not finish standing up.
type RunnerOption ¶
type RunnerOption func(*Runner)
RunnerOption configures a Runner.
func WithClock ¶
func WithClock(c clock.Timing) RunnerOption
WithClock sets the time source used to stamp a registered service (default clock.System).
func WithConfirmer ¶
func WithConfirmer(c flow.Confirmer) RunnerOption
WithConfirmer sets the port that asks the operator to approve a playbook's confirm steps (an interactive terminal prompt, or a fail-closed instruction for a non-interactive run). Without it, a confirm step fails closed.
func WithCredentialSink ¶
func WithCredentialSink(s flow.CredentialSink) RunnerOption
WithCredentialSink sets the port that materializes a playbook's secret steps into a provider's secret store. Without it, a secret step fails closed.
func WithObserver ¶
func WithObserver(o flow.Observer) RunnerOption
WithObserver sets the port that watches each command and dependency step as it runs, so a host can show progress while a playbook executes. Without it, the playbook still runs; nothing is reported.
type SandboxExecer ¶
type SandboxExecer struct {
// contains filtered or unexported fields
}
SandboxExecer adapts a sandbox to the flow's Execer port, so a playbook's exec steps run confined in the sandbox rather than spawning a process directly.
func NewSandboxExecer ¶
func NewSandboxExecer(sb sandbox.Sandbox) SandboxExecer
NewSandboxExecer wraps a sandbox as a flow command runner.
func (SandboxExecer) Exec ¶
func (e SandboxExecer) Exec(ctx context.Context, req flow.ExecRequest) (flow.ExecResult, error)
Exec runs the command through the sandbox and returns its exit code and combined output.
type ServiceBlock ¶
type ServiceBlock struct {
// Provider is the provider that owns the workload (for example "fly").
Provider string `json:"provider"`
// Target classifies the workload (static-site, container, vps). Optional.
Target service.Target `json:"target,omitempty"`
}
ServiceBlock declares how to classify the supervised Service a playbook registers when its flow succeeds. The live fields (the service name, its URL, the provider's external id, and the addressing the supervisor replays) come from the flow's return value, so all templating stays inside the flow; this block supplies only the static classification.
type Spec ¶
type Spec struct {
// Description is a short human summary of what the playbook accomplishes.
Description string `json:"description,omitempty"`
// Inputs is a JSON Schema describing the config an operator passes to a run. It is
// documentation and (later) validation; the runner exposes the config to the flow as
// "config" regardless.
Inputs json.RawMessage `json:"inputs,omitempty"`
// Flow is the declarative procedure the playbook runs, in the flow interpreter's shape.
Flow json.RawMessage `json:"flow"`
// Service, when set, is the supervised Service to register from the flow's result.
Service *ServiceBlock `json:"service,omitempty"`
}
Spec is the desired shape of a playbook: a description, an optional input schema for the config an operator supplies, the flow that carries out the procedure, and an optional service block to register on success.
func DecodeSpec ¶
DecodeSpec reads the typed spec from a resource.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the typed playbook facade over a resource.Store. Playbooks live in the instance-global scope, addressed by name.
func NewStore ¶
NewStore returns a playbook facade over rs. The caller must have registered the Playbook kind with the registry rs admits against (see RegisterKind).