feat(vault-tui): implement KV client and service for managing secrets

- Added internal/vault/client.go for creating a Vault client with configuration settings.
- Introduced internal/vault/errors.go to classify Vault API errors for better UI handling.
- Created internal/vault/kv.go to manage KV secrets, including listing, reading, writing, and deleting operations.
- Implemented internal/vault/mounts.go to list and describe secret engine mounts.
- Developed internal/vault/service.go to provide a unified entry point for Vault operations.
- Added internal/vault/kv_test.go for comprehensive testing of KV operations.
- Introduced internal/ui/toast.go for transient notifications in the UI.
- Added renovate.json for dependency management and updates.
This commit is contained in:
2026-08-14 11:09:03 +02:00
commit ae30ba1240
85 changed files with 9413 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
package cli
import (
"bufio"
"fmt"
"os"
"strings"
"golang.org/x/term"
"git.morlana.online/f.weber/vault-tui/internal/auth"
)
// promptMissing fills in any of m's still-missing required fields by
// prompting on the controlling TTY. It never blocks when stdin is not a
// terminal (e.g. CI/pipes) — callers should check IsInteractive first and
// treat a non-empty Missing() list as a hard error in that case instead of
// calling this.
func promptMissing(m auth.Method, creds auth.Credentials) error {
missing := auth.Missing(m, creds)
if len(missing) == 0 {
return nil
}
reader := bufio.NewReader(os.Stdin)
for _, f := range missing {
if f.Kind == auth.FieldSecret {
v, err := readPassword(f.Label)
if err != nil {
return err
}
creds[f.Name] = v
continue
}
fmt.Fprintf(os.Stderr, "%s: ", f.Label)
line, err := reader.ReadString('\n')
if err != nil {
return fmt.Errorf("reading %s: %w", f.Label, err)
}
creds[f.Name] = strings.TrimSpace(line)
}
return nil
}
func readPassword(label string) (string, error) {
fmt.Fprintf(os.Stderr, "%s (will be hidden): ", label)
b, err := term.ReadPassword(int(os.Stdin.Fd()))
fmt.Fprintln(os.Stderr)
if err != nil {
return "", fmt.Errorf("reading %s: %w", label, err)
}
return strings.TrimSpace(string(b)), nil
}
// IsInteractive reports whether stdin is a terminal we can prompt on.
func IsInteractive() bool {
return term.IsTerminal(int(os.Stdin.Fd()))
}