Documentation
¶
Overview ¶
Package seatcred resolves a seat's fleet Redis user and password in the process that needs them (nova-tools#4052). nova-sprint, nova-card, nova-swarm and nova-wake take `--seat <name>` (or NOVA_SEAT) and read the seat's file through pkg/secrets -- the same store, key and sops, and the same checks, `nova-secrets exec` uses -- so no shell wrapper stands between a coordinator and its own store.
The password is held as a secrets.Secret: never printed, never logged, never an argument. It is handed to the Redis client in memory and, for the one child that needs it (`nova-sprint redis-cli`), to that child's environment only; it is never set in this process's own environment, so no other child this process starts inherits it.
Index ¶
- Constants
- Variables
- func Addr() string
- func FromArgs(args []string, getenv func(string) string) ([]string, error)
- func PasswordKey(user string) string
- func ProfilePath(tool string, getenv func(string) string) (string, error)
- type ConfigProfile
- type Cred
- type Paths
- type Profile
- type Selection
- func (s *Selection) Active() (c Cred, ok bool, err error)
- func (s *Selection) Addr() string
- func (s *Selection) FromArgs(args []string, getenv func(string) string) ([]string, error)
- func (s *Selection) Select(seat string)
- func (s *Selection) SelectProfile(p Profile, resolve func(seat string) (Cred, error))
- func (s *Selection) SelectWith(seat, redisAddr string, resolve func(seat string) (Cred, error))
- func (s *Selection) Selected() string
Constants ¶
const ( // SeatEnv names the seat when no --seat flag does. SeatEnv = "NOVA_SEAT" // StoreEnv overrides the store directory, DefaultStore under $HOME. StoreEnv = "NOVA_SECRETS_STORE" // KeyEnv overrides the seat's age key, DefaultKeyDir/<seat>.key under $HOME. KeyEnv = "NOVA_SECRETS_KEY" // SopsEnv overrides the sops binary, else sops on PATH. SopsEnv = "NOVA_SECRETS_SOPS" // UserEnv picks the Redis ACL user when the seat's file holds more than // one password; it is the variable internal/nsprint/store already reads. UserEnv = "NOVA_SPRINT_REDIS_USER" // DefaultStore and DefaultKeyDir are the fleet layout under $HOME. DefaultStore = "nova-bench/secrets" DefaultKeyDir = ".config/nova-secrets" )
const ConfigProfileColumns = "name, dsn, password env"
ConfigProfileColumns names the tab-separated columns for a nova-config seat profile.
const ProfileColumns = "name, redis addr, redis user, secret env, store, key[, github token env]"
ProfileColumns names the tab-separated columns, in order; a refusal about a row prints it so the fix needs no doc. The seventh, the GitHub token env, is optional: a six-column row is the #4330 row, and its GitHub verbs read GH_TOKEN from the session as before.
const ProfileFile = "seats.tsv"
ProfileFile is the profile's name under $XDG_CONFIG_HOME/<tool>/.
Variables ¶
var ErrNoProfileRow = errors.New("no row")
ErrNoProfileRow is wrapped by LoadProfile's refusal when the file has no row for the seat (or there is no file).
var Users = []string{"coordinator", "bench"}
Users is the order a seat's Redis user is chosen in when UserEnv is unset: the first whose password the seat's file holds.
Functions ¶
func PasswordKey ¶
PasswordKey is the key in a seat's file that holds user's Redis password.
Types ¶
type ConfigProfile ¶
type ConfigProfile struct {
Name string // the seat --seat names
DSN string // the PostgreSQL DSN, postgres://user@host:port/db
PasswordEnv string // the name of the variable that holds the password
}
ConfigProfile is one seats.tsv row for nova-config: the seat names where its Postgres store is, and the name of the variable holding its password.
func LoadConfigProfile ¶
func LoadConfigProfile(path, seat string) (ConfigProfile, error)
LoadConfigProfile reads path and returns the row named seat. A missing file or row is an error wrapping ErrNoProfileRow. When seat is not found in the file, the error names the known seats. Blank lines and lines starting with # are skipped.
type Cred ¶
type Cred struct {
Seat string
User string
Key string
Password secrets.Secret
// GitHubKey is the key of the seat's file its seats.tsv row names for the
// GitHub token (the seventh column), "" when the row names none. GitHub
// is the token when the file holds it; GitHubErr says why not when it
// does not (nova-tools#4330).
GitHubKey string
GitHub secrets.Secret
GitHubErr error
}
Cred is one seat's Redis login. The password formats as secrets.Redacted under every verb.
func Resolve ¶
Resolve opens seat's file through secrets.OpenSeatFile and picks its Redis login: UserEnv's user when set, else the first of Users whose password the file holds. A refusal names the seat and what to do, never a value.
func ResolveProfile ¶
ResolveProfile opens the row's seat file through secrets.OpenSeatFile -- the store, key and checks nova-secrets exec uses -- and returns the row's login: User with the password held under SecretEnv, and, when the row names a GitHub token env, the token held under it (a file without it is GitHubErr, refused only when a GitHub verb asks). sops is SopsEnv's, else the one on PATH. A refusal names the seat, the row's file and the remedy, never a value.
type Paths ¶
type Paths struct{ Store, Key, Sops string }
Paths is where a seat's file, key and sops are.
type Profile ¶
type Profile struct {
Name string // the seat --seat names
Addr string // host:port of the seat's Redis
User string // the Redis ACL user
SecretEnv string // the key of the seat's file that holds User's password
Store string // the nova-secrets store directory
Key string // the age key that opens the seat's file; <as>.key names the file <as>.yaml
GitHubEnv string // optional seventh column: the key of the seat's file that holds its GitHub token, "" when none
}
Profile is one seats.tsv row.
func LoadProfile ¶
LoadProfile reads path and returns the row named seat. A missing file or row is an error wrapping ErrNoProfileRow that names the file and its columns; a malformed row is an error naming file:line, even when it is not the seat's row, since the fleet play wrote the whole file. Blank lines and lines starting with # are skipped. A leading ~/ in store or key is home.
type Selection ¶
type Selection struct {
// contains filtered or unexported fields
}
Selection is a seat choice: Select records it, Active resolves it once. The process has one (Process), which the package functions act on; a test holds its own so it runs in parallel with every other (nova-tools#4330).
func (*Selection) Active ¶
Active is the selected seat's login, resolved on first use and kept for the life of the selection. ok is false when no seat is selected: the caller then authenticates as it did before (its own environment variables).
func (*Selection) Addr ¶
Addr is the selected seat's Redis address from its profile row, "" when no seat is selected or its row names none: the address a store dial falls back to when its caller names none.
func (*Selection) FromArgs ¶
FromArgs takes --seat <name> or --seat=<name> out of args (only before a "--", which ends a tool's own flags), selects that seat or else getenv's NOVA_SEAT, and returns the rest. A --seat with no name is an error.
func (*Selection) Select ¶
Select makes seat the selection ("" is none) and forgets any earlier resolution.
func (*Selection) SelectProfile ¶
SelectProfile is SelectWith for a seats.tsv row: the row's seat and its Redis address, resolved through resolve.
func (*Selection) SelectWith ¶
SelectWith is Select with the seat's Redis address (Addr, "" when the seat names none) and the resolution Active runs on first use: resolve (a seat profile row, nova-tools#4330) instead of Resolve's default layout. A nil resolve is Resolve.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package seattest builds a real nova-secrets store for a test: a git working copy with an upstream, recovery.pub, .sops.yaml and one seat's file sealed by sops to a fresh age key, laid out where pkg/seatcred looks by default under a temporary HOME.
|
Package seattest builds a real nova-secrets store for a test: a git working copy with an upstream, recovery.pub, .sops.yaml and one seat's file sealed by sops to a fresh age key, laid out where pkg/seatcred looks by default under a temporary HOME. |