Documentation
¶
Overview ¶
Package verbs is the shared half of the launcher verbs every lock accepts, so that `lox init` drives every lock the same way (GUIDE.md §14):
<lock> init <agent> <lock> profile add [--non-interactive] [--json] [--project DIR] [--profile NAME] [--production] [--credentials ask|vault [--vault-path P]] <target flags> <lock> doctor [--fix [--yes]] [--json]
The verbs themselves are the product's: verbs gives the checks of the non-interactive form (no secret value, ever, and a credential source that is the console asking at start or Vault) and the JSON shapes `lox init` reads.
Index ¶
- Constants
- Variables
- func Credentials(source, vaultPath string) (string, error)
- func ErrorCode(err error, fallback string) string
- func Parse(p kit.Product, fs *flag.FlagSet, args []string) error
- func RefuseSecrets(p kit.Product, fs *flag.FlagSet) error
- func WantsJSON(args []string) bool
- func WriteJSON(w io.Writer, v any) error
- type Check
- type Doctor
- type Error
- type Profile
Constants ¶
const ( FlagNonInteractive = "non-interactive" FlagJSON = "json" FlagProject = "project" FlagProfile = "profile" FlagProduction = "production" FlagCredentials = "credentials" FlagVaultPath = "vault-path" FlagFix = "fix" FlagYes = "yes" )
The flags of the contract that every lock spells the same way.
const ( // CodeUsage: a flag is missing, unknown or invalid. CodeUsage = "usage" // CodeSecret: a secret was given (ErrSecret). CodeSecret = "secret" // CodeExists: the profile is already in the project's config; nothing // was written. CodeExists = "exists" // CodeFailed: anything else (a file could not be written, a check // failed). CodeFailed = "failed" )
The codes of an Error, which `lox init` acts on.
const ( StatusOK = "ok" StatusWarn = "warn" StatusFail = "fail" )
The statuses of a Check.
Variables ¶
var ErrSecret = errors.New("a secret is never given on the command line")
ErrSecret is the refusal of a secret given on the command line: a flag named like a secret (--password, --token, ...), a value that embeds a password (user:pw@host, password=...), or a credential source other than the console asking at start or Vault. errors.Is finds it in the errors of RefuseSecrets and Credentials.
Functions ¶
func Credentials ¶
Credentials checks the credential source of a non-interactive `profile add`: "" (the default) or "ask", the console asks for the secret at start, or "vault", the console reads it from Vault at vaultPath. It returns the source to write ("ask" or "vault"). Any other source, the keychain included, is refused with ErrSecret: under `lox up` the console reads its secret at start or from Vault only. A vault path is checked as secrets.CheckVaultPath does, and refused without "vault". The source is never quoted (a secret pasted in the wrong place).
func ErrorCode ¶
ErrorCode is the code of err: CodeSecret for an error that wraps ErrSecret, else fallback.
func Parse ¶
Parse parses args, the arguments of a non-interactive `profile add` after the verb, into fs and checks them with RefuseSecrets: call it instead of fs.Parse, before writing anything. Unlike fs.Parse it never writes to fs's output (it discards it) and its error never quotes an argument: a flag package error ("invalid value \"…\" for flag -port") would quote the value, which may be a secret pasted in the wrong place. The error names the flag when fs defines it, and wraps ErrSecret for an unknown flag named like a secret (--password).
func RefuseSecrets ¶
RefuseSecrets checks fs after fs.Parse, the parsed flags of a non-interactive `profile add` (Parse calls it). It refuses a flag whose name has a part that names a secret (password, passwd, pwd, secret, token: --password, --vault-token, --api-secret), whatever its value; a value that embeds a password or holds a control or formatting character; and any positional argument (the flag package stops at the first one, so a flag after it would go unchecked: `profile add` takes flags only). It inspects each flag's Value.String(), so a repeatable flag's String must render every value. The error names the flag or the argument's position, never its value (it may be the secret), and wraps ErrSecret for a secret.
Types ¶
type Check ¶
type Check struct {
Check string `json:"check"`
Status string `json:"status"`
Detail string `json:"detail"`
// Fix is what --fix would do, or the command the human runs; empty
// when nothing does.
Fix string `json:"fix,omitempty"`
}
Check is one line of a doctor.
type Doctor ¶
type Doctor struct {
Lock string `json:"lock"`
// OK: no check failed (after the repairs, with --fix).
OK bool `json:"ok"`
// Fixed are the repairs --fix made, one line each.
Fixed []string `json:"fixed"`
Checks []Check `json:"checks"`
}
Doctor is the JSON `doctor --json` prints on stdout. Its exit status is 0 exactly when OK.
type Error ¶
type Error struct {
Lock string `json:"lock"`
Code string `json:"code"`
Error string `json:"error"`
}
Error is the JSON a verb run with --json prints on stdout when it fails (its exit status is not 0).
type Profile ¶
type Profile struct {
Lock string `json:"lock"`
Profile string `json:"profile"`
// Config is the file the profile was written to.
Config string `json:"config"`
Production bool `json:"production"`
// Credentials is "ask" or "vault"; empty for a target that has no
// secret.
Credentials string `json:"credentials,omitempty"`
}
Profile is the JSON `profile add --json` prints on stdout when it wrote the profile (exit status 0).