Skip to content

Commit 00ff396

Browse files
authored
Merge pull request #168 from luthermonson/check-move
always return lbnotfound from getNodeBalancerForService
2 parents 3a68362 + 0714d4b commit 00ff396

File tree

4 files changed

+121
-16
lines changed

4 files changed

+121
-16
lines changed

cloud/linode/loadbalancers.go

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,7 @@ func (l *loadbalancers) getNodeBalancerForService(ctx context.Context, service *
7070

7171
if hasIDAnn {
7272
sentry.SetTag(ctx, "load_balancer_id", rawID)
73-
nb, err := l.getNodeBalancerByID(ctx, service, id)
74-
switch err.(type) {
75-
case nil:
76-
return nb, nil
77-
78-
case lbNotFoundError:
79-
return nil, fmt.Errorf("%s annotation points to a NodeBalancer that does not exist: %s", annLinodeNodeBalancerID, err)
80-
81-
default:
82-
return nil, err
83-
}
73+
return l.getNodeBalancerByID(ctx, service, id)
8474
}
8575
return l.getNodeBalancerByStatus(ctx, service)
8676
}
@@ -199,6 +189,13 @@ func (l *loadbalancers) EnsureLoadBalancer(ctx context.Context, clusterName stri
199189
nb, err = l.getNodeBalancerForService(ctx, service)
200190
switch err.(type) {
201191
case lbNotFoundError:
192+
if service.GetAnnotations()[annLinodeNodeBalancerID] != "" {
193+
// a load balancer annotation has been created so a NodeBalancer is coming, error out and retry later
194+
klog.Infof("NodeBalancer created but not available yet, waiting...")
195+
sentry.CaptureError(ctx, err)
196+
return nil, err
197+
}
198+
202199
if nb, err = l.buildLoadBalancerRequest(ctx, clusterName, service, nodes); err != nil {
203200
sentry.CaptureError(ctx, err)
204201
return nil, err

cloud/linode/loadbalancers_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,10 +2123,12 @@ func testGetNodeBalancerForServiceIDDoesNotExist(t *testing.T, client *linodego.
21232123
t.Fatal("expected getNodeBalancerForService to return an error")
21242124
}
21252125

2126-
expectedErr := fmt.Sprintf("%s annotation points to a NodeBalancer that does not exist: LoadBalancer (%s) not found for service (%s)",
2127-
annLinodeNodeBalancerID, bogusNodeBalancerID, getServiceNn(svc))
2128-
2129-
if err.Error() != expectedErr {
2126+
nbid, _ := strconv.Atoi(bogusNodeBalancerID)
2127+
expectedErr := lbNotFoundError{
2128+
serviceNn: getServiceNn(svc),
2129+
nodeBalancerID: nbid,
2130+
}
2131+
if err.Error() != expectedErr.Error() {
21302132
t.Errorf("expected error to be '%s' but got '%s'", expectedErr, err)
21312133
}
21322134
}

e2e/test/ccm_e2e_test.go

Lines changed: 103 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import (
66
"fmt"
77
"os/exec"
88
"strconv"
9+
"time"
10+
11+
"k8s.io/apimachinery/pkg/api/errors"
912

1013
"github.com/linode/linodego"
1114
. "github.com/onsi/ginkgo/v2"
@@ -90,6 +93,14 @@ var _ = Describe("e2e tests", func() {
9093
Eventually(watcher.ResultChan()).Should(Receive(EnsuredService()))
9194
}
9295

96+
ensureServiceWasDeleted := func() {
97+
err := func() error {
98+
_, err := f.LoadBalancer.GetService()
99+
return err
100+
}
101+
Eventually(err).WithTimeout(10 * time.Second).Should(MatchError(errors.IsNotFound, "IsNotFound"))
102+
}
103+
93104
createServiceWithSelector := func(selector map[string]string, ports []core.ServicePort, isSessionAffinityClientIP bool) {
94105
Expect(f.LoadBalancer.CreateService(selector, nil, ports, isSessionAffinityClientIP)).NotTo(HaveOccurred())
95106
Eventually(f.LoadBalancer.GetServiceEndpoints).Should(Not(BeEmpty()))
@@ -942,7 +953,7 @@ var _ = Describe("e2e tests", func() {
942953
By("Creating new NodeBalancer")
943954
nbID := createNodeBalancer()
944955

945-
By("Waiting for currenct NodeBalancer to be ready")
956+
By("Waiting for current NodeBalancer to be ready")
946957
checkNodeBalancerID(framework.TestServerResourceName, nodeBalancerID)
947958

948959
By("Annotating service with new NodeBalancer ID")
@@ -957,6 +968,97 @@ var _ = Describe("e2e tests", func() {
957968
})
958969
})
959970

971+
Context("Deleted Service when NodeBalancer not present", func() {
972+
var (
973+
pods []string
974+
labels map[string]string
975+
annotations map[string]string
976+
servicePorts []core.ServicePort
977+
978+
nodeBalancerID int
979+
)
980+
981+
BeforeEach(func() {
982+
pods = []string{"test-pod-1"}
983+
ports := []core.ContainerPort{
984+
{
985+
Name: "http-1",
986+
ContainerPort: 8080,
987+
},
988+
}
989+
servicePorts = []core.ServicePort{
990+
{
991+
Name: "http-1",
992+
Port: 80,
993+
TargetPort: intstr.FromInt(8080),
994+
Protocol: "TCP",
995+
},
996+
}
997+
998+
labels = map[string]string{
999+
"app": "test-loadbalancer-with-nodebalancer-id",
1000+
}
1001+
1002+
By("Creating NodeBalancer")
1003+
nodeBalancerID = createNodeBalancer()
1004+
1005+
annotations = map[string]string{
1006+
annLinodeNodeBalancerID: strconv.Itoa(nodeBalancerID),
1007+
}
1008+
1009+
By("Creating Pod")
1010+
createPodWithLabel(pods, ports, framework.TestServerImage, labels, false)
1011+
1012+
By("Creating Service")
1013+
createServiceWithAnnotations(labels, annotations, servicePorts, false)
1014+
})
1015+
1016+
AfterEach(func() {
1017+
By("Deleting the Pods")
1018+
deletePods(pods)
1019+
1020+
err := root.Recycle()
1021+
Expect(err).NotTo(HaveOccurred())
1022+
})
1023+
1024+
It("should use the specified NodeBalancer", func() {
1025+
By("Checking the NodeBalancerID")
1026+
checkNodeBalancerID(framework.TestServerResourceName, nodeBalancerID)
1027+
})
1028+
1029+
It("should use the newly specified NodeBalancer ID", func() {
1030+
By("Creating new NodeBalancer")
1031+
nbID := createNodeBalancer()
1032+
1033+
By("Waiting for current NodeBalancer to be ready")
1034+
checkNodeBalancerID(framework.TestServerResourceName, nodeBalancerID)
1035+
1036+
By("Annotating service with new NodeBalancer ID")
1037+
annotations[annLinodeNodeBalancerID] = strconv.Itoa(nbID)
1038+
updateServiceWithAnnotations(labels, annotations, servicePorts, false)
1039+
1040+
By("Checking the NodeBalancer ID")
1041+
checkNodeBalancerID(framework.TestServerResourceName, nbID)
1042+
1043+
By("Checking old NodeBalancer was deleted")
1044+
checkNodeBalancerNotExists(nodeBalancerID)
1045+
})
1046+
1047+
It("should delete the service with no NodeBalancer present", func() {
1048+
By("Deleting the NodeBalancer")
1049+
deleteNodeBalancer(nodeBalancerID)
1050+
1051+
By("Checking old NodeBalancer was deleted")
1052+
checkNodeBalancerNotExists(nodeBalancerID)
1053+
1054+
By("Deleting the Service")
1055+
deleteService()
1056+
1057+
By("Checking if the service was deleted")
1058+
ensureServiceWasDeleted()
1059+
})
1060+
})
1061+
9601062
Context("With Preserve Annotation", func() {
9611063
var (
9621064
pods []string

e2e/test/framework/service.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ func (i *lbInvocation) GetServiceWatcher() (watch.Interface, error) {
6969
return watcher, nil
7070
}
7171

72+
func (i *lbInvocation) GetService() (*core.Service, error) {
73+
return i.kubeClient.CoreV1().Services(i.Namespace()).Get(context.TODO(), TestServerResourceName, metav1.GetOptions{})
74+
}
75+
7276
func (i *lbInvocation) CreateService(selector, annotations map[string]string, ports []core.ServicePort, isSessionAffinityClientIP bool) error {
7377
return i.createOrUpdateService(selector, annotations, ports, isSessionAffinityClientIP, true)
7478
}

0 commit comments

Comments
 (0)