Skip to content

Commit

Permalink
Enable TLS termination on LB. (#44)
Browse files Browse the repository at this point in the history
* Add support to disable TLS on the backend via annotation: `oci-native-ingress.oraclecloud.com/backend-tls-enabled`

---------

Co-authored-by: Inbaraj S <[email protected]>
  • Loading branch information
robo-cap and Inbaraj-S authored Mar 22, 2024
1 parent 913ccdd commit 46ad7f3
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 3 deletions.
19 changes: 16 additions & 3 deletions pkg/state/ingressstate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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 {
Expand All @@ -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)
}
}
}
Expand Down Expand Up @@ -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()
Expand Down
31 changes: 31 additions & 0 deletions pkg/state/ingressstate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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))
}
23 changes: 23 additions & 0 deletions pkg/state/test-ssl-termination-lb.yaml
Original file line number Diff line number Diff line change
@@ -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
18 changes: 18 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 {
Expand Down
35 changes: 35 additions & 0 deletions pkg/util/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 46ad7f3

Please sign in to comment.