Skip to content

Commit 4c60937

Browse files
committed
feat(lb): add ssl bridging annotations
1 parent 2ba1ad7 commit 4c60937

File tree

3 files changed

+100
-7
lines changed

3 files changed

+100
-7
lines changed

docs/loadbalancer-annotations.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ This is the annotation to set the forward protocol of the LB to HTTP.
140140
The possible values are `false`, `true` or `*` for all ports or a comma delimited list of the service port (for instance `80,443`).
141141
NB: forwarding HTTPS traffic with HTTP protocol enabled will work only if using a certificate, and the LB will send HTTP traffic to the backend.
142142

143+
### `service.beta.kubernetes.io/scw-loadbalancer-http-backend-tls`
144+
This is the annotation to enable tls towards the backend when using http forward protocol
145+
The possible values are `false`, `true` or `*` for all ports or a comma delimited list of the service port (for instance `80,443`)
146+
147+
### `service.beta.kubernetes.io/scw-loadbalancer-http-backend-tls-skip-verify`
148+
This is the annotation to skip tls verification on backends when using http forward protocol with TLS enabled
149+
The possible values are `false`, `true` or `*` for all ports or a comma delimited list of the service port (for instance `80,443`)
150+
143151
### `service.beta.kubernetes.io/scw-loadbalancer-certificate-ids`
144152
This is the annotation to choose the the certificate IDs to associate with this LoadBalancer.
145153
The possible format are:

scaleway/loadbalancers.go

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,16 @@ func servicePortToBackend(service *v1.Service, loadbalancer *scwlb.LB, port v1.S
978978
return nil, err
979979
}
980980

981+
sslBridging, err := getSSLBridging(service, port.NodePort)
982+
if err != nil {
983+
return nil, err
984+
}
985+
986+
sslSkipVerify, err := getSSLBridgingSkipVerify(service, port.NodePort)
987+
if err != nil {
988+
return nil, err
989+
}
990+
981991
forwardPortAlgorithm, err := getForwardPortAlgorithm(service)
982992
if err != nil {
983993
return nil, err
@@ -1107,8 +1117,10 @@ func servicePortToBackend(service *v1.Service, loadbalancer *scwlb.LB, port v1.S
11071117
backend := &scwlb.Backend{
11081118
Name: fmt.Sprintf("%s_tcp_%d", string(service.UID), port.NodePort),
11091119
Pool: nodeIPs,
1110-
ForwardPort: port.NodePort,
11111120
ForwardProtocol: protocol,
1121+
SslBridging: scw.BoolPtr(sslBridging),
1122+
IgnoreSslServerVerify: scw.BoolPtr(sslSkipVerify),
1123+
ForwardPort: port.NodePort,
11121124
ForwardPortAlgorithm: forwardPortAlgorithm,
11131125
StickySessions: stickySessions,
11141126
ProxyProtocol: proxyProtocol,
@@ -1196,14 +1208,22 @@ func backendEquals(got, want *scwlb.Backend) bool {
11961208
klog.V(3).Infof("backend.Name: %s - %s", got.Name, want.Name)
11971209
return false
11981210
}
1199-
if got.ForwardPort != want.ForwardPort {
1200-
klog.V(3).Infof("backend.ForwardPort: %d - %d", got.ForwardPort, want.ForwardPort)
1201-
return false
1202-
}
12031211
if got.ForwardProtocol != want.ForwardProtocol {
12041212
klog.V(3).Infof("backend.ForwardProtocol: %s - %s", got.ForwardProtocol, want.ForwardProtocol)
12051213
return false
12061214
}
1215+
if !reflect.DeepEqual(got.SslBridging, want.SslBridging) {
1216+
klog.V(3).Infof("backend.SslBridging: %s - %s", ptrBoolToString(got.SslBridging), ptrBoolToString(want.SslBridging))
1217+
return false
1218+
}
1219+
if !reflect.DeepEqual(got.IgnoreSslServerVerify, want.IgnoreSslServerVerify) {
1220+
klog.V(3).Infof("backend.IgnoreSslServerVerify: %s - %s", ptrBoolToString(got.IgnoreSslServerVerify), ptrBoolToString(want.IgnoreSslServerVerify))
1221+
return false
1222+
}
1223+
if got.ForwardPort != want.ForwardPort {
1224+
klog.V(3).Infof("backend.ForwardPort: %d - %d", got.ForwardPort, want.ForwardPort)
1225+
return false
1226+
}
12071227
if got.ForwardPortAlgorithm != want.ForwardPortAlgorithm {
12081228
klog.V(3).Infof("backend.ForwardPortAlgorithm: %s - %s", got.ForwardPortAlgorithm, want.ForwardPortAlgorithm)
12091229
return false
@@ -1410,6 +1430,7 @@ func (l *loadbalancers) createBackend(service *v1.Service, loadbalancer *scwlb.L
14101430
LBID: loadbalancer.ID,
14111431
Name: backend.Name,
14121432
ForwardProtocol: backend.ForwardProtocol,
1433+
SslBridging: backend.SslBridging,
14131434
ForwardPort: backend.ForwardPort,
14141435
ForwardPortAlgorithm: backend.ForwardPortAlgorithm,
14151436
StickySessions: backend.StickySessions,
@@ -1438,6 +1459,7 @@ func (l *loadbalancers) updateBackend(service *v1.Service, loadbalancer *scwlb.L
14381459
BackendID: backend.ID,
14391460
Name: backend.Name,
14401461
ForwardProtocol: backend.ForwardProtocol,
1462+
SslBridging: backend.SslBridging,
14411463
ForwardPort: backend.ForwardPort,
14421464
ForwardPortAlgorithm: backend.ForwardPortAlgorithm,
14431465
StickySessions: backend.StickySessions,
@@ -1477,7 +1499,7 @@ func (l *loadbalancers) updateBackend(service *v1.Service, loadbalancer *scwlb.L
14771499
return b, nil
14781500
}
14791501

1480-
// createBackend creates a frontend on the load balancer
1502+
// createFrontend creates a frontend on the load balancer
14811503
func (l *loadbalancers) createFrontend(service *v1.Service, loadbalancer *scwlb.LB, frontend *scwlb.Frontend, backend *scwlb.Backend) (*scwlb.Frontend, error) {
14821504
f, err := l.api.CreateFrontend(&scwlb.ZonedAPICreateFrontendRequest{
14831505
Zone: loadbalancer.Zone,
@@ -1493,7 +1515,7 @@ func (l *loadbalancers) createFrontend(service *v1.Service, loadbalancer *scwlb.
14931515
return f, err
14941516
}
14951517

1496-
// updateBackend updates a frontend on the load balancer
1518+
// updateFrontend updates a frontend on the load balancer
14971519
func (l *loadbalancers) updateFrontend(service *v1.Service, loadbalancer *scwlb.LB, frontend *scwlb.Frontend, backend *scwlb.Backend) (*scwlb.Frontend, error) {
14981520
f, err := l.api.UpdateFrontend(&scwlb.ZonedAPIUpdateFrontendRequest{
14991521
Zone: loadbalancer.Zone,
@@ -1638,3 +1660,10 @@ func ptrInt32ToString(i *int32) string {
16381660
}
16391661
return fmt.Sprintf("%d", *i)
16401662
}
1663+
1664+
func ptrBoolToString(b *bool) string {
1665+
if b == nil {
1666+
return "<nil>"
1667+
}
1668+
return fmt.Sprintf("%t", *b)
1669+
}

scaleway/loadbalancers_annotations.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ const (
136136
// (for instance "80,443")
137137
serviceAnnotationLoadBalancerProtocolHTTP = "service.beta.kubernetes.io/scw-loadbalancer-protocol-http"
138138

139+
// serviceAnnotationLoadBalancerHTTPBackendTLS is the annotation to enable tls towards the backend when using http forward protocol
140+
// The possible values are "false", "true" or "*" for all ports or a comma delimited list of the service port
141+
// (for instance "80,443")
142+
serviceAnnotationLoadBalancerHTTPBackendTLS = "service.beta.kubernetes.io/scw-loadbalancer-http-backend-tls"
143+
144+
// serviceAnnotationLoadBalancerHTTPBackendTLSSkipVerify is the annotation to skip tls verification on backends when using http forward protocol with TLS enabled
145+
// The possible values are "false", "true" or "*" for all ports or a comma delimited list of the service port
146+
// (for instance "80,443")
147+
serviceAnnotationLoadBalancerHTTPBackendTLSSkipVerify = "service.beta.kubernetes.io/scw-loadbalancer-http-backend-tls-skip-verify"
148+
139149
// serviceAnnotationLoadBalancerCertificateIDs is the annotation to choose the certificate IDS to associate
140150
// with this LoadBalancer.
141151
// The possible format are:
@@ -543,6 +553,52 @@ func getForwardProtocol(service *v1.Service, nodePort int32) (scwlb.Protocol, er
543553
return scwlb.ProtocolTCP, nil
544554
}
545555

556+
func getSSLBridging(service *v1.Service, nodePort int32) (bool, error) {
557+
tlsEnabled := service.Annotations[serviceAnnotationLoadBalancerHTTPBackendTLS]
558+
559+
var svcPort int32 = -1
560+
for _, p := range service.Spec.Ports {
561+
if p.NodePort == nodePort {
562+
svcPort = p.Port
563+
}
564+
}
565+
if svcPort == -1 {
566+
klog.Errorf("no valid port found")
567+
return false, errLoadBalancerInvalidAnnotation
568+
}
569+
570+
isTLSEnabled, err := isPortInRange(tlsEnabled, svcPort)
571+
if err != nil {
572+
klog.Errorf("unable to check if port %d is in range %s", svcPort, tlsEnabled)
573+
return false, err
574+
}
575+
576+
return isTLSEnabled, nil
577+
}
578+
579+
func getSSLBridgingSkipVerify(service *v1.Service, nodePort int32) (bool, error) {
580+
skipTLSVerify := service.Annotations[serviceAnnotationLoadBalancerHTTPBackendTLSSkipVerify]
581+
582+
var svcPort int32 = -1
583+
for _, p := range service.Spec.Ports {
584+
if p.NodePort == nodePort {
585+
svcPort = p.Port
586+
}
587+
}
588+
if svcPort == -1 {
589+
klog.Errorf("no valid port found")
590+
return false, errLoadBalancerInvalidAnnotation
591+
}
592+
593+
isSkipTLSVerify, err := isPortInRange(skipTLSVerify, svcPort)
594+
if err != nil {
595+
klog.Errorf("unable to check if port %d is in range %s", svcPort, skipTLSVerify)
596+
return false, err
597+
}
598+
599+
return isSkipTLSVerify, nil
600+
}
601+
546602
func getCertificateIDs(service *v1.Service, port int32) ([]string, error) {
547603
certificates := service.Annotations[serviceAnnotationLoadBalancerCertificateIDs]
548604
ids := []string{}

0 commit comments

Comments
 (0)