// Package vault wraps github.com/hashicorp/vault/api behind a small // Service that the UI and CLI layers talk to. Nothing in this package // imports a TUI toolkit, so it is fully unit-testable with httptest and // reusable by the headless commands in internal/cli. package vault import ( "fmt" "github.com/hashicorp/vault/api" "git.morlana.online/f.weber/vault-tui/internal/config" ) // NewClient builds an *api.Client from a fully resolved config.Settings. // // api.DefaultConfig() already calls ReadEnvironment(), and api.NewClient // additionally picks up VAULT_TOKEN/VAULT_NAMESPACE/VAULT_HEADERS as soon as // it sees a *api.Config — all of which would bypass the flag>env>profile> // defaults precedence that config.Resolve already computed into s. So this // function overwrites every field env may have set, then explicitly clears // the token and re-sets the namespace from s: ClearToken()+SetNamespace() // right after NewClient is the load-bearing pair of calls here. func NewClient(s *config.Settings) (*api.Client, error) { cfg := api.DefaultConfig() if cfg.Error != nil { return nil, fmt.Errorf("building base client config: %w", cfg.Error) } cfg.Address = s.Address cfg.Timeout = s.Timeout cfg.MaxRetries = s.MaxRetries if s.MinRetryWait > 0 { cfg.MinRetryWait = s.MinRetryWait } if s.MaxRetryWait > 0 { cfg.MaxRetryWait = s.MaxRetryWait } cfg.SRVLookup = s.SRVLookup cfg.DisableRedirects = s.DisableRedirects cfg.CloneHeaders = true tls := &api.TLSConfig{ CACert: s.CACert, CACertBytes: s.CACertPEM, CAPath: s.CAPath, ClientCert: s.ClientCert, ClientKey: s.ClientKey, TLSServerName: s.ServerName, Insecure: s.SkipVerify, } if err := cfg.ConfigureTLS(tls); err != nil { return nil, fmt.Errorf("configuring TLS: %w", err) } c, err := api.NewClient(cfg) if err != nil { return nil, fmt.Errorf("creating vault client: %w", err) } c.ClearToken() c.SetNamespace(s.Namespace) c.SetCloneHeaders(true) if len(s.Headers) > 0 { h := c.Headers() if h == nil { h = make(map[string][]string) } for k, v := range s.Headers { h.Set(k, v) } c.SetHeaders(h) } return c, nil }