diff --git a/pkg/state/ingressstate.go b/pkg/state/ingressstate.go index ea67f69b..4a48f7d3 100644 --- a/pkg/state/ingressstate.go +++ b/pkg/state/ingressstate.go @@ -150,7 +150,7 @@ func (s *StateStore) BuildState(ingressClass *networkingv1.IngressClass) error { if err != nil { return err } - + bsTLSEnabled := util.GetBackendTlsEnabled(ing) certificateId := util.GetListenerTlsCertificateOcid(ing) if certificateId != nil { tlsPortDetail, ok := listenerTLSConfigMap[servicePort] @@ -165,11 +165,12 @@ func (s *StateStore) BuildState(ingressClass *networkingv1.IngressClass) error { Artifact: *certificateId, } listenerTLSConfigMap[servicePort] = config - bsTLSConfigMap[bsName] = config + updateBackendTlsStatus(bsTLSEnabled, bsTLSConfigMap, bsName, config) } if rule.Host != "" { secretName, ok := hostSecretMap[rule.Host] + if ok && secretName != "" { tlsPortDetail, ok := listenerTLSConfigMap[servicePort] if ok { @@ -183,7 +184,7 @@ func (s *StateStore) BuildState(ingressClass *networkingv1.IngressClass) error { Artifact: secretName, } listenerTLSConfigMap[servicePort] = config - bsTLSConfigMap[bsName] = config + updateBackendTlsStatus(bsTLSEnabled, bsTLSConfigMap, bsName, config) } } } @@ -214,6 +215,18 @@ func (s *StateStore) BuildState(ingressClass *networkingv1.IngressClass) error { return nil } +func updateBackendTlsStatus(bsTLSEnabled bool, bsTLSConfigMap map[string]TlsConfig, bsName string, config TlsConfig) { + if bsTLSEnabled { + bsTLSConfigMap[bsName] = config + } else { + config := TlsConfig{ + Type: "", + Artifact: "", + } + bsTLSConfigMap[bsName] = config + } +} + func validateBackendSetHealthChecker(ingressResource *networkingv1.Ingress, bsHealthCheckerMap map[string]*ociloadbalancer.HealthCheckerDetails, bsName string) error { defaultHealthChecker := util.GetDefaultHeathChecker() diff --git a/pkg/state/ingressstate_test.go b/pkg/state/ingressstate_test.go index 92efa31a..52d326c6 100644 --- a/pkg/state/ingressstate_test.go +++ b/pkg/state/ingressstate_test.go @@ -35,6 +35,7 @@ const ( TestIngressStateFilePath = "test-ingress-state.yaml" TestIngressStateWithPortNameFilePath = "test-ingress-state_withportname.yaml" TestIngressStateWithNamedClassesFilePath = "test-ingress-state_withnamedclasses.yaml" + TestSslTerminationAtLb = "test-ssl-termination-lb.yaml" ) func setUp(ctx context.Context, ingressClassList *networkingv1.IngressClassList, ingressList *networkingv1.IngressList, testService *v1.ServiceList) (networkinglisters.IngressClassLister, networkinglisters.IngressLister, corelisters.ServiceLister) { @@ -418,3 +419,33 @@ func TestValidateProtocolConfigWithConflict(t *testing.T) { Expect(err.Error()).Should(ContainSubstring(fmt.Sprintf(ProtocolConflictMessage, 900))) } + +func TestSslTerminationAtLB(t *testing.T) { + RegisterTestingT(t) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + ingressClassList := testutil.GetIngressClassList() + + ingressList := testutil.ReadResourceAsIngressList(TestSslTerminationAtLb) + + certificateId := "certificateId" + ingressList.Items[0].Spec.TLS = []networkingv1.IngressTLS{} + ingressList.Items[0].Annotations = map[string]string{util.IngressListenerTlsCertificateAnnotation: certificateId} + + testService := testutil.GetServiceListResource("default", "tls-test", 443) + ingressClassLister, ingressLister, serviceLister := setUp(ctx, ingressClassList, ingressList, testService) + + stateStore := NewStateStore(ingressClassLister, ingressLister, serviceLister, nil) + err := stateStore.BuildState(&ingressClassList.Items[0]) + Expect(err).NotTo(HaveOccurred()) + + bsName := util.GenerateBackendSetName("default", "tls-test", 443) + bsTlsConfig := stateStore.IngressGroupState.BackendSetTLSConfigMap[bsName] + Expect(bsTlsConfig.Artifact).Should(Equal("")) + Expect(bsTlsConfig.Type).Should(Equal("")) + + lstTlsConfig := stateStore.IngressGroupState.ListenerTLSConfigMap[443] + Expect(lstTlsConfig.Artifact).Should(Equal(certificateId)) + Expect(lstTlsConfig.Type).Should(Equal(ArtifactTypeCertificate)) +} diff --git a/pkg/state/test-ssl-termination-lb.yaml b/pkg/state/test-ssl-termination-lb.yaml new file mode 100644 index 00000000..1a741e3c --- /dev/null +++ b/pkg/state/test-ssl-termination-lb.yaml @@ -0,0 +1,23 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-tls + annotations: + oci-native-ingress.oraclecloud.com/protocol: HTTP2 + oci-native-ingress.oraclecloud.com/backend-tls-enabled: "false" +spec: + tls: + - hosts: + - foo.bar.com + secretName: secret_name + rules: + - host: "foo.bar.com" + http: + paths: + - pathType: Prefix + path: "/TLSPath" + backend: + service: + name: tls-test + port: + number: 443 \ No newline at end of file diff --git a/pkg/util/util.go b/pkg/util/util.go index c60be8b4..6ffad8c9 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -50,6 +50,7 @@ const ( IngressControllerFinalizer = "oci.oraclecloud.com/ingress-controller-protection" IngressListenerTlsCertificateAnnotation = "oci-native-ingress.oraclecloud.com/certificate-ocid" + IngressBackendTlsEnabledAnnotation = "oci-native-ingress.oraclecloud.com/backend-tls-enabled" // IngressProtocolAnntoation - HTTP only for now // HTTP, HTTP2 - accepted. @@ -164,6 +165,23 @@ func GetListenerTlsCertificateOcid(i *networkingv1.Ingress) *string { return &value } +func GetBackendTlsEnabled(i *networkingv1.Ingress) bool { + annotation := IngressBackendTlsEnabledAnnotation + value, ok := i.Annotations[annotation] + + if !ok || strings.TrimSpace(value) == "" { + return true + } + + result, err := strconv.ParseBool(value) + if err != nil { + klog.Errorf("Error parsing value %s for flag %s as boolean. Setting the default value as 'true'", value, annotation) + return true + } + + return result +} + func GetIngressHealthCheckProtocol(i *networkingv1.Ingress) string { protocol, ok := i.Annotations[IngressHealthCheckProtocolAnnotation] if !ok { diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 1dd9324d..81082467 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -181,6 +181,41 @@ func TestGetListenerTlsCertificateOcid(t *testing.T) { Expect(result).To(BeNil()) } +func TestGetBackendTlsEnabled(t *testing.T) { + RegisterTestingT(t) + i := networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{IngressBackendTlsEnabledAnnotation: "true"}, + }, + } + result := GetBackendTlsEnabled(&i) + Expect(result).Should(Equal(true)) + + i = networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{IngressBackendTlsEnabledAnnotation: "false"}, + }, + } + result = GetBackendTlsEnabled(&i) + Expect(result).Should(Equal(false)) + + i = networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{IngressBackendTlsEnabledAnnotation: "scam"}, + }, + } + result = GetBackendTlsEnabled(&i) + Expect(result).Should(Equal(true)) + + i = networkingv1.Ingress{ + ObjectMeta: metav1.ObjectMeta{ + Annotations: map[string]string{IngressBackendTlsEnabledAnnotation: ""}, + }, + } + result = GetBackendTlsEnabled(&i) + Expect(result).Should(Equal(true)) +} + func TestGetIngressHealthCheckProtocol(t *testing.T) { RegisterTestingT(t) protocol := "http"