rename certificate runtime data struct

baalajimaestro: Forward port for v2.9+

Signed-off-by: baalajimaestro <me@baalajimaestro.me>
This commit is contained in:
Alessandro Chitolina 2021-10-01 08:00:17 +02:00 committed by baalajimaestro
parent 3ae0b9342b
commit 05e36e3136
Signed by: baalajimaestro
GPG key ID: F93C394FE9BBAFD5
6 changed files with 33 additions and 37 deletions

View file

@ -54,7 +54,7 @@ type OCSPConfig struct {
// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen=true
// Certificate holds a SSL cert/key pair // Certificate holds a SSL cert/key pair
// Certs and Key could be either a file path, or the file content itself. // CertificateCollection and Key could be either a file path, or the file content itself.
type Certificate struct { type Certificate struct {
CertFile FileOrContent `json:"certFile,omitempty" toml:"certFile,omitempty" yaml:"certFile,omitempty"` CertFile FileOrContent `json:"certFile,omitempty" toml:"certFile,omitempty" yaml:"certFile,omitempty"`
KeyFile FileOrContent `json:"keyFile,omitempty" toml:"keyFile,omitempty" yaml:"keyFile,omitempty" loggable:"false"` KeyFile FileOrContent `json:"keyFile,omitempty" toml:"keyFile,omitempty" yaml:"keyFile,omitempty" loggable:"false"`
@ -63,10 +63,10 @@ type Certificate struct {
} }
// Certificates defines traefik Certificates type // Certificates defines traefik Certificates type
// Certs and Keys could be either a file path, or the file content itself. // CertificateCollection and Keys could be either a file path, or the file content itself.
type Certificates []Certificate type Certificates []Certificate
// GetCertificates retrieves the Certs as slice of tls.Certificate. // GetCertificates retrieves the CertificateCollection as slice of tls.Certificate.
func (c Certificates) GetCertificates() []tls.Certificate { func (c Certificates) GetCertificates() []tls.Certificate {
var certs []tls.Certificate var certs []tls.Certificate

View file

@ -13,26 +13,22 @@ import (
"time" "time"
"github.com/traefik/traefik/v2/pkg/log" "github.com/traefik/traefik/v2/pkg/log"
"github.com/traefik/traefik/v2/pkg/tls/generate"
"golang.org/x/crypto/ocsp" "golang.org/x/crypto/ocsp"
) )
// Cert holds runtime data for runtime TLS certificate handling. // CertificateData holds runtime data for runtime TLS certificate handling.
type Cert struct { type CertificateData struct {
config *Certificate config *Certificate
Certificate *tls.Certificate Certificate *tls.Certificate
OCSPServer []string OCSPServer []string
OCSPResponse *ocsp.Response OCSPResponse *ocsp.Response
} }
// Certs defines traefik Certs type // CertificateCollection defines traefik CertificateCollection type.
// Certs and Keys could be either a file path, or the file content itself. type CertificateCollection []CertificateData
type Certs []Cert
// CreateTLSConfig creates a TLS config from Certificate structures. // AppendCertificate appends a CertificateData to a certificates map keyed by entrypoint.
func (c *CertificateData) AppendCertificate(certs map[string]map[string]*CertificateData, storeName string) error {
// AppendCertificate appends a Cert to a certificates map keyed by entrypoint.
func (c *Cert) AppendCertificate(certs map[string]map[string]*Cert, storeName string) error {
certContent, err := c.config.CertFile.Read() certContent, err := c.config.CertFile.Read()
if err != nil { if err != nil {
return fmt.Errorf("unable to read CertFile : %w", err) return fmt.Errorf("unable to read CertFile : %w", err)
@ -72,7 +68,7 @@ func (c *Cert) AppendCertificate(certs map[string]map[string]*Cert, storeName st
certExists := false certExists := false
if certs[storeName] == nil { if certs[storeName] == nil {
certs[storeName] = make(map[string]*Cert) certs[storeName] = make(map[string]*CertificateData)
} else { } else {
for domains := range certs[storeName] { for domains := range certs[storeName] {
if domains == certKey { if domains == certKey {
@ -87,7 +83,7 @@ func (c *Cert) AppendCertificate(certs map[string]map[string]*Cert, storeName st
} else { } else {
log.Debugf("Adding certificate for domain(s) %s", certKey) log.Debugf("Adding certificate for domain(s) %s", certKey)
certs[storeName][certKey] = &Cert{ certs[storeName][certKey] = &CertificateData{
Certificate: &tlsCert, Certificate: &tlsCert,
OCSPServer: parsedCert.OCSPServer, OCSPServer: parsedCert.OCSPServer,
config: &Certificate{ config: &Certificate{
@ -102,7 +98,7 @@ func (c *Cert) AppendCertificate(certs map[string]map[string]*Cert, storeName st
return err return err
} }
func getOCSPForCert(certificate *Cert, issuedCertificate *x509.Certificate, issuerCertificate *x509.Certificate) ([]byte, *ocsp.Response, error) { func getOCSPForCert(certificate *CertificateData, issuedCertificate *x509.Certificate, issuerCertificate *x509.Certificate) ([]byte, *ocsp.Response, error) {
if len(certificate.OCSPServer) == 0 { if len(certificate.OCSPServer) == 0 {
return nil, nil, fmt.Errorf("no OCSP server specified in certificate") return nil, nil, fmt.Errorf("no OCSP server specified in certificate")
} }
@ -134,7 +130,7 @@ func getOCSPForCert(certificate *Cert, issuedCertificate *x509.Certificate, issu
} }
// StapleOCSP populates the ocsp response of the certificate if needed and not disabled by configuration. // StapleOCSP populates the ocsp response of the certificate if needed and not disabled by configuration.
func (c *Cert) StapleOCSP() error { func (c *CertificateData) StapleOCSP() error {
if c.config.OCSP.DisableStapling { if c.config.OCSP.DisableStapling {
return nil return nil
} }
@ -177,7 +173,7 @@ func (c *Cert) StapleOCSP() error {
// String is the method to format the flag's value, part of the flag.Value interface. // String is the method to format the flag's value, part of the flag.Value interface.
// The String method's output will be used in diagnostics. // The String method's output will be used in diagnostics.
func (c *Certs) String() string { func (c *CertificateCollection) String() string {
if len(*c) == 0 { if len(*c) == 0 {
return "" return ""
} }
@ -191,14 +187,14 @@ func (c *Certs) String() string {
// Set is the method to set the flag value, part of the flag.Value interface. // Set is the method to set the flag value, part of the flag.Value interface.
// Set's argument is a string to be parsed to set the flag. // Set's argument is a string to be parsed to set the flag.
// It's a comma-separated list, so we split it. // It's a comma-separated list, so we split it.
func (c *Certs) Set(value string) error { func (c *CertificateCollection) Set(value string) error {
TLSCertificates := strings.Split(value, ";") TLSCertificates := strings.Split(value, ";")
for _, certificate := range TLSCertificates { for _, certificate := range TLSCertificates {
files := strings.Split(certificate, ",") files := strings.Split(certificate, ",")
if len(files) != 2 { if len(files) != 2 {
return fmt.Errorf("bad Certs format: %s", value) return fmt.Errorf("bad CertificateCollection format: %s", value)
} }
*c = append(*c, Cert{ *c = append(*c, CertificateData{
config: &Certificate{ config: &Certificate{
CertFile: FileOrContent(files[0]), CertFile: FileOrContent(files[0]),
KeyFile: FileOrContent(files[1]), KeyFile: FileOrContent(files[1]),
@ -212,6 +208,6 @@ func (c *Certs) Set(value string) error {
} }
// Type is type of the struct. // Type is type of the struct.
func (c *Certs) Type() string { func (c *CertificateCollection) Type() string {
return "Certs" return "CertificateCollection"
} }

View file

@ -63,7 +63,7 @@ func (c CertificateStore) GetAllDomains() []string {
// Get dynamic certificates // Get dynamic certificates
if c.DynamicCerts != nil && c.DynamicCerts.Get() != nil { if c.DynamicCerts != nil && c.DynamicCerts.Get() != nil {
for domain := range c.DynamicCerts.Get().(map[string]*Cert) { for domain := range c.DynamicCerts.Get().(map[string]*CertificateData) {
allDomains = append(allDomains, domain) allDomains = append(allDomains, domain)
} }
} }
@ -72,7 +72,7 @@ func (c CertificateStore) GetAllDomains() []string {
} }
// GetBestCertificate returns the best match certificate, and caches the response. // GetBestCertificate returns the best match certificate, and caches the response.
func (c *CertificateStore) GetBestCertificate(clientHello *tls.ClientHelloInfo) *Cert { func (c *CertificateStore) GetBestCertificate(clientHello *tls.ClientHelloInfo) *CertificateData {
if c == nil { if c == nil {
return nil return nil
} }
@ -87,12 +87,12 @@ func (c *CertificateStore) GetBestCertificate(clientHello *tls.ClientHelloInfo)
} }
if cert, ok := c.CertCache.Get(serverName); ok { if cert, ok := c.CertCache.Get(serverName); ok {
return cert.(*Cert) return cert.(*CertificateData)
} }
matchedCerts := map[string]*Cert{} matchedCerts := map[string]*CertificateData{}
if c.DynamicCerts != nil && c.DynamicCerts.Get() != nil { if c.DynamicCerts != nil && c.DynamicCerts.Get() != nil {
for domains, cert := range c.DynamicCerts.Get().(map[string]*Cert) { for domains, cert := range c.DynamicCerts.Get().(map[string]*CertificateData) {
for _, certDomain := range strings.Split(domains, ",") { for _, certDomain := range strings.Split(domains, ",") {
if matchDomain(serverName, certDomain) { if matchDomain(serverName, certDomain) {
matchedCerts[certDomain] = cert matchedCerts[certDomain] = cert

View file

@ -59,7 +59,7 @@ func TestGetBestCertificate(t *testing.T) {
test := test test := test
t.Run(test.desc, func(t *testing.T) { t.Run(test.desc, func(t *testing.T) {
t.Parallel() t.Parallel()
dynamicMap := map[string]*Cert{} dynamicMap := map[string]*CertificateData{}
if test.dynamicCert != "" { if test.dynamicCert != "" {
cert, err := loadTestCert(test.dynamicCert, test.uppercase) cert, err := loadTestCert(test.dynamicCert, test.uppercase)
@ -72,7 +72,7 @@ func TestGetBestCertificate(t *testing.T) {
CertCache: cache.New(1*time.Hour, 10*time.Minute), CertCache: cache.New(1*time.Hour, 10*time.Minute),
} }
var expected *Cert var expected *CertificateData
if test.expectedCert != "" { if test.expectedCert != "" {
cert, err := loadTestCert(test.expectedCert, test.uppercase) cert, err := loadTestCert(test.expectedCert, test.uppercase)
require.NoError(t, err) require.NoError(t, err)
@ -89,7 +89,7 @@ func TestGetBestCertificate(t *testing.T) {
} }
} }
func loadTestCert(certName string, uppercase bool) (*Cert, error) { func loadTestCert(certName string, uppercase bool) (*CertificateData, error) {
replacement := "wildcard" replacement := "wildcard"
if uppercase { if uppercase {
replacement = "uppercase_wildcard" replacement = "uppercase_wildcard"
@ -103,7 +103,7 @@ func loadTestCert(certName string, uppercase bool) (*Cert, error) {
return nil, err return nil, err
} }
return &Cert{ return &CertificateData{
Certificate: &staticCert, Certificate: &staticCert,
}, nil }, nil
} }

View file

@ -83,7 +83,7 @@ func (m *Manager) UpdateConfigs(ctx context.Context, stores map[string]Store, co
m.storesConfig[tlsalpn01.ACMETLS1Protocol] = Store{} m.storesConfig[tlsalpn01.ACMETLS1Protocol] = Store{}
} }
storesCertificates := make(map[string]map[string]*Cert) storesCertificates := make(map[string]map[string]*CertificateData)
for _, conf := range certs { for _, conf := range certs {
if len(conf.Stores) == 0 { if len(conf.Stores) == 0 {
if log.GetLevel() >= logrus.DebugLevel { if log.GetLevel() >= logrus.DebugLevel {
@ -100,7 +100,7 @@ func (m *Manager) UpdateConfigs(ctx context.Context, stores map[string]Store, co
m.storesConfig[store] = Store{} m.storesConfig[store] = Store{}
} }
cert := Cert{config: &conf.Certificate} cert := CertificateData{config: &conf.Certificate}
err := cert.AppendCertificate(storesCertificates, store) err := cert.AppendCertificate(storesCertificates, store)
if err != nil { if err != nil {
log.FromContext(ctxStore).Errorf("Unable to append certificate %s to store: %v", conf.Certificate.GetTruncatedCertificateName(), err) log.FromContext(ctxStore).Errorf("Unable to append certificate %s to store: %v", conf.Certificate.GetTruncatedCertificateName(), err)
@ -242,7 +242,7 @@ func (m *Manager) GetCertificates() []*x509.Certificate {
// We iterate over all the certificates. // We iterate over all the certificates.
for _, store := range m.stores { for _, store := range m.stores {
if store.DynamicCerts != nil && store.DynamicCerts.Get() != nil { if store.DynamicCerts != nil && store.DynamicCerts.Get() != nil {
for _, cert := range store.DynamicCerts.Get().(map[string]*Cert) { for _, cert := range store.DynamicCerts.Get().(map[string]*CertificateData) {
x509Cert, err := x509.ParseCertificate(cert.Certificate.Certificate[0]) x509Cert, err := x509.ParseCertificate(cert.Certificate.Certificate[0])
if err != nil { if err != nil {
continue continue

View file

@ -79,7 +79,7 @@ func TestTLSInStore(t *testing.T) {
tlsManager := NewManager() tlsManager := NewManager()
tlsManager.UpdateConfigs(context.Background(), nil, nil, dynamicConfigs) tlsManager.UpdateConfigs(context.Background(), nil, nil, dynamicConfigs)
certs := tlsManager.GetStore("default").DynamicCerts.Get().(map[string]*Cert) certs := tlsManager.GetStore("default").DynamicCerts.Get().(map[string]*CertificateData)
if len(certs) == 0 { if len(certs) == 0 {
t.Fatal("got error: default store must have TLS certificates.") t.Fatal("got error: default store must have TLS certificates.")
} }
@ -104,7 +104,7 @@ func TestTLSInvalidStore(t *testing.T) {
}, },
}, nil, dynamicConfigs) }, nil, dynamicConfigs)
certs := tlsManager.GetStore("default").DynamicCerts.Get().(map[string]*Cert) certs := tlsManager.GetStore("default").DynamicCerts.Get().(map[string]*CertificateData)
if len(certs) == 0 { if len(certs) == 0 {
t.Fatal("got error: default store must have TLS certificates.") t.Fatal("got error: default store must have TLS certificates.")
} }