This commit is contained in:
Kuritka 2026-01-29 17:30:21 +01:00 committed by GitHub
commit 4e4343ac58
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 112 additions and 64 deletions

View file

@ -2,6 +2,7 @@ package dynamic
import (
"github.com/traefik/traefik/v3/pkg/tls"
"github.com/traefik/traefik/v3/pkg/types"
)
// +k8s:deepcopy-gen=true
@ -35,3 +36,103 @@ type TLSConfiguration struct {
Options map[string]tls.Options `json:"options,omitempty" toml:"options,omitempty" yaml:"options,omitempty" label:"-" export:"true"`
Stores map[string]tls.Store `json:"stores,omitempty" toml:"stores,omitempty" yaml:"stores,omitempty" export:"true"`
}
func (c *Configuration) IsEmpty() bool {
if c.TCP == nil {
c.TCP = &TCPConfiguration{}
}
if c.HTTP == nil {
c.HTTP = &HTTPConfiguration{}
}
if c.UDP == nil {
c.UDP = &UDPConfiguration{}
}
httpEmpty := c.HTTP.Routers == nil && c.HTTP.Services == nil && c.HTTP.Middlewares == nil
tlsEmpty := c.TLS == nil || c.TLS.Certificates == nil && c.TLS.Stores == nil && c.TLS.Options == nil
tcpEmpty := c.TCP.Routers == nil && c.TCP.Services == nil && c.TCP.Middlewares == nil
udpEmpty := c.UDP.Routers == nil && c.UDP.Services == nil
return httpEmpty && tlsEmpty && tcpEmpty && udpEmpty
}
func (c *Configuration) GetSanitizedConfigurationTLS() *Configuration {
copyConf := c.DeepCopy()
if copyConf.TLS != nil {
copyConf.TLS.Certificates = nil
if copyConf.TLS.Options != nil {
cleanedOptions := make(map[string]tls.Options, len(copyConf.TLS.Options))
for name, option := range copyConf.TLS.Options {
option.ClientAuth.CAFiles = []types.FileOrContent{}
cleanedOptions[name] = option
}
copyConf.TLS.Options = cleanedOptions
}
for k := range copyConf.TLS.Stores {
st := copyConf.TLS.Stores[k]
st.DefaultCertificate = nil
copyConf.TLS.Stores[k] = st
}
}
if copyConf.HTTP != nil {
for _, transport := range copyConf.HTTP.ServersTransports {
transport.Certificates = tls.Certificates{}
transport.RootCAs = []types.FileOrContent{}
}
}
if copyConf.TCP != nil {
for _, transport := range copyConf.TCP.ServersTransports {
if transport.TLS != nil {
transport.TLS.Certificates = tls.Certificates{}
transport.TLS.RootCAs = []types.FileOrContent{}
}
}
}
return copyConf
}
func (c *Configuration) SummaryTLS() map[string]any {
if c.TLS == nil {
return nil
}
stores := make([]string, 0, len(c.TLS.Stores))
defaultCerts := 0
for name, st := range c.TLS.Stores {
stores = append(stores, name)
if st.DefaultCertificate != nil {
defaultCerts++
}
}
caFiles := 0
if c.TLS.Options != nil {
for _, opt := range c.TLS.Options {
caFiles += len(opt.ClientAuth.CAFiles)
}
}
return map[string]any{
"certificates": map[string]any{
"present": len(c.TLS.Certificates) > 0,
"count": len(c.TLS.Certificates),
"value": "<redacted>",
},
"stores": map[string]any{
"names": stores,
"default_cert_count": defaultCerts,
"default_cert": "<redacted>",
},
"clientAuth": map[string]any{
"ca_files_total": caFiles,
"ca_files": "<redacted>",
},
}
}

View file

@ -11,8 +11,6 @@ import (
"github.com/traefik/traefik/v3/pkg/observability/logs"
"github.com/traefik/traefik/v3/pkg/provider"
"github.com/traefik/traefik/v3/pkg/safe"
"github.com/traefik/traefik/v3/pkg/tls"
"github.com/traefik/traefik/v3/pkg/types"
)
// ConfigurationWatcher watches configuration changes.
@ -121,7 +119,7 @@ func (c *ConfigurationWatcher) receiveConfigurations(ctx context.Context) {
continue
}
if isEmptyConfiguration(configMsg.Configuration) {
if configMsg.Configuration.IsEmpty() {
logger.Debug().Msg("Skipping empty configuration")
continue
}
@ -190,68 +188,17 @@ func logConfiguration(logger zerolog.Logger, configMsg dynamic.Message) {
if logger.GetLevel() > zerolog.DebugLevel {
return
}
copyConf := configMsg.Configuration.DeepCopy()
if copyConf.TLS != nil {
copyConf.TLS.Certificates = nil
if copyConf.TLS.Options != nil {
cleanedOptions := make(map[string]tls.Options, len(copyConf.TLS.Options))
for name, option := range copyConf.TLS.Options {
option.ClientAuth.CAFiles = []types.FileOrContent{}
cleanedOptions[name] = option
}
copyConf.TLS.Options = cleanedOptions
}
for k := range copyConf.TLS.Stores {
st := copyConf.TLS.Stores[k]
st.DefaultCertificate = nil
copyConf.TLS.Stores[k] = st
}
}
if copyConf.HTTP != nil {
for _, transport := range copyConf.HTTP.ServersTransports {
transport.Certificates = tls.Certificates{}
transport.RootCAs = []types.FileOrContent{}
}
}
if copyConf.TCP != nil {
for _, transport := range copyConf.TCP.ServersTransports {
if transport.TLS != nil {
transport.TLS.Certificates = tls.Certificates{}
transport.TLS.RootCAs = []types.FileOrContent{}
}
}
}
jsonConf, err := json.Marshal(copyConf)
sanitizedConfiguration := configMsg.Configuration.GetSanitizedConfigurationTLS()
summary := configMsg.Configuration.SummaryTLS()
jsonConf, err := json.Marshal(sanitizedConfiguration)
if err != nil {
logger.Error().Err(err).Msg("Could not marshal dynamic configuration")
logger.Debug().Msgf("Configuration received: [struct] %#v", copyConf)
} else {
logger.Debug().RawJSON("config", jsonConf).Msg("Configuration received")
logger.Debug().Msgf("Configuration received: [struct] %#v", sanitizedConfiguration)
return
}
}
func isEmptyConfiguration(conf *dynamic.Configuration) bool {
if conf.TCP == nil {
conf.TCP = &dynamic.TCPConfiguration{}
}
if conf.HTTP == nil {
conf.HTTP = &dynamic.HTTPConfiguration{}
}
if conf.UDP == nil {
conf.UDP = &dynamic.UDPConfiguration{}
}
httpEmpty := conf.HTTP.Routers == nil && conf.HTTP.Services == nil && conf.HTTP.Middlewares == nil
tlsEmpty := conf.TLS == nil || conf.TLS.Certificates == nil && conf.TLS.Stores == nil && conf.TLS.Options == nil
tcpEmpty := conf.TCP.Routers == nil && conf.TCP.Services == nil && conf.TCP.Middlewares == nil
udpEmpty := conf.UDP.Routers == nil && conf.UDP.Services == nil
return httpEmpty && tlsEmpty && tcpEmpty && udpEmpty
evt := logger.Debug().RawJSON("config", jsonConf)
if summary != nil {
evt = evt.Any("tls_summary", summary)
}
evt.Msg("Configuration received (TLS redacted)")
}