Documentation
¶
Index ¶
- func ComputeApprovalHash(res profile.Resolved) string
- func DefaultPrompt(req PromptRequest, stdin io.Reader, stdout io.Writer) (map[string]map[string]bool, error)
- func WithLock(store Store, fullName string, fn func() error) error
- type ApprovedField
- type EphemeralStore
- type FSStore
- type GatedItem
- type Lockable
- type Prompt
- type PromptRequest
- type ReadOnlyStore
- type State
- type Store
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ComputeApprovalHash ¶
ComputeApprovalHash returns a 12-hex-char hash of the non-user gated fields of res, pre-template-expansion. The hash fingerprints the granted values only — contributor identity is excluded — so a grant moving between contributors (e.g. a tpd catalog refactor) does not re-prompt, while any value or key change does.
func DefaultPrompt ¶
func DefaultPrompt(req PromptRequest, stdin io.Reader, stdout io.Writer) (map[string]map[string]bool, error)
DefaultPrompt is the bubbletea implementation: a scrollable flat list of every gated item, with previously approved items pre-checked and newly introduced ones unchecked. Enter submits the visible state as the choices map; esc/Ctrl+C aborts and surfaces as "approval declined".
func WithLock ¶ added in v0.0.8
WithLock runs fn while holding an exclusive advisory lock on the profile's approval state file, so concurrent tpd processes cannot lose each other's approvals. The lock file is a stable sibling of the state file — never the state file itself — so locking the renamed path could not serialize writers. A store that does not implement Lockable (an in-memory overlay, or a decorator that fails to forward LockPath) is rejected rather than run unlocked.
Types ¶
type ApprovedField ¶
ApprovedField represents one field's approved set. Map fields use Keys; the scalar network uses Network (nil = never decided, true = approved, false = denied).
type EphemeralStore ¶
type EphemeralStore struct {
// contains filtered or unexported fields
}
EphemeralStore wraps a base Store with an in-memory overlay. Load returns the overlay (ignoring the base); Save is a no-op. Used by the --dry-run --yes/--no path so the re-filter sees the choice without persisting.
func NewEphemeralStore ¶
func NewEphemeralStore(base Store, overlay State) *EphemeralStore
type FSStore ¶
type FSStore struct {
// contains filtered or unexported fields
}
FSStore writes state files under <root>/approvals/<FullName>.yaml.
func NewFSStore ¶
type GatedItem ¶ added in v0.0.10
type GatedItem struct {
Field string
Key string
Value string
Source profile.Contributor
// PriorApproved reports whether the stored state already approved this
// key. The UI pre-selects such items and leaves newly introduced ones
// unselected, so a profile change cannot silently re-approve old grants.
PriorApproved bool
// Detail is a concise one-line descriptor for the list view ("read/write",
// "host value", "talk", a host→container port binding, ...). Value is the
// full pre-expansion label, shown for the highlighted item in the detail
// pane.
Detail string
// Body is an optional multi-line rendering of the item's full value for
// the detail pane (services format their definition across lines). When
// empty, the pane shows Value wrapped.
Body string
// Benign marks permissions that are almost always harmless — common
// dotfiles, cache dirs, display/runtime env vars, loopback ports,
// D-Bus talk. Benign items are de-emphasized (grey, listed at the
// bottom); everything else — including anything new from a remote import
// — stays prominent, so the emphasis is fail-safe.
Benign bool
// Warning marks grants that deserve a highlighted color and the very top
// of the list. Services are the biggest grant — a whole companion
// container — so they carry it.
Warning bool
}
GatedItem is one gated key the user must decide on.
type Lockable ¶ added in v0.0.8
type Lockable interface {
// LockPath returns the advisory lock file path for fullName's state
// file: a stable sibling of the state file, which Save replaces via
// rename.
LockPath(fullName string) (string, error)
}
Lockable is implemented by stores that back onto a filesystem state file and can name its advisory lock file. WithLock requires it, so a store or decorator that cannot lock never silently runs a transaction unlocked.
type Prompt ¶
type Prompt func(req PromptRequest, stdin io.Reader, stdout io.Writer) (map[string]map[string]bool, error)
Prompt renders the interactive approval dialog and returns the user's choices as a map[field]set[key]bool. If stdin is not a TTY, returns an error.
type PromptRequest ¶
PromptRequest is what the dialog renders. Empty Items = no prompt.
type ReadOnlyStore ¶
type ReadOnlyStore struct {
// contains filtered or unexported fields
}
ReadOnlyStore wraps a base Store: Load delegates to the base; Save is a no-op. Used for the whole --dry-run flow so the initial Filter can read stored approvals (an approved profile must not prompt) but a reconciliation write-back never touches disk.
func NewReadOnlyStore ¶
func NewReadOnlyStore(base Store) *ReadOnlyStore
type State ¶
type State struct {
Hash string
Approved map[string]ApprovedField
}