@@ -17,6 +17,7 @@ package oci
17
17
import (
18
18
"context"
19
19
20
+ "github.com/oracle/oci-go-sdk/common"
20
21
"github.com/oracle/oci-go-sdk/core"
21
22
"github.com/oracle/oci-go-sdk/loadbalancer"
22
23
"github.com/pkg/errors"
@@ -63,6 +64,12 @@ const (
63
64
// See: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
64
65
ServiceAnnotationLoadBalancerTLSSecret = "service.beta.kubernetes.io/oci-load-balancer-tls-secret"
65
66
67
+ // ServiceAnnotationLoadBalancerTLSBackendSecret is a Service annotation for
68
+ // specifying the TLS secret to install on the load balancer listeners which
69
+ // have SSL enabled.
70
+ // See: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls
71
+ ServiceAnnotationLoadBalancerTLSBackendSecret = "service.beta.kubernetes.io/oci-load-balancer-tls-backend-secret"
72
+
66
73
// ServiceAnnotationLoadBalancerConnectionIdleTimeout is the annotation used
67
74
// on the service to specify the idle connection timeout.
68
75
ServiceAnnotationLoadBalancerConnectionIdleTimeout = "service.beta.kubernetes.io/oci-load-balancer-connection-idle-timeout"
@@ -89,9 +96,10 @@ const (
89
96
// Fallback value if annotation on service is not set
90
97
lbDefaultShape = "100Mbps"
91
98
92
- lbNodesHealthCheckPath = "/healthz"
93
- lbNodesHealthCheckPort = k8sports .ProxyHealthzPort
94
- lbNodesHealthCheckProto = "HTTP"
99
+ lbNodesHealthCheckPath = "/healthz"
100
+ lbNodesHealthCheckPort = k8sports .ProxyHealthzPort
101
+ lbNodesHealthCheckProtoHTTP = "HTTP"
102
+ lbNodesHealthCheckProtoTCP = "TCP"
95
103
)
96
104
97
105
// GetLoadBalancer returns whether the specified load balancer exists, and if
@@ -189,10 +197,10 @@ func getSubnetsForNodes(ctx context.Context, nodes []*v1.Node, client client.Int
189
197
190
198
// readSSLSecret returns the certificate and private key from a Kubernetes TLS
191
199
// private key Secret.
192
- func (cp * CloudProvider ) readSSLSecret (svc * v1.Service ) (string , string , error ) {
193
- secretString , ok := svc .Annotations [ServiceAnnotationLoadBalancerTLSSecret ]
194
- if ! ok {
195
- return "" , "" , errors .Errorf ("no %q annotation found" , ServiceAnnotationLoadBalancerTLSSecret )
200
+ func (cp * CloudProvider ) readSSLSecret (secretType string , svc * v1.Service ) (* SSLK8SSecret , error ) {
201
+ secretString , ok := svc .Annotations [secretType ]
202
+ if ! ok && secretType == ServiceAnnotationLoadBalancerTLSSecret {
203
+ return & SSLK8SSecret {}, errors .Errorf ("no %q annotation found" , secretType )
196
204
}
197
205
198
206
ns , name := parseSecretString (secretString )
@@ -201,24 +209,35 @@ func (cp *CloudProvider) readSSLSecret(svc *v1.Service) (string, string, error)
201
209
}
202
210
secret , err := cp .kubeclient .CoreV1 ().Secrets (ns ).Get (name , metav1.GetOptions {})
203
211
if err != nil {
204
- return "" , "" , err
212
+ return & SSLK8SSecret {} , err
205
213
}
206
214
207
- var cert , key []byte
208
- if cert , ok = secret .Data [sslCertificateFileName ]; ! ok {
209
- return "" , "" , errors .Errorf ("%s not found in secret %s/%s" , sslCertificateFileName , ns , name )
215
+ var cacert , cert , key , pass []byte
216
+ var cacertstr , passstr * string
217
+ if cacert , ok = secret .Data [SSLCAFileName ]; ! ok {
218
+ cacertstr = new (string )
219
+ } else {
220
+ cacertstr = common .String (string (cacert ))
210
221
}
211
- if key , ok = secret .Data [sslPrivateKeyFileName ]; ! ok {
212
- return "" , "" , errors .Errorf ("%s not found in secret %s/%s" , sslPrivateKeyFileName , ns , name )
222
+ if cert , ok = secret .Data [SSLCertificateFileName ]; ! ok {
223
+ return & SSLK8SSecret {}, errors .Errorf ("%s not found in secret %s/%s" , SSLCertificateFileName , ns , name )
213
224
}
214
-
215
- return string (cert ), string (key ), nil
225
+ if key , ok = secret .Data [SSLPrivateKeyFileName ]; ! ok {
226
+ return & SSLK8SSecret {}, errors .Errorf ("%s not found in secret %s/%s" , SSLPrivateKeyFileName , ns , name )
227
+ }
228
+ if pass , ok = secret .Data [SSLPassphrase ]; ! ok {
229
+ passstr = new (string )
230
+ } else {
231
+ passstr = common .String (string (pass ))
232
+ }
233
+ return & SSLK8SSecret {CACert : cacertstr , PublicCert : common .String (string (cert )), PrivateKey : common .String (string (key )),
234
+ Passphrase : passstr }, nil
216
235
}
217
236
218
237
// ensureSSLCertificate creates a OCI SSL certificate to the given load
219
238
// balancer, if it doesn't already exist.
220
- func (cp * CloudProvider ) ensureSSLCertificate (ctx context.Context , lb * loadbalancer.LoadBalancer , spec * LBSpec ) error {
221
- name := spec . SSLConfig .Name
239
+ func (cp * CloudProvider ) ensureSSLCertificate (ctx context.Context , lb * loadbalancer.LoadBalancer , sslConfig * SSLConfig , svc * v1. Service ) error {
240
+ name := sslConfig .Name
222
241
logger := cp .logger .With ("loadBalancerID" , * lb .Id , "certificateName" , name )
223
242
_ , err := cp .client .LoadBalancer ().GetCertificateByName (ctx , * lb .Id , name )
224
243
if err == nil {
@@ -230,7 +249,8 @@ func (cp *CloudProvider) ensureSSLCertificate(ctx context.Context, lb *loadbalan
230
249
}
231
250
232
251
// Although we iterate here only one certificate is supported at the moment.
233
- certs , err := spec .Certificates ()
252
+ certs := make (map [string ]loadbalancer.CertificateDetails )
253
+ err = buildCertificates (sslConfig , svc , certs )
234
254
if err != nil {
235
255
return err
236
256
}
@@ -266,7 +286,8 @@ func (cp *CloudProvider) createLoadBalancer(ctx context.Context, spec *LBSpec) (
266
286
}
267
287
268
288
// Then we create the load balancer and wait for it to be online.
269
- certs , err := spec .Certificates ()
289
+ certs := make (map [string ]loadbalancer.CertificateDetails )
290
+ err = buildCertificates (spec .SSLConfig , spec .service , certs )
270
291
if err != nil {
271
292
return nil , errors .Wrap (err , "get certificates" )
272
293
}
@@ -323,16 +344,17 @@ func (cp *CloudProvider) EnsureLoadBalancer(ctx context.Context, clusterName str
323
344
}
324
345
exists := ! client .IsNotFound (err )
325
346
326
- var ssl * SSLConfig
347
+ var ssl , sslBackendSet * SSLConfig
327
348
if requiresCertificate (service ) {
328
349
ports , err := getSSLEnabledPorts (service )
329
350
if err != nil {
330
351
return nil , err
331
352
}
332
- ssl = NewSSLConfig (lbName , ports , cp )
353
+ ssl = NewSSLConfig (lbName , ServiceAnnotationLoadBalancerTLSSecret , ports , cp )
354
+ sslBackendSet = NewSSLConfig (lbName , ServiceAnnotationLoadBalancerTLSBackendSecret , ports , cp )
333
355
}
334
356
subnets := []string {cp .config .LoadBalancer .Subnet1 , cp .config .LoadBalancer .Subnet2 }
335
- spec , err := NewLBSpec (service , nodes , subnets , ssl , cp .securityListManagerFactory )
357
+ spec , err := NewLBSpec (service , nodes , subnets , ssl , sslBackendSet , cp .securityListManagerFactory )
336
358
if err != nil {
337
359
logger .With (zap .Error (err )).Error ("Failed to derive LBSpec" )
338
360
return nil , err
@@ -351,8 +373,11 @@ func (cp *CloudProvider) EnsureLoadBalancer(ctx context.Context, clusterName str
351
373
352
374
// If the load balancer needs an SSL cert ensure it is present.
353
375
if requiresCertificate (service ) {
354
- if err := cp .ensureSSLCertificate (ctx , lb , spec ); err != nil {
355
- return nil , errors .Wrap (err , "ensuring ssl certificate" )
376
+ if err := cp .ensureSSLCertificate (ctx , lb , spec .SSLConfig , spec .service ); err != nil {
377
+ return nil , errors .Wrap (err , "ensuring ssl certificate for listeners" )
378
+ }
379
+ if err := cp .ensureSSLCertificate (ctx , lb , spec .SSLBackendSetConfig , spec .service ); err != nil {
380
+ return nil , errors .Wrap (err , "ensuring ssl certificate for backend sets" )
356
381
}
357
382
}
358
383
0 commit comments