Skip to content

Commit a9b7292

Browse files
Merge pull request #1114 from gcs278/NE705-aws-subnet-selection-fix-nlbstatus
NE-1531: Fix Initialization of NLB Status Parameters
2 parents 64eafae + b8b9a43 commit a9b7292

File tree

4 files changed

+114
-71
lines changed

4 files changed

+114
-71
lines changed

pkg/operator/controller/ingress/controller.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,12 @@ func setDefaultProviderParameters(lbs *operatorv1.LoadBalancerStrategy, ingressC
714714
if lbs.ProviderParameters.AWS.ClassicLoadBalancerParameters == nil {
715715
lbs.ProviderParameters.AWS.ClassicLoadBalancerParameters = &operatorv1.AWSClassicLoadBalancerParameters{}
716716
}
717+
case operatorv1.AWSNetworkLoadBalancer:
718+
if lbs.ProviderParameters.AWS.NetworkLoadBalancerParameters == nil {
719+
lbs.ProviderParameters.AWS.NetworkLoadBalancerParameters = &operatorv1.AWSNetworkLoadBalancerParameters{}
720+
}
717721
}
722+
718723
case operatorv1.GCPLoadBalancerProvider:
719724
if lbs.ProviderParameters == nil {
720725
lbs.ProviderParameters = &operatorv1.ProviderLoadBalancerParameters{}

pkg/operator/controller/ingress/controller_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,8 @@ func TestSetDefaultPublishingStrategySetsPlatformDefaults(t *testing.T) {
154154
ProviderParameters: &operatorv1.ProviderLoadBalancerParameters{
155155
Type: operatorv1.AWSLoadBalancerProvider,
156156
AWS: &operatorv1.AWSLoadBalancerParameters{
157-
Type: operatorv1.AWSNetworkLoadBalancer,
157+
Type: operatorv1.AWSNetworkLoadBalancer,
158+
NetworkLoadBalancerParameters: &operatorv1.AWSNetworkLoadBalancerParameters{},
158159
},
159160
},
160161
},

test/e2e/lb_subnets_test.go

Lines changed: 104 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"fmt"
1010
"reflect"
11+
"strings"
1112
"testing"
1213
"time"
1314

@@ -79,7 +80,7 @@ func TestAWSLBSubnets(t *testing.T) {
7980
t.Cleanup(func() { assertIngressControllerDeleted(t, kclient, ic) })
8081

8182
// Wait for the load balancer and DNS to be ready.
82-
if err = waitForIngressControllerCondition(t, kclient, 10*time.Minute, icName, availableConditionsForIngressControllerWithLoadBalancer...); err != nil {
83+
if err = waitForIngressControllerCondition(t, kclient, 10*time.Minute, icName, availableNotProgressingConditionsForIngressControllerWithLoadBalancer...); err != nil {
8384
t.Fatalf("failed to observe expected conditions: %v", err)
8485
}
8586

@@ -114,12 +115,19 @@ func TestAWSLBSubnets(t *testing.T) {
114115
t.Fatalf("failed to update ingresscontroller: %v", err)
115116
}
116117

117-
// Since the subnets are invalid, the load balancer will fail to provision and set LoadBalancerReady=False.
118-
loadBalancerReadyFalse := operatorv1.OperatorCondition{
119-
Type: operatorv1.LoadBalancerReadyIngressConditionType,
120-
Status: operatorv1.ConditionFalse,
118+
// Since the subnets are invalid, the load balancer will fail to provision and set LoadBalancerReady=False, but
119+
// it shouldn't be Progressing either.
120+
loadBalancerNotReadyNotProgressing := []operatorv1.OperatorCondition{
121+
{
122+
Type: operatorv1.LoadBalancerReadyIngressConditionType,
123+
Status: operatorv1.ConditionFalse,
124+
},
125+
{
126+
Type: operatorv1.OperatorStatusTypeProgressing,
127+
Status: operatorv1.ConditionFalse,
128+
},
121129
}
122-
effectuateIngressControllerSubnets(t, ic, invalidSubnets, loadBalancerReadyFalse)
130+
effectuateIngressControllerSubnets(t, ic, invalidSubnets, loadBalancerNotReadyNotProgressing...)
123131

124132
// Now, update the IngressController to change to use a NLB and the public subnets again.
125133
t.Logf("updating ingresscontroller %q to use an NLB and public subnets", ic.Name)
@@ -132,7 +140,7 @@ func TestAWSLBSubnets(t *testing.T) {
132140
t.Fatalf("failed to update ingresscontroller: %v", err)
133141
}
134142

135-
effectuateIngressControllerSubnets(t, ic, publicSubnets, availableConditionsForIngressControllerWithLoadBalancer...)
143+
effectuateIngressControllerSubnets(t, ic, publicSubnets, availableNotProgressingConditionsForIngressControllerWithLoadBalancer...)
136144

137145
// Verify we can still reach the NLB with the provided public subnets.
138146
t.Logf("verifying external connectivity for ingresscontroller %q using an NLB with specified public subnets", ic.Name)
@@ -158,7 +166,7 @@ func TestAWSLBSubnets(t *testing.T) {
158166
waitForLBSubnetAnnotation(t, ic, nil)
159167

160168
// Expect the load balancer to provision successfully with the subnets removed.
161-
if err = waitForIngressControllerCondition(t, kclient, 10*time.Minute, icName, availableConditionsForIngressControllerWithLoadBalancer...); err != nil {
169+
if err = waitForIngressControllerCondition(t, kclient, 10*time.Minute, icName, availableNotProgressingConditionsForIngressControllerWithLoadBalancer...); err != nil {
162170
t.Fatalf("failed to observe expected conditions: %v", err)
163171
}
164172

@@ -190,76 +198,102 @@ func TestUnmanagedAWSLBSubnets(t *testing.T) {
190198
}
191199
t.Logf("discovered the following public subnets: %q", publicSubnets.Names)
192200

193-
// Next, create a vanilla IngressController.
194-
icName := types.NamespacedName{Namespace: operatorNamespace, Name: "unmanaged-aws-subnets"}
195-
t.Logf("creating ingresscontroller %q using CLB with public subnets", icName.Name)
196-
domain := icName.Name + "." + dnsConfig.Spec.BaseDomain
197-
ic := newLoadBalancerController(icName, domain)
198-
if err = kclient.Create(context.Background(), ic); err != nil {
199-
t.Fatalf("expected ingresscontroller creation failed: %v", err)
201+
testCases := []struct {
202+
name string
203+
lbType operatorv1.AWSLoadBalancerType
204+
}{
205+
{
206+
name: "IngressController using NLB with unmanaged subnets on service",
207+
lbType: operatorv1.AWSNetworkLoadBalancer,
208+
},
209+
{
210+
name: "IngressController using CLB with unmanaged subnets on service",
211+
lbType: operatorv1.AWSClassicLoadBalancer,
212+
},
200213
}
201-
t.Cleanup(func() { assertIngressControllerDeleted(t, kclient, ic) })
214+
for _, tc := range testCases {
215+
t.Run(tc.name, func(t *testing.T) {
216+
// Create the IngressController with the LB Type specified.
217+
icName := types.NamespacedName{Namespace: operatorNamespace, Name: fmt.Sprintf("unmanaged-aws-subnets-%s", strings.ToLower(string(tc.lbType)))}
218+
t.Logf("creating ingresscontroller %q using %q load balancer with public subnets", icName.Name, tc.lbType)
219+
domain := icName.Name + "." + dnsConfig.Spec.BaseDomain
220+
ic := newLoadBalancerController(icName, domain)
221+
ic.Spec.EndpointPublishingStrategy.LoadBalancer = &operatorv1.LoadBalancerStrategy{
222+
Scope: operatorv1.ExternalLoadBalancer,
223+
DNSManagementPolicy: operatorv1.ManagedLoadBalancerDNS,
224+
ProviderParameters: &operatorv1.ProviderLoadBalancerParameters{
225+
Type: operatorv1.AWSLoadBalancerProvider,
226+
AWS: &operatorv1.AWSLoadBalancerParameters{
227+
Type: tc.lbType,
228+
},
229+
},
230+
}
231+
if err = kclient.Create(context.Background(), ic); err != nil {
232+
t.Fatalf("expected ingresscontroller creation failed: %v", err)
233+
}
234+
t.Cleanup(func() { assertIngressControllerDeleted(t, kclient, ic) })
202235

203-
// Wait for the load balancer and DNS to be ready.
204-
if err = waitForIngressControllerCondition(t, kclient, 10*time.Minute, icName, availableConditionsForIngressControllerWithLoadBalancer...); err != nil {
205-
t.Fatalf("failed to observe expected conditions: %v", err)
206-
}
236+
// Wait for the load balancer and DNS to be ready.
237+
if err = waitForIngressControllerCondition(t, kclient, 10*time.Minute, icName, availableNotProgressingConditionsForIngressControllerWithLoadBalancer...); err != nil {
238+
t.Fatalf("failed to observe expected conditions: %v", err)
239+
}
207240

208-
// Ensure there is no subnet annotation on the service.
209-
waitForLBSubnetAnnotation(t, ic, nil)
241+
// Ensure there is no subnet annotation on the service.
242+
waitForLBSubnetAnnotation(t, ic, nil)
210243

211-
// Now, update the subnet annotation directly on the service.
212-
serviceName := controller.LoadBalancerServiceName(ic)
213-
t.Logf("updating service %s%s directly add unmanaged subnet annotation", serviceName.Namespace, serviceName.Name)
214-
lbService := &corev1.Service{}
215-
if err := kclient.Get(context.Background(), serviceName, lbService); err != nil {
216-
t.Fatalf("failed to get service: %v", err)
217-
}
218-
lbService.Annotations[awsLBSubnetAnnotation] = ingress.JoinAWSSubnets(publicSubnets, ",")
219-
if err := kclient.Update(context.Background(), lbService); err != nil {
220-
t.Fatalf("failed to update service: %v", err)
221-
}
244+
// Now, update the subnet annotation directly on the service.
245+
serviceName := controller.LoadBalancerServiceName(ic)
246+
t.Logf("updating service %s/%s by adding unmanaged subnet annotation", serviceName.Namespace, serviceName.Name)
247+
lbService := &corev1.Service{}
248+
if err := kclient.Get(context.Background(), serviceName, lbService); err != nil {
249+
t.Fatalf("failed to get service: %v", err)
250+
}
251+
lbService.Annotations[awsLBSubnetAnnotation] = ingress.JoinAWSSubnets(publicSubnets, ",")
252+
if err := kclient.Update(context.Background(), lbService); err != nil {
253+
t.Fatalf("failed to update service: %v", err)
254+
}
222255

223-
// LoadBalancerProgressing should become True because the subnet annotation
224-
// doesn't match the IngressController spec.
225-
loadBalancerProgressingTrue := operatorv1.OperatorCondition{
226-
Type: ingress.IngressControllerLoadBalancerProgressingConditionType,
227-
Status: operatorv1.ConditionTrue,
228-
}
229-
if err = waitForIngressControllerCondition(t, kclient, 5*time.Minute, icName, loadBalancerProgressingTrue); err != nil {
230-
t.Fatalf("failed to observe expected conditions: %v", err)
231-
}
256+
// LoadBalancerProgressing should become True because the subnet annotation
257+
// doesn't match the IngressController spec.
258+
loadBalancerProgressingTrue := operatorv1.OperatorCondition{
259+
Type: ingress.IngressControllerLoadBalancerProgressingConditionType,
260+
Status: operatorv1.ConditionTrue,
261+
}
262+
if err = waitForIngressControllerCondition(t, kclient, 5*time.Minute, icName, loadBalancerProgressingTrue); err != nil {
263+
t.Fatalf("failed to observe expected conditions: %v", err)
264+
}
232265

233-
// Verify the subnet annotation didn't get removed.
234-
waitForLBSubnetAnnotation(t, ic, publicSubnets)
266+
// Verify the subnet annotation didn't get removed.
267+
waitForLBSubnetAnnotation(t, ic, publicSubnets)
235268

236-
// Now, update the IngressController to specify the same unmanaged subnets.
237-
t.Logf("updating ingresscontroller %q to specify the subnets in the unmanaged subnets annotation", ic.Name)
238-
if err = updateIngressControllerWithRetryOnConflict(t, icName, 5*time.Minute, func(ic *operatorv1.IngressController) {
239-
ic.Spec.EndpointPublishingStrategy.LoadBalancer = &operatorv1.LoadBalancerStrategy{
240-
Scope: operatorv1.ExternalLoadBalancer,
241-
DNSManagementPolicy: operatorv1.ManagedLoadBalancerDNS,
242-
ProviderParameters: &operatorv1.ProviderLoadBalancerParameters{
243-
Type: operatorv1.AWSLoadBalancerProvider,
244-
AWS: &operatorv1.AWSLoadBalancerParameters{
245-
Type: operatorv1.AWSClassicLoadBalancer,
246-
ClassicLoadBalancerParameters: &operatorv1.AWSClassicLoadBalancerParameters{
269+
// Now, update the IngressController to specify the same unmanaged subnets.
270+
t.Logf("updating ingresscontroller %q to specify the subnets in the unmanaged subnets annotation", ic.Name)
271+
if err = updateIngressControllerWithRetryOnConflict(t, icName, 5*time.Minute, func(ic *operatorv1.IngressController) {
272+
switch tc.lbType {
273+
case operatorv1.AWSNetworkLoadBalancer:
274+
ic.Spec.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.NetworkLoadBalancerParameters = &operatorv1.AWSNetworkLoadBalancerParameters{
247275
Subnets: publicSubnets,
248-
},
249-
},
250-
},
251-
}
252-
}); err != nil {
253-
t.Fatalf("failed to update ingresscontroller: %v", err)
254-
}
276+
}
277+
case operatorv1.AWSClassicLoadBalancer:
278+
ic.Spec.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.ClassicLoadBalancerParameters = &operatorv1.AWSClassicLoadBalancerParameters{
279+
Subnets: publicSubnets,
280+
}
281+
default:
282+
t.Fatalf("unsupported load balancer type: %q", tc.lbType)
283+
}
284+
}); err != nil {
285+
t.Fatalf("failed to update ingresscontroller: %v", err)
286+
}
255287

256-
// The LoadBalancerProgressing=True condition should be resolved and the IngressController should be available.
257-
if err = waitForIngressControllerCondition(t, kclient, 5*time.Minute, icName, availableConditionsForIngressControllerWithLoadBalancer...); err != nil {
258-
t.Fatalf("failed to observe expected conditions: %v", err)
259-
}
288+
// The LoadBalancerProgressing=True condition should be resolved and the IngressController should be available.
289+
if err = waitForIngressControllerCondition(t, kclient, 5*time.Minute, icName, availableNotProgressingConditionsForIngressControllerWithLoadBalancer...); err != nil {
290+
t.Fatalf("failed to observe expected conditions: %v", err)
291+
}
260292

261-
// Verify the subnet annotation is still the same.
262-
waitForLBSubnetAnnotation(t, ic, publicSubnets)
293+
// Verify the subnet annotation is still the same.
294+
waitForLBSubnetAnnotation(t, ic, publicSubnets)
295+
})
296+
}
263297
}
264298

265299
// waitForLBSubnetAnnotation waits for the provided subnets to appear on the LoadBalancer-type service for the
@@ -326,7 +360,7 @@ func verifyIngressControllerSubnetStatus(t *testing.T, icName types.NamespacedNa
326360
if classicLoadBalancerParametersStatusExists(ic) {
327361
subnetStatus = ic.Status.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.ClassicLoadBalancerParameters.Subnets
328362
}
329-
if networkLoadBalancerParametersStatusExist(ic) {
363+
if networkLoadBalancerParametersStatusExist(ic) && ic.Status.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.NetworkLoadBalancerParameters.Subnets != nil {
330364
t.Logf("expected subnets in NetworkLoadBalancerParameters to be nil when LB type is Classic, got: %v, retrying...", ic.Status.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.NetworkLoadBalancerParameters.Subnets)
331365
return false, nil
332366
}
@@ -337,7 +371,7 @@ func verifyIngressControllerSubnetStatus(t *testing.T, icName types.NamespacedNa
337371
if networkLoadBalancerParametersStatusExist(ic) {
338372
subnetStatus = ic.Status.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.NetworkLoadBalancerParameters.Subnets
339373
}
340-
if classicLoadBalancerParametersStatusExists(ic) {
374+
if classicLoadBalancerParametersStatusExists(ic) && ic.Status.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.ClassicLoadBalancerParameters.Subnets != nil {
341375
t.Logf("expected subnets in ClassicLoadBalancerParameters to be nil when LB type is NLB, got: %v, retrying...", ic.Status.EndpointPublishingStrategy.LoadBalancer.ProviderParameters.AWS.ClassicLoadBalancerParameters.Subnets)
342376
return false, nil
343377
}

test/e2e/operator_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ var (
108108
}
109109
// The ingress canary check status condition only applies to the default ingress controller.
110110
defaultAvailableConditions = append(availableConditionsForIngressControllerWithLoadBalancer, operatorv1.OperatorCondition{Type: ingresscontroller.IngressControllerCanaryCheckSuccessConditionType, Status: operatorv1.ConditionTrue})
111+
112+
// IngressController must be Available AND Progressing must also be False.
113+
availableNotProgressingConditionsForIngressControllerWithLoadBalancer = append(availableConditionsForIngressControllerWithLoadBalancer, operatorv1.OperatorCondition{Type: operatorv1.OperatorStatusTypeProgressing, Status: operatorv1.ConditionFalse})
111114
)
112115

113116
var (

0 commit comments

Comments
 (0)