kubernetes: sort and uniq TLS secrets

This commit is contained in:
zarqman 2018-12-20 12:08:03 -07:00 committed by Traefiker Bot
parent 60b5286f8c
commit a0b1d54012
2 changed files with 85 additions and 38 deletions

View file

@ -9,6 +9,7 @@ import (
"net"
"os"
"reflect"
"sort"
"strconv"
"strings"
"text/template"
@ -179,6 +180,8 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
Frontends: map[string]*types.Frontend{},
}
tlsConfigs := map[string]*tls.Configuration{}
for _, i := range ingresses {
ingressClass, err := getStringSafeValue(i.Annotations, annotationKubernetesIngressClass, "")
if err != nil {
@ -190,12 +193,10 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
continue
}
tlsSection, err := getTLS(i, k8sClient)
if err != nil {
if err = getTLS(i, k8sClient, tlsConfigs); err != nil {
log.Errorf("Error configuring TLS for ingress %s/%s: %v", i.Namespace, i.Name, err)
continue
}
templateObjects.TLS = append(templateObjects.TLS, tlsSection...)
if i.Spec.Backend != nil {
err := p.addGlobalBackend(k8sClient, i, templateObjects)
@ -416,6 +417,9 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
log.Errorf("Cannot update Ingress %s/%s due to error: %v", i.Namespace, i.Name, err)
}
}
templateObjects.TLS = getTLSConfig(tlsConfigs)
return templateObjects, nil
}
@ -636,37 +640,69 @@ func getRuleForHost(host string) string {
return "Host:" + host
}
func getTLS(ingress *extensionsv1beta1.Ingress, k8sClient Client) ([]*tls.Configuration, error) {
var tlsConfigs []*tls.Configuration
func getTLS(ingress *extensionsv1beta1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error {
for _, t := range ingress.Spec.TLS {
newEntryPoints := getSliceStringValue(ingress.Annotations, annotationKubernetesFrontendEntryPoints)
configKey := ingress.Namespace + "/" + t.SecretName
if tlsConfig, tlsExists := tlsConfigs[configKey]; tlsExists {
for _, entryPoint := range newEntryPoints {
tlsConfig.EntryPoints = mergeEntryPoint(tlsConfig.EntryPoints, entryPoint)
}
} else {
secret, exists, err := k8sClient.GetSecret(ingress.Namespace, t.SecretName)
if err != nil {
return nil, fmt.Errorf("failed to fetch secret %s/%s: %v", ingress.Namespace, t.SecretName, err)
return fmt.Errorf("failed to fetch secret %s/%s: %v", ingress.Namespace, t.SecretName, err)
}
if !exists {
return nil, fmt.Errorf("secret %s/%s does not exist", ingress.Namespace, t.SecretName)
return fmt.Errorf("secret %s/%s does not exist", ingress.Namespace, t.SecretName)
}
cert, key, err := getCertificateBlocks(secret, ingress.Namespace, t.SecretName)
if err != nil {
return nil, err
return err
}
entryPoints := getSliceStringValue(ingress.Annotations, annotationKubernetesFrontendEntryPoints)
sort.Strings(newEntryPoints)
tlsConfig := &tls.Configuration{
EntryPoints: entryPoints,
tlsConfig = &tls.Configuration{
EntryPoints: newEntryPoints,
Certificate: &tls.Certificate{
CertFile: tls.FileOrContent(cert),
KeyFile: tls.FileOrContent(key),
},
}
tlsConfigs = append(tlsConfigs, tlsConfig)
tlsConfigs[configKey] = tlsConfig
}
}
return tlsConfigs, nil
return nil
}
func getTLSConfig(tlsConfigs map[string]*tls.Configuration) []*tls.Configuration {
var secretNames []string
for secretName := range tlsConfigs {
secretNames = append(secretNames, secretName)
}
sort.Strings(secretNames)
var configs []*tls.Configuration
for _, secretName := range secretNames {
configs = append(configs, tlsConfigs[secretName])
}
return configs
}
func mergeEntryPoint(entryPoints []string, newEntryPoint string) []string {
for _, ep := range entryPoints {
if ep == newEntryPoint {
return entryPoints
}
}
entryPoints = append(entryPoints, newEntryPoint)
sort.Strings(entryPoints)
return entryPoints
}
func getCertificateBlocks(secret *corev1.Secret, namespace, secretName string) (string, string, error) {

View file

@ -2830,7 +2830,7 @@ func TestGetTLS(t *testing.T) {
desc string
ingress *extensionsv1beta1.Ingress
client Client
result []*tls.Configuration
result map[string]*tls.Configuration
errResult string
}{
{
@ -2910,11 +2910,21 @@ func TestGetTLS(t *testing.T) {
),
iTLSes(
iTLS("test-secret"),
iTLS("test-secret"),
iTLS("test-secret2"),
),
),
client: clientMock{
secrets: []*corev1.Secret{
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret2",
Namespace: "testing",
},
Data: map[string][]byte{
"tls.crt": []byte("tls-crt"),
"tls.key": []byte("tls-key"),
},
},
{
ObjectMeta: metav1.ObjectMeta{
Name: "test-secret",
@ -2927,14 +2937,14 @@ func TestGetTLS(t *testing.T) {
},
},
},
result: []*tls.Configuration{
{
result: map[string]*tls.Configuration{
"testing/test-secret": {
Certificate: &tls.Certificate{
CertFile: tls.FileOrContent("tls-crt"),
KeyFile: tls.FileOrContent("tls-key"),
},
},
{
"testing/test-secret2": {
Certificate: &tls.Certificate{
CertFile: tls.FileOrContent("tls-crt"),
KeyFile: tls.FileOrContent("tls-key"),
@ -2964,9 +2974,9 @@ func TestGetTLS(t *testing.T) {
},
},
},
result: []*tls.Configuration{
{
EntryPoints: []string{"https", "api-secure"},
result: map[string]*tls.Configuration{
"testing/test-secret": {
EntryPoints: []string{"api-secure", "https"},
Certificate: &tls.Certificate{
CertFile: tls.FileOrContent("tls-crt"),
KeyFile: tls.FileOrContent("tls-key"),
@ -2981,7 +2991,8 @@ func TestGetTLS(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
tlsConfigs, err := getTLS(test.ingress, test.client)
tlsConfigs := map[string]*tls.Configuration{}
err := getTLS(test.ingress, test.client, tlsConfigs)
if test.errResult != "" {
assert.EqualError(t, err, test.errResult)