vctx: always exec write and patch (MFA prompt on stdout)
This commit is contained in:
+2
-2
@@ -72,8 +72,8 @@ terminal), and vault's exit code is returned
|
||||
Without colour (piped output, `NO_COLOR`, `table`/`raw`/`pretty` formats)
|
||||
`vctx` execs `vault` exactly as before, so scripts see unchanged output.
|
||||
Streaming or interactive commands (`monitor`, `debug`, `events`, `ssh`,
|
||||
`agent`, `proxy`, `server`, `login`, `operator`, and `write` to an `auth/`
|
||||
path, which may prompt for MFA) are always exec'd and never coloured. `JQ_COLORS`
|
||||
`agent`, `proxy`, `server`, `login`, `operator`, and `write`/`patch`, which
|
||||
may prompt for MFA) are always exec'd and never coloured. `JQ_COLORS`
|
||||
overrides the JSON palette as in `jq`.
|
||||
|
||||
## Flags
|
||||
|
||||
+4
-8
@@ -17,7 +17,6 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"slices"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
@@ -37,9 +36,9 @@ var execVault = syscall.Exec
|
||||
var osExit = os.Exit
|
||||
|
||||
// uncaptured commands are always exec'd: buffering their stdout would hide
|
||||
// streamed output or prompts (unseal keys, MFA passcodes) until exit, or break
|
||||
// the TTY, for ssh.
|
||||
var uncaptured = map[string]bool{"monitor": true, "debug": true, "events": true, "ssh": true, "agent": true, "proxy": true, "server": true, "login": true, "operator": true}
|
||||
// streamed output or prompts (unseal keys, MFA passcodes; write and patch can
|
||||
// prompt for MFA) until exit, or break the TTY, for ssh.
|
||||
var uncaptured = map[string]bool{"monitor": true, "debug": true, "events": true, "ssh": true, "agent": true, "proxy": true, "server": true, "login": true, "operator": true, "write": true, "patch": true}
|
||||
|
||||
func main() {
|
||||
if err := newRootCmd().Execute(); err != nil {
|
||||
@@ -268,15 +267,12 @@ func colourFormat(args, env []string) string {
|
||||
f = val
|
||||
}
|
||||
f = strings.ToLower(f)
|
||||
if len(pos) == 0 || uncaptured[pos[0]] || (pos[0] == "write" && slices.ContainsFunc(pos[1:], isAuthPath)) || (f != "json" && f != "yaml") {
|
||||
if len(pos) == 0 || uncaptured[pos[0]] || (f != "json" && f != "yaml") {
|
||||
return ""
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
// isAuthPath matches auth/ paths; a write there may be a login prompting for MFA on stdout.
|
||||
func isAuthPath(p string) bool { return strings.HasPrefix(strings.TrimPrefix(p, "/"), "auth/") }
|
||||
|
||||
// runChild runs vault with stdin/stderr passed through, forwards SIGTERM and
|
||||
// SIGHUP, then writes its captured stdout colourised to w. It returns vault's
|
||||
// exit code, or 128+n if it died from signal n.
|
||||
|
||||
+4
-4
@@ -285,10 +285,10 @@ func TestColourFormat(t *testing.T) {
|
||||
{[]string{"-format=yaml", "operator", "generate-root"}, nil, ""},
|
||||
{[]string{"operator", "rekey", "-format=json"}, nil, ""},
|
||||
{[]string{"write", "auth/userpass/login/bob"}, []string{"VAULT_FORMAT=json"}, ""},
|
||||
{[]string{"write", "-format=json", "auth/x/login/y"}, nil, ""},
|
||||
{[]string{"write", "-format", "yaml", "auth/x/login/y", "password=p"}, nil, ""},
|
||||
{[]string{"write", "secret/foo", "a=b"}, []string{"VAULT_FORMAT=json"}, "json"},
|
||||
{[]string{"write", "-format=json", "secret/foo", "a=b"}, nil, "json"},
|
||||
{[]string{"write", "-format=json", "ns1/auth/x/login/y"}, nil, ""},
|
||||
{[]string{"write", "-format=json", "secret/foo", "a=b"}, nil, ""},
|
||||
{[]string{"patch", "auth/x/config"}, []string{"VAULT_FORMAT=json"}, ""},
|
||||
{[]string{"patch", "-format=yaml", "secret/foo", "a=b"}, nil, ""},
|
||||
}
|
||||
for _, c := range cases {
|
||||
if got := colourFormat(c.args, c.env); got != c.want {
|
||||
|
||||
Reference in New Issue
Block a user