VAULT-33758: IPv6 address conformance for proxy and agent (#29517)

This is a follow-up to our initial work[0] to address RFC-5952 §4 conformance for IPv6 addresses in Vault. The initial pass focused on the vault server configuration and start-up routines. This follow-up focuses on Agent and Proxy, with a few minor improvements for server.

The approach generally mirrors the server implementation but also adds support for normalization with CLI configuration overrides.

One aspect we do not normalize currently is Agent/Proxy client creation to the Vault server with credentials taken from environment variables, as it would require larger changes to the `api` module. In practice this ought to be fine for the majority of cases.

[0]: https://github.com/hashicorp/vault/pull/29228
This commit is contained in:
Ryan Cragun
2025-02-27 15:57:46 -07:00
committed by GitHub
parent 69646127df
commit 58a49e6ce0
32 changed files with 1474 additions and 315 deletions

View File

@@ -460,56 +460,89 @@ func (i *uint64Value) Hidden() bool { return i.hidden }
// -- StringVar and stringValue
type StringVar struct {
Name string
Aliases []string
Usage string
Default string
Hidden bool
EnvVar string
Target *string
Completion complete.Predictor
Name string
Aliases []string
Usage string
Default string
Hidden bool
EnvVar string
Target *string
Normalizers []func(string) string
Completion complete.Predictor
}
func (s *StringVar) SetTarget(val string) {
if s == nil {
return
}
for _, f := range s.Normalizers {
val = f(val)
}
*s.Target = val
}
func (f *FlagSet) StringVar(i *StringVar) {
initial := i.Default
if v, exist := os.LookupEnv(i.EnvVar); exist {
initial = v
if i == nil {
return
}
def := ""
if i.Default != "" {
def = i.Default
val := i.Default
envVar, ok := os.LookupEnv(i.EnvVar)
if ok {
val = envVar
}
f.VarFlag(&VarFlag{
Name: i.Name,
Aliases: i.Aliases,
Usage: i.Usage,
Default: def,
Default: i.Default,
EnvVar: i.EnvVar,
Value: newStringValue(initial, i.Target, i.Hidden),
Value: newStringValue(val, i.Target, i.Hidden, i.Normalizers),
Completion: i.Completion,
})
}
type stringValue struct {
hidden bool
target *string
hidden bool
target *string
normalizers []func(string) string
}
func newStringValue(def string, target *string, hidden bool) *stringValue {
*target = def
return &stringValue{
hidden: hidden,
target: target,
func newStringValue(val string, target *string, hidden bool, normalizers []func(string) string) *stringValue {
sv := &stringValue{
hidden: hidden,
target: target,
normalizers: append(normalizers, strings.TrimSpace),
}
sv.set(val)
return sv
}
func (s *stringValue) Set(val string) error {
*s.target = val
s.set(val)
return nil
}
func (s *stringValue) set(val string) {
*s.target = s.normalize(val)
}
func (s *stringValue) normalize(in string) string {
if s == nil || len(s.normalizers) < 1 {
return in
}
for _, f := range s.normalizers {
in = f(in)
}
return in
}
func (s *stringValue) Get() interface{} { return *s.target }
func (s *stringValue) String() string { return *s.target }
func (s *stringValue) Example() string { return "string" }