154 lines
4.8 KiB
Go
154 lines
4.8 KiB
Go
package config
|
|
|
|
import "encoding/json"
|
|
|
|
const redactedSecret = "[REDACTED]"
|
|
|
|
// Redacted returns a detached configuration view suitable for diagnostics.
|
|
func (c *Config) Redacted() Config {
|
|
if c == nil {
|
|
return Config{}
|
|
}
|
|
redacted := cloneConfig(*c)
|
|
redactAuth(&redacted.Gateway.Auth)
|
|
redactAuth(&redacted.Distribution.Auth)
|
|
redactAuth(&redacted.Admin.Auth)
|
|
for name, upstream := range redacted.Upstreams {
|
|
redactProviderAuth(&upstream.API.Auth)
|
|
upstream.ProxyAuth.Password = redact(upstream.ProxyAuth.Password)
|
|
redacted.Upstreams[name] = upstream
|
|
}
|
|
redacted.Storage.PostgresURL = redact(redacted.Storage.PostgresURL)
|
|
redacted.Storage.RedisURL = redact(redacted.Storage.RedisURL)
|
|
return redacted
|
|
}
|
|
|
|
func (c *Config) String() string {
|
|
if c == nil {
|
|
return "<nil>"
|
|
}
|
|
encoded, err := json.Marshal(c.Redacted())
|
|
if err != nil {
|
|
return `{"config":"[REDACTED]"}`
|
|
}
|
|
return string(encoded)
|
|
}
|
|
|
|
func (c *Config) GoString() string { return c.String() }
|
|
|
|
func redactAuth(auth *Auth) {
|
|
auth.Password = redact(auth.Password)
|
|
auth.Token = redact(auth.Token)
|
|
for index := range auth.Methods {
|
|
auth.Methods[index].Password = redact(auth.Methods[index].Password)
|
|
auth.Methods[index].Value = redact(auth.Methods[index].Value)
|
|
}
|
|
}
|
|
|
|
func redactProviderAuth(auth *ProviderAuth) {
|
|
auth.Password = redact(auth.Password)
|
|
auth.Token = redact(auth.Token)
|
|
auth.Value = redact(auth.Value)
|
|
}
|
|
|
|
func redact(value string) string {
|
|
if value == "" {
|
|
return ""
|
|
}
|
|
return redactedSecret
|
|
}
|
|
|
|
func cloneConfig(source Config) Config {
|
|
cloned := source
|
|
cloned.Defaults.Check.URLs = cloneStrings(source.Defaults.Check.URLs)
|
|
cloned.Gateway = cloneListener(source.Gateway)
|
|
cloned.Distribution.Listener = cloneListener(source.Distribution.Listener)
|
|
cloned.Admin = cloneListener(source.Admin)
|
|
cloned.Routing = make([]Routing, len(source.Routing))
|
|
for index, route := range source.Routing {
|
|
cloned.Routing[index] = cloneRouting(route)
|
|
}
|
|
cloned.Upstreams = make(map[string]Upstream, len(source.Upstreams))
|
|
for name, upstream := range source.Upstreams {
|
|
cloned.Upstreams[name] = cloneUpstream(upstream)
|
|
}
|
|
return cloned
|
|
}
|
|
|
|
func cloneListener(source Listener) Listener {
|
|
cloned := source
|
|
cloned.Access.AllowCIDRs = cloneStrings(source.Access.AllowCIDRs)
|
|
cloned.Access.TrustedProxies = cloneStrings(source.Access.TrustedProxies)
|
|
cloned.Auth.CIDRs = cloneStrings(source.Auth.CIDRs)
|
|
cloned.Auth.Permissions = cloneStrings(source.Auth.Permissions)
|
|
cloned.Auth.ClientPolicy = source.Auth.ClientPolicy.Clone()
|
|
cloned.Auth.Methods = append([]AuthMethod(nil), source.Auth.Methods...)
|
|
for index := range cloned.Auth.Methods {
|
|
cloned.Auth.Methods[index].CIDRs = cloneStrings(source.Auth.Methods[index].CIDRs)
|
|
cloned.Auth.Methods[index].Permissions = cloneStrings(source.Auth.Methods[index].Permissions)
|
|
cloned.Auth.Methods[index].ClientPolicy = source.Auth.Methods[index].ClientPolicy.Clone()
|
|
}
|
|
cloned.Retry.RetryMethods = cloneStrings(source.Retry.RetryMethods)
|
|
cloned.DestinationPolicy.DenyPrivateNetworks = cloneBool(source.DestinationPolicy.DenyPrivateNetworks)
|
|
cloned.DestinationPolicy.DenyLoopback = cloneBool(source.DestinationPolicy.DenyLoopback)
|
|
cloned.DestinationPolicy.DenyLinkLocal = cloneBool(source.DestinationPolicy.DenyLinkLocal)
|
|
cloned.DestinationPolicy.DenyCIDRs = cloneStrings(source.DestinationPolicy.DenyCIDRs)
|
|
cloned.DestinationPolicy.AllowedPorts = append([]uint16(nil), source.DestinationPolicy.AllowedPorts...)
|
|
return cloned
|
|
}
|
|
|
|
func cloneBool(source *bool) *bool {
|
|
if source == nil {
|
|
return nil
|
|
}
|
|
cloned := *source
|
|
return &cloned
|
|
}
|
|
|
|
func cloneRouting(source Routing) Routing {
|
|
cloned := source
|
|
cloned.Match.Methods = cloneStrings(source.Match.Methods)
|
|
cloned.Match.Headers = cloneStringMap(source.Match.Headers)
|
|
cloned.Upstreams = cloneStrings(source.Upstreams)
|
|
cloned.Strategy.Weights = cloneIntMap(source.Strategy.Weights)
|
|
cloned.Check.Targets = cloneStrings(source.Check.Targets)
|
|
return cloned
|
|
}
|
|
|
|
func cloneUpstream(source Upstream) Upstream {
|
|
cloned := source
|
|
cloned.Exposure = cloneStrings(source.Exposure)
|
|
cloned.Provider.Protocols = cloneStrings(source.Provider.Protocols)
|
|
cloned.API.Headers = cloneStringMap(source.API.Headers)
|
|
cloned.API.Query = cloneStringMap(source.API.Query)
|
|
cloned.API.Body.Value = cloneStringMap(source.API.Body.Value)
|
|
cloned.Check.URLs = cloneStrings(source.Check.URLs)
|
|
return cloned
|
|
}
|
|
|
|
func cloneStrings(source []string) []string {
|
|
return append([]string(nil), source...)
|
|
}
|
|
|
|
func cloneStringMap(source map[string]string) map[string]string {
|
|
if source == nil {
|
|
return nil
|
|
}
|
|
cloned := make(map[string]string, len(source))
|
|
for key, value := range source {
|
|
cloned[key] = value
|
|
}
|
|
return cloned
|
|
}
|
|
|
|
func cloneIntMap(source map[string]int) map[string]int {
|
|
if source == nil {
|
|
return nil
|
|
}
|
|
cloned := make(map[string]int, len(source))
|
|
for key, value := range source {
|
|
cloned[key] = value
|
|
}
|
|
return cloned
|
|
}
|