diff --git a/pkg/config/dynamic/config.go b/pkg/config/dynamic/config.go index 1e125ad78..33a1798a6 100644 --- a/pkg/config/dynamic/config.go +++ b/pkg/config/dynamic/config.go @@ -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": "", + }, + "stores": map[string]any{ + "names": stores, + "default_cert_count": defaultCerts, + "default_cert": "", + }, + "clientAuth": map[string]any{ + "ca_files_total": caFiles, + "ca_files": "", + }, + } +} diff --git a/pkg/server/configurationwatcher.go b/pkg/server/configurationwatcher.go index 747f476f6..76f16fff2 100644 --- a/pkg/server/configurationwatcher.go +++ b/pkg/server/configurationwatcher.go @@ -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)") }