Documentation
¶
Overview ¶
Package dryrun records what a mutating command WOULD have sent, and stops it from being sent.
It is a transport rather than a check at each call site because the CLI builds its HTTP client in two places but writes from dozens of verbs, and because the reported request is then the bytes the generated client really assembled, not a preview that could drift.
The Run is the channel, not the error. RoundTrip must return an error to abort — a synthetic response would be parsed as a real result — but the error cannot be relied on to survive: controlplane's networkError formats its cause with %v into an ExitError with no Unwrap. Callers ask the Run whether an interception happened.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Wrap ¶
func Wrap(base http.RoundTripper, run *Run, mutatingGETs ...*regexp.Regexp) http.RoundTripper
Wrap returns base wrapped so that any request that changes state is recorded into run and never sent.
mutatingGETs are path patterns for GET requests that change state anyway: Control Plane declares `GET /v1/cluster/init` and `GET /v1/databases/{id}/tasks/{id}/cancel`, so a method-only rule would let `task cancel --dry-run` really cancel. Each caller supplies the patterns for the spec it vendors; starfleet's three specs have none.
With a nil run it returns base itself, as httplog.Wrap does, so a normal command gets no extra layer.
Types ¶
type Request ¶
type Request struct {
Method string
// URL comes from url.URL.Redacted, so an --api-url carrying
// userinfo credentials cannot be echoed back out of the report.
URL string
Header http.Header
// Body has been through httplog.RedactBody, so secret values are
// masked and the length is bounded; it is never the raw payload.
Body []byte
// BodyIsJSON reports whether Body still parses as JSON. It is
// false for a body that never was JSON, one truncated at
// httplog.MaxDumpBytes, and RedactBody's fail-closed prose summary.
BodyIsJSON bool
}
Request is the write that would have been sent.
type Run ¶
type Run struct {
// contains filtered or unexported fields
}
Run is one dry run's state: the checks that passed, and the write that was stopped.
A nil *Run means dry-run is off, and every method tolerates one, so check sites call Pass unconditionally rather than each guarding on a mode flag.
The mutex is needed: the --wait paths issue requests from more than one goroutine.
func (*Run) Checks ¶
Checks returns a copy of the ledger, in recorded order: a goroutine still unwinding may write to the Run while the renderer reads it.
func (*Run) Intercepted ¶
Intercepted reports whether a write was stopped. A true here is the command's outcome, whatever error the caller also received.