diff --git a/internal/gatewayapi/backendtlspolicy.go b/internal/gatewayapi/backendtlspolicy.go index 8cce36d0fd..1066485279 100644 --- a/internal/gatewayapi/backendtlspolicy.go +++ b/internal/gatewayapi/backendtlspolicy.go @@ -291,7 +291,7 @@ func getCaCertsFromCARefs(namespace string, caCertificates []gwapiv1.LocalObject case resource.KindConfigMap: cm := resources.GetConfigMap(namespace, string(caRef.Name)) if cm != nil { - if crt, dataOk := cm.Data[caCertKey]; dataOk { + if crt, dataOk := getCaCertFromConfigMap(cm); dataOk { if ca != "" { ca += "\n" } @@ -305,7 +305,7 @@ func getCaCertsFromCARefs(namespace string, caCertificates []gwapiv1.LocalObject case resource.KindSecret: secret := resources.GetSecret(namespace, string(caRef.Name)) if secret != nil { - if crt, dataOk := secret.Data[caCertKey]; dataOk { + if crt, dataOk := getCaCertFromSecret(secret); dataOk { if ca != "" { ca += "\n" } diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go index 843109838f..894afbcbe3 100644 --- a/internal/gatewayapi/clienttrafficpolicy.go +++ b/internal/gatewayapi/clienttrafficpolicy.go @@ -834,7 +834,7 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli return irTLSConfig, err } - secretBytes, ok := secret.Data[caCertKey] + secretBytes, ok := getCaCertFromSecret(secret) if !ok || len(secretBytes) == 0 { return irTLSConfig, fmt.Errorf( "caCertificateRef not found in secret %s", caCertRef.Name) @@ -853,7 +853,7 @@ func (t *Translator) buildListenerTLSParameters(policy *egv1a1.ClientTrafficPoli return irTLSConfig, err } - configMapBytes, ok := configMap.Data[caCertKey] + configMapBytes, ok := getCaCertFromConfigMap(configMap) if !ok || len(configMapBytes) == 0 { return irTLSConfig, fmt.Errorf( "caCertificateRef not found in configMap %s", caCertRef.Name) diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 44c177b73f..8e8e4dae04 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -674,3 +674,37 @@ func getPreserveRouteOrder(envoyProxy *egv1a1.EnvoyProxy) bool { } return false } + +func getCaCertFromConfigMap(cm *corev1.ConfigMap) (string, bool) { + var data string + data, exits := cm.Data[caCertKey] + switch { + case exits: + return data, true + case len(cm.Data) == 1: // Fallback to the first key if ca.crt is not found + for _, value := range cm.Data { + data = value + break + } + return data, true + default: + return "", false + } +} + +func getCaCertFromSecret(s *corev1.Secret) ([]byte, bool) { + var data []byte + data, exits := s.Data[caCertKey] + switch { + case exits: + return data, true + case len(s.Data) == 1: // Fallback to the first key if ca.crt is not found + for _, value := range s.Data { + data = value + break + } + return data, true + default: + return nil, false + } +} diff --git a/internal/gatewayapi/helpers_test.go b/internal/gatewayapi/helpers_test.go index 22bcafd2c9..f39bacf83d 100644 --- a/internal/gatewayapi/helpers_test.go +++ b/internal/gatewayapi/helpers_test.go @@ -717,3 +717,95 @@ func TestGetServiceIPFamily(t *testing.T) { }) } } + +func TestGetCaCertFromConfigMap(t *testing.T) { + cases := []struct { + name string + cm *corev1.ConfigMap + expectedFound bool + expected string + }{ + { + name: "get from ca.crt", + cm: &corev1.ConfigMap{ + Data: map[string]string{ + "ca.crt": "fake-cert", + "root-cert.pem": "fake-root", + }, + }, + expectedFound: true, + expected: "fake-cert", + }, + { + name: "get from first key", + cm: &corev1.ConfigMap{ + Data: map[string]string{ + "root-cert.pem": "fake-root", + }, + }, + expectedFound: true, + expected: "fake-root", + }, + { + name: "not found", + cm: &corev1.ConfigMap{ + Data: map[string]string{}, + }, + expectedFound: false, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + got, found := getCaCertFromConfigMap(tc.cm) + require.Equal(t, tc.expectedFound, found) + require.Equal(t, tc.expected, got) + }) + } +} + +func TestGetCaCertFromSecret(t *testing.T) { + cases := []struct { + name string + s *corev1.Secret + expectedFound bool + expected string + }{ + { + name: "get from ca.crt", + s: &corev1.Secret{ + Data: map[string][]byte{ + "ca.crt": []byte("fake-cert"), + "root-cert.pem": []byte("fake-root"), + }, + }, + expectedFound: true, + expected: "fake-cert", + }, + { + name: "get from first key", + s: &corev1.Secret{ + Data: map[string][]byte{ + "root-cert.pem": []byte("fake-root"), + }, + }, + expectedFound: true, + expected: "fake-root", + }, + { + name: "not found", + s: &corev1.Secret{ + Data: map[string][]byte{}, + }, + expectedFound: false, + }, + } + + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + got, found := getCaCertFromSecret(tc.s) + require.Equal(t, tc.expectedFound, found) + require.Equal(t, tc.expected, string(got)) + }) + } +} diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml index a5484a2035..9352e1a47e 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.in.yaml @@ -84,16 +84,6 @@ endpointSlices: - "10.244.0.11" conditions: ready: true - -configMaps: - - apiVersion: v1 - kind: ConfigMap - metadata: - name: no-ca-cmap - namespace: backends - data: - garbage.crt: | - itsAllGarbage backendTLSPolicies: - apiVersion: gateway.networking.k8s.io/v1alpha2 kind: BackendTLSPolicy diff --git a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml index 105cc38542..e5abcf72b2 100644 --- a/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml +++ b/internal/gatewayapi/testdata/backendtlspolicy-invalid-ca.out.yaml @@ -25,7 +25,7 @@ backendTLSPolicies: sectionName: http conditions: - lastTransitionTime: null - message: No ca found in configmap no-ca-cmap. + message: Configmap no-ca-cmap not found in namespace backends. reason: Invalid status: "False" type: Accepted @@ -101,8 +101,8 @@ httpRoutes: status: "True" type: Accepted - lastTransitionTime: null - message: 'Failed to process route rule 0 backendRef 0: no ca found in configmap - no-ca-cmap.' + message: 'Failed to process route rule 0 backendRef 0: configmap no-ca-cmap + not found in namespace backends.' reason: InvalidBackendTLS status: "False" type: ResolvedRefs diff --git a/release-notes/current.yaml b/release-notes/current.yaml index a1776f50b0..df7b4c7604 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -24,6 +24,7 @@ new features: | Added support for configuring cluster stat name for HTTPRoute and GRPCRoute in EnvoyProxy CRD. Added support for configuring `SameSite` attribute for Oauth cookies for OIDC authentication. Added support for configuring the cache sync period for K8s provider. + Added support for fallback to first key when load ca certificate from Secret or ConfigMap. Added support for configuring user provided name to generated HorizontalPodAutoscaler and PodDisruptionBudget resources.