Skip to content

Commit 418cd06

Browse files
committed
fix update logic for BackendSets and Listeners
- For Listener sync, fix panic scenario when updating non-TLS configured Ingress to TLS-configured Ingress - Split BackendSet update wrapper method into two - one for bulk updating backends and one for updating other details. This is done to enable updating to nil value for sslConfig.
1 parent cb80bdb commit 418cd06

File tree

5 files changed

+117
-50
lines changed

5 files changed

+117
-50
lines changed

pkg/controllers/ingress/ingress.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ func syncListener(ctx context.Context, namespace string, stateStore *state.State
522522
}
523523

524524
if sslConfig != nil {
525-
if !reflect.DeepEqual(listener.SslConfiguration.CertificateIds, sslConfig.CertificateIds) {
525+
if listener.SslConfiguration == nil || !reflect.DeepEqual(listener.SslConfiguration.CertificateIds, sslConfig.CertificateIds) {
526526
klog.Infof("SSL config for listener update is %s", util.PrettyPrint(sslConfig))
527527
needsUpdate = true
528528
}
@@ -579,11 +579,10 @@ func syncBackendSet(ctx context.Context, ingress *networkingv1.Ingress, lbID str
579579
if err != nil {
580580
return err
581581
}
582-
if sslConfig != nil {
583-
if bs.SslConfiguration == nil || !reflect.DeepEqual(bs.SslConfiguration.TrustedCertificateAuthorityIds, sslConfig.TrustedCertificateAuthorityIds) {
584-
klog.Infof("SSL config for backend set %s update is %s", *bs.Name, util.PrettyPrint(sslConfig))
585-
needsUpdate = true
586-
}
582+
583+
if backendSetSslConfigNeedsUpdate(sslConfig, &bs) {
584+
klog.Infof("SSL config for backend set %s update is %s", *bs.Name, util.PrettyPrint(sslConfig))
585+
needsUpdate = true
587586
}
588587

589588
healthChecker := stateStore.GetBackendSetHealthChecker(*bs.Name)
@@ -601,7 +600,7 @@ func syncBackendSet(ctx context.Context, ingress *networkingv1.Ingress, lbID str
601600
}
602601

603602
if needsUpdate {
604-
err = wrapperClient.GetLbClient().UpdateBackendSet(context.TODO(), lb.Id, etag, bs, nil, sslConfig, healthChecker, &policy)
603+
err = wrapperClient.GetLbClient().UpdateBackendSetDetails(context.TODO(), *lb.Id, etag, &bs, sslConfig, healthChecker, policy)
605604
if err != nil {
606605
return err
607606
}

pkg/controllers/ingress/util.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,3 +429,17 @@ func CreateOrGetCaBundleForBackendSet(namespace string, secretName string, compa
429429
func isTrustAuthorityCaBundle(id string) bool {
430430
return strings.Contains(id, "cabundle")
431431
}
432+
433+
func backendSetSslConfigNeedsUpdate(calculatedConfig *ociloadbalancer.SslConfigurationDetails,
434+
currentBackendSet *ociloadbalancer.BackendSet) bool {
435+
if calculatedConfig == nil && currentBackendSet.SslConfiguration != nil {
436+
return true
437+
}
438+
439+
if calculatedConfig != nil && (currentBackendSet.SslConfiguration == nil ||
440+
!reflect.DeepEqual(currentBackendSet.SslConfiguration.TrustedCertificateAuthorityIds, calculatedConfig.TrustedCertificateAuthorityIds)) {
441+
return true
442+
}
443+
444+
return false
445+
}

pkg/controllers/ingress/util_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,34 @@ intermediatecert
367367
Expect(err).To(HaveOccurred())
368368
}
369369

370+
func TestBackendSetSslConfigNeedsUpdate(t *testing.T) {
371+
RegisterTestingT(t)
372+
373+
caBundleId1 := []string{"caCert1"}
374+
caBundleId2 := []string{"caCert2"}
375+
376+
backendSetWithNilSslConfig := &ociloadbalancer.BackendSet{}
377+
presentBackendSet1 := &ociloadbalancer.BackendSet{
378+
SslConfiguration: &ociloadbalancer.SslConfiguration{
379+
TrustedCertificateAuthorityIds: caBundleId1,
380+
},
381+
}
382+
presentBackendSet2 := &ociloadbalancer.BackendSet{
383+
SslConfiguration: &ociloadbalancer.SslConfiguration{
384+
TrustedCertificateAuthorityIds: caBundleId2,
385+
},
386+
}
387+
calculatedConfig1 := &ociloadbalancer.SslConfigurationDetails{
388+
TrustedCertificateAuthorityIds: caBundleId1,
389+
}
390+
391+
Expect(backendSetSslConfigNeedsUpdate(nil, backendSetWithNilSslConfig)).To(BeFalse())
392+
Expect(backendSetSslConfigNeedsUpdate(nil, presentBackendSet1)).To(BeTrue())
393+
Expect(backendSetSslConfigNeedsUpdate(calculatedConfig1, presentBackendSet1)).To(BeFalse())
394+
Expect(backendSetSslConfigNeedsUpdate(calculatedConfig1, presentBackendSet2)).To(BeTrue())
395+
Expect(backendSetSslConfigNeedsUpdate(calculatedConfig1, backendSetWithNilSslConfig)).To(BeTrue())
396+
}
397+
370398
func generateTestCertsAndKey() (string, string, string) {
371399
caCert := &x509.Certificate{
372400
SerialNumber: big.NewInt(1),

pkg/loadbalancer/loadbalancer.go

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ func (lbc *LoadBalancerClient) updateRoutingPolicyRules(ctx context.Context, lbI
451451
return err
452452
}
453453

454+
// UpdateBackends updates Backends for backendSetName, while preserving sslConfig, policy, and healthChecker details
454455
func (lbc *LoadBalancerClient) UpdateBackends(ctx context.Context, lbID string, backendSetName string, backends []loadbalancer.BackendDetails) error {
455456
lb, etag, err := lbc.GetLoadBalancer(ctx, lbID)
456457
if err != nil {
@@ -477,56 +478,60 @@ func (lbc *LoadBalancerClient) UpdateBackends(ctx context.Context, lbID string,
477478
return nil
478479
}
479480

480-
return lbc.UpdateBackendSet(ctx, lb.Id, etag, backendSet, backends, nil, nil, nil)
481-
}
482-
483-
func (lbc *LoadBalancerClient) UpdateBackendSet(ctx context.Context, lbID *string, etag string, backendSet loadbalancer.BackendSet,
484-
backends []loadbalancer.BackendDetails, sslConfig *loadbalancer.SslConfigurationDetails,
485-
healthCheckerDetails *loadbalancer.HealthCheckerDetails, policy *string) error {
486-
487-
if backends == nil {
488-
backends = make([]loadbalancer.BackendDetails, len(backendSet.Backends))
489-
for i := range backendSet.Backends {
490-
backend := backendSet.Backends[i]
491-
backends[i] = loadbalancer.BackendDetails{
492-
IpAddress: backend.IpAddress,
493-
Port: backend.Port,
494-
Weight: backend.Weight,
495-
Drain: backend.Drain,
496-
Backup: backend.Backup,
497-
Offline: backend.Offline,
498-
}
481+
var sslConfig *loadbalancer.SslConfigurationDetails
482+
if backendSet.SslConfiguration != nil {
483+
sslConfig = &loadbalancer.SslConfigurationDetails{
484+
TrustedCertificateAuthorityIds: backendSet.SslConfiguration.TrustedCertificateAuthorityIds,
499485
}
500486
}
501-
if sslConfig == nil && backendSet.SslConfiguration != nil {
502-
sslConfig = &loadbalancer.SslConfigurationDetails{TrustedCertificateAuthorityIds: backendSet.SslConfiguration.TrustedCertificateAuthorityIds}
503-
}
504-
505-
if healthCheckerDetails == nil {
506-
healthChecker := backendSet.HealthChecker
507-
healthCheckerDetails = &loadbalancer.HealthCheckerDetails{
508-
Protocol: healthChecker.Protocol,
509-
UrlPath: healthChecker.UrlPath,
510-
Port: healthChecker.Port,
511-
ReturnCode: healthChecker.ReturnCode,
512-
Retries: healthChecker.Retries,
513-
TimeoutInMillis: healthChecker.TimeoutInMillis,
514-
IntervalInMillis: healthChecker.IntervalInMillis,
515-
ResponseBodyRegex: healthChecker.ResponseBodyRegex,
516-
IsForcePlainText: healthChecker.IsForcePlainText,
517-
}
487+
488+
healthCheckerDetails := &loadbalancer.HealthCheckerDetails{
489+
Protocol: backendSet.HealthChecker.Protocol,
490+
UrlPath: backendSet.HealthChecker.UrlPath,
491+
Port: backendSet.HealthChecker.Port,
492+
ReturnCode: backendSet.HealthChecker.ReturnCode,
493+
Retries: backendSet.HealthChecker.Retries,
494+
TimeoutInMillis: backendSet.HealthChecker.TimeoutInMillis,
495+
IntervalInMillis: backendSet.HealthChecker.IntervalInMillis,
496+
ResponseBodyRegex: backendSet.HealthChecker.ResponseBodyRegex,
497+
IsForcePlainText: backendSet.HealthChecker.IsForcePlainText,
518498
}
519499

520-
if policy == nil {
521-
policy = backendSet.Policy
500+
policy := *backendSet.Policy
501+
502+
return lbc.UpdateBackendSet(ctx, lbID, etag, *backendSet.Name, policy, healthCheckerDetails, sslConfig, backends)
503+
}
504+
505+
// UpdateBackendSetDetails updates sslConfig, policy, and healthChecker details for backendSet, while preserving individual backends
506+
func (lbc *LoadBalancerClient) UpdateBackendSetDetails(ctx context.Context, lbID string, etag string,
507+
backendSet *loadbalancer.BackendSet, sslConfig *loadbalancer.SslConfigurationDetails,
508+
healthCheckerDetails *loadbalancer.HealthCheckerDetails, policy string) error {
509+
510+
backends := make([]loadbalancer.BackendDetails, len(backendSet.Backends))
511+
for i := range backendSet.Backends {
512+
backend := backendSet.Backends[i]
513+
backends[i] = loadbalancer.BackendDetails{
514+
IpAddress: backend.IpAddress,
515+
Port: backend.Port,
516+
Weight: backend.Weight,
517+
Drain: backend.Drain,
518+
Backup: backend.Backup,
519+
Offline: backend.Offline,
520+
}
522521
}
523522

523+
return lbc.UpdateBackendSet(ctx, lbID, etag, *backendSet.Name, policy, healthCheckerDetails, sslConfig, backends)
524+
}
525+
526+
func (lbc *LoadBalancerClient) UpdateBackendSet(ctx context.Context, lbID string, etag string, backendSetName string,
527+
policy string, healthCheckerDetails *loadbalancer.HealthCheckerDetails, sslConfig *loadbalancer.SslConfigurationDetails,
528+
backends []loadbalancer.BackendDetails) error {
524529
updateBackendSetRequest := loadbalancer.UpdateBackendSetRequest{
525530
IfMatch: common.String(etag),
526-
LoadBalancerId: lbID,
527-
BackendSetName: common.String(*backendSet.Name),
531+
LoadBalancerId: common.String(lbID),
532+
BackendSetName: common.String(backendSetName),
528533
UpdateBackendSetDetails: loadbalancer.UpdateBackendSetDetails{
529-
Policy: policy,
534+
Policy: common.String(policy),
530535
HealthChecker: healthCheckerDetails,
531536
SslConfiguration: sslConfig,
532537
Backends: backends,
@@ -539,7 +544,8 @@ func (lbc *LoadBalancerClient) UpdateBackendSet(ctx context.Context, lbID *strin
539544
return err
540545
}
541546

542-
klog.Infof("Update backend set response: name: %s, work request id: %s, opc request id: %s.", *backendSet.Name, *resp.OpcWorkRequestId, *resp.OpcRequestId)
547+
klog.Infof("Update backend set response: name: %s, work request id: %s, opc request id: %s.",
548+
*updateBackendSetRequest.BackendSetName, *resp.OpcWorkRequestId, *resp.OpcRequestId)
543549
_, err = lbc.waitForWorkRequest(ctx, *resp.OpcWorkRequestId)
544550
return err
545551
}
@@ -643,7 +649,7 @@ func (lbc *LoadBalancerClient) CreateListener(ctx context.Context, lbID string,
643649
if sslConfig == nil {
644650
return fmt.Errorf("no TLS configuration provided for a HTTP2 listener at port %d", listenerPort)
645651
}
646-
652+
647653
sslConfig.CipherSuiteName = common.String(util.ProtocolHTTP2DefaultCipherSuite)
648654
}
649655

pkg/loadbalancer/loadbalancer_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,26 @@ func TestLoadBalancerClient_UpdateBackends(t *testing.T) {
119119

120120
}
121121

122+
func TestLoadBalancerClient_UpdateBackendSetDetails(t *testing.T) {
123+
RegisterTestingT(t)
124+
loadBalancerClient := setupLBClient()
125+
126+
lbId := "id"
127+
etag := "etag"
128+
policy := "policy"
129+
bsName := util.GenerateBackendSetName("default", "testecho1", 80)
130+
131+
lb := util.SampleLoadBalancerResponse()
132+
sslConfigDetails := ociloadbalancer.SslConfigurationDetails{TrustedCertificateAuthorityIds: []string{"trusted-cert"}}
133+
healthCheckerDetails := ociloadbalancer.HealthCheckerDetails{}
134+
135+
bs := lb.BackendSets[bsName]
136+
137+
err := loadBalancerClient.UpdateBackendSetDetails(context.TODO(), lbId, etag, &bs, &sslConfigDetails,
138+
&healthCheckerDetails, policy)
139+
Expect(err).To(BeNil())
140+
}
141+
122142
func TestLoadBalancerClient_DeleteBackendSet(t *testing.T) {
123143
RegisterTestingT(t)
124144
loadBalancerClient := setupLBClient()

0 commit comments

Comments
 (0)