kubernetes: sort and uniq TLS secrets
This commit is contained in:
parent
60b5286f8c
commit
a0b1d54012
2 changed files with 85 additions and 38 deletions
|
@ -9,6 +9,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
@ -179,6 +180,8 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
Frontends: map[string]*types.Frontend{},
|
Frontends: map[string]*types.Frontend{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlsConfigs := map[string]*tls.Configuration{}
|
||||||
|
|
||||||
for _, i := range ingresses {
|
for _, i := range ingresses {
|
||||||
ingressClass, err := getStringSafeValue(i.Annotations, annotationKubernetesIngressClass, "")
|
ingressClass, err := getStringSafeValue(i.Annotations, annotationKubernetesIngressClass, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -190,12 +193,10 @@ func (p *Provider) loadIngresses(k8sClient Client) (*types.Configuration, error)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsSection, err := getTLS(i, k8sClient)
|
if err = getTLS(i, k8sClient, tlsConfigs); err != nil {
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Error configuring TLS for ingress %s/%s: %v", i.Namespace, i.Name, err)
|
log.Errorf("Error configuring TLS for ingress %s/%s: %v", i.Namespace, i.Name, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
templateObjects.TLS = append(templateObjects.TLS, tlsSection...)
|
|
||||||
|
|
||||||
if i.Spec.Backend != nil {
|
if i.Spec.Backend != nil {
|
||||||
err := p.addGlobalBackend(k8sClient, i, templateObjects)
|
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)
|
log.Errorf("Cannot update Ingress %s/%s due to error: %v", i.Namespace, i.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
templateObjects.TLS = getTLSConfig(tlsConfigs)
|
||||||
|
|
||||||
return templateObjects, nil
|
return templateObjects, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,37 +640,69 @@ func getRuleForHost(host string) string {
|
||||||
return "Host:" + host
|
return "Host:" + host
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTLS(ingress *extensionsv1beta1.Ingress, k8sClient Client) ([]*tls.Configuration, error) {
|
func getTLS(ingress *extensionsv1beta1.Ingress, k8sClient Client, tlsConfigs map[string]*tls.Configuration) error {
|
||||||
var tlsConfigs []*tls.Configuration
|
|
||||||
|
|
||||||
for _, t := range ingress.Spec.TLS {
|
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)
|
secret, exists, err := k8sClient.GetSecret(ingress.Namespace, t.SecretName)
|
||||||
if err != nil {
|
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 {
|
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)
|
cert, key, err := getCertificateBlocks(secret, ingress.Namespace, t.SecretName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
entryPoints := getSliceStringValue(ingress.Annotations, annotationKubernetesFrontendEntryPoints)
|
sort.Strings(newEntryPoints)
|
||||||
|
|
||||||
tlsConfig := &tls.Configuration{
|
tlsConfig = &tls.Configuration{
|
||||||
EntryPoints: entryPoints,
|
EntryPoints: newEntryPoints,
|
||||||
Certificate: &tls.Certificate{
|
Certificate: &tls.Certificate{
|
||||||
CertFile: tls.FileOrContent(cert),
|
CertFile: tls.FileOrContent(cert),
|
||||||
KeyFile: tls.FileOrContent(key),
|
KeyFile: tls.FileOrContent(key),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
tlsConfigs[configKey] = tlsConfig
|
||||||
tlsConfigs = append(tlsConfigs, 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) {
|
func getCertificateBlocks(secret *corev1.Secret, namespace, secretName string) (string, string, error) {
|
||||||
|
|
|
@ -2830,7 +2830,7 @@ func TestGetTLS(t *testing.T) {
|
||||||
desc string
|
desc string
|
||||||
ingress *extensionsv1beta1.Ingress
|
ingress *extensionsv1beta1.Ingress
|
||||||
client Client
|
client Client
|
||||||
result []*tls.Configuration
|
result map[string]*tls.Configuration
|
||||||
errResult string
|
errResult string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
|
@ -2910,11 +2910,21 @@ func TestGetTLS(t *testing.T) {
|
||||||
),
|
),
|
||||||
iTLSes(
|
iTLSes(
|
||||||
iTLS("test-secret"),
|
iTLS("test-secret"),
|
||||||
iTLS("test-secret"),
|
iTLS("test-secret2"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
client: clientMock{
|
client: clientMock{
|
||||||
secrets: []*corev1.Secret{
|
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{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "test-secret",
|
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{
|
Certificate: &tls.Certificate{
|
||||||
CertFile: tls.FileOrContent("tls-crt"),
|
CertFile: tls.FileOrContent("tls-crt"),
|
||||||
KeyFile: tls.FileOrContent("tls-key"),
|
KeyFile: tls.FileOrContent("tls-key"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
"testing/test-secret2": {
|
||||||
Certificate: &tls.Certificate{
|
Certificate: &tls.Certificate{
|
||||||
CertFile: tls.FileOrContent("tls-crt"),
|
CertFile: tls.FileOrContent("tls-crt"),
|
||||||
KeyFile: tls.FileOrContent("tls-key"),
|
KeyFile: tls.FileOrContent("tls-key"),
|
||||||
|
@ -2964,9 +2974,9 @@ func TestGetTLS(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
result: []*tls.Configuration{
|
result: map[string]*tls.Configuration{
|
||||||
{
|
"testing/test-secret": {
|
||||||
EntryPoints: []string{"https", "api-secure"},
|
EntryPoints: []string{"api-secure", "https"},
|
||||||
Certificate: &tls.Certificate{
|
Certificate: &tls.Certificate{
|
||||||
CertFile: tls.FileOrContent("tls-crt"),
|
CertFile: tls.FileOrContent("tls-crt"),
|
||||||
KeyFile: tls.FileOrContent("tls-key"),
|
KeyFile: tls.FileOrContent("tls-key"),
|
||||||
|
@ -2981,7 +2991,8 @@ func TestGetTLS(t *testing.T) {
|
||||||
t.Run(test.desc, func(t *testing.T) {
|
t.Run(test.desc, func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tlsConfigs, err := getTLS(test.ingress, test.client)
|
tlsConfigs := map[string]*tls.Configuration{}
|
||||||
|
err := getTLS(test.ingress, test.client, tlsConfigs)
|
||||||
|
|
||||||
if test.errResult != "" {
|
if test.errResult != "" {
|
||||||
assert.EqualError(t, err, test.errResult)
|
assert.EqualError(t, err, test.errResult)
|
||||||
|
|
Loading…
Reference in a new issue