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
+39
View File
@@ -0,0 +1,39 @@
package cli
import (
"context"
"fmt"
"strings"
"git.morlana.online/f.weber/vault-tui/internal/vault"
)
// splitMountPath finds which configured mount a full logical path like
// "secret/team/prod/db" belongs to, and returns the mount plus the
// remaining path relative to it ("team/prod/db"). Mirrors how `vault kv`
// itself resolves a bare path against sys/internal/ui/mounts.
func splitMountPath(ctx context.Context, svc *vault.Service, full string) (vault.Mount, string, error) {
full = strings.TrimPrefix(full, "/")
mounts, err := svc.Mounts(ctx)
if err != nil {
return vault.Mount{}, "", fmt.Errorf("listing mounts: %w", err)
}
var best vault.Mount
for _, m := range mounts {
mp := strings.TrimSuffix(m.Path, "/")
if full == mp || strings.HasPrefix(full, mp+"/") {
if len(mp) > len(strings.TrimSuffix(best.Path, "/")) {
best = m
}
}
}
if best.Path == "" {
return vault.Mount{}, "", fmt.Errorf("no configured mount matches %q", full)
}
if !best.Supported() {
return vault.Mount{}, "", fmt.Errorf("mount %q (type %s) is not supported by vault-tui", best.Path, best.Type)
}
rel := strings.TrimPrefix(full, strings.TrimSuffix(best.Path, "/"))
rel = strings.TrimPrefix(rel, "/")
return best, rel, nil
}