Skip to content

Commit 4899055

Browse files
authored
Fixing the nodebalancer config rebuilds to include ids of preexisting nodebalancer nodes (#192)
Fixing the nodebalancer config rebuilds to include ids of preexisting nodebalancer nodes to avoid rebuilds. + tests + Bumping k8s deps and updating CCM to reflect new API + Fixing node_controller and service_controller due to changes in k8s api. + upgrading toolchain + Bumping CI's go version + Adding build deps/tools to separate file + Refactored client mocks to generate just one file and dropped the two copies which existed due to _test.go in name, that prevents the code to be imported
1 parent b7ecd57 commit 4899055

File tree

16 files changed

+648
-1527
lines changed

16 files changed

+648
-1527
lines changed

cloud/linode/client/client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package client
22

3-
//go:generate go run github.com/golang/mock/mockgen -destination mock_client_test.go -package client github.com/linode/linode-cloud-controller-manager/cloud/linode/client Client
3+
//go:generate go run github.com/golang/mock/mockgen -destination mocks/mock_client.go -package mocks github.com/linode/linode-cloud-controller-manager/cloud/linode/client Client
44

55
import (
66
"context"
@@ -21,6 +21,7 @@ type Client interface {
2121
UpdateNodeBalancer(context.Context, int, linodego.NodeBalancerUpdateOptions) (*linodego.NodeBalancer, error)
2222
DeleteNodeBalancer(context.Context, int) error
2323
ListNodeBalancers(context.Context, *linodego.ListOptions) ([]linodego.NodeBalancer, error)
24+
ListNodeBalancerNodes(context.Context, int, int, *linodego.ListOptions) ([]linodego.NodeBalancerNode, error)
2425

2526
CreateNodeBalancerConfig(context.Context, int, linodego.NodeBalancerConfigCreateOptions) (*linodego.NodeBalancerConfig, error)
2627
DeleteNodeBalancerConfig(context.Context, int, int) error
Lines changed: 17 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cloud/linode/instances_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"testing"
99

1010
"github.com/golang/mock/gomock"
11+
"github.com/linode/linode-cloud-controller-manager/cloud/linode/client/mocks"
1112
"github.com/linode/linodego"
1213
"github.com/stretchr/testify/assert"
1314
v1 "k8s.io/api/core/v1"
@@ -30,7 +31,7 @@ func TestInstanceExists(t *testing.T) {
3031
ctrl := gomock.NewController(t)
3132
defer ctrl.Finish()
3233

33-
client := NewMockClient(ctrl)
34+
client := mocks.NewMockClient(ctrl)
3435

3536
t.Run("should return false if linode does not exist (by providerID)", func(t *testing.T) {
3637
instances := newInstances(client)
@@ -90,7 +91,7 @@ func TestMetadataRetrieval(t *testing.T) {
9091
ctrl := gomock.NewController(t)
9192
defer ctrl.Finish()
9293

93-
client := NewMockClient(ctrl)
94+
client := mocks.NewMockClient(ctrl)
9495

9596
t.Run("errors when linode does not exist (by name)", func(t *testing.T) {
9697
instances := newInstances(client)
@@ -231,7 +232,7 @@ func TestMalformedProviders(t *testing.T) {
231232
ctrl := gomock.NewController(t)
232233
defer ctrl.Finish()
233234

234-
client := NewMockClient(ctrl)
235+
client := mocks.NewMockClient(ctrl)
235236

236237
t.Run("fails on non-numeric providerID", func(t *testing.T) {
237238
instances := newInstances(client)
@@ -250,7 +251,7 @@ func TestInstanceShutdown(t *testing.T) {
250251
ctrl := gomock.NewController(t)
251252
defer ctrl.Finish()
252253

253-
client := NewMockClient(ctrl)
254+
client := mocks.NewMockClient(ctrl)
254255

255256
t.Run("fails when instance not found (by provider)", func(t *testing.T) {
256257
instances := newInstances(client)

cloud/linode/loadbalancers.go

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -296,12 +296,6 @@ func (l *loadbalancers) updateNodeBalancer(
296296
return err
297297
}
298298

299-
// Add all of the Nodes to the config
300-
var newNBNodes []linodego.NodeBalancerNodeCreateOptions
301-
for _, node := range nodes {
302-
newNBNodes = append(newNBNodes, l.buildNodeBalancerNodeCreateOptions(node, port.NodePort))
303-
}
304-
305299
// Look for an existing config for this port
306300
var currentNBCfg *linodego.NodeBalancerConfig
307301
for i := range nbCfgs {
@@ -311,6 +305,34 @@ func (l *loadbalancers) updateNodeBalancer(
311305
break
312306
}
313307
}
308+
oldNBNodeIDs := make(map[string]int)
309+
if currentNBCfg != nil {
310+
// Obtain list of current NB nodes and convert it to map of node IDs
311+
currentNBNodes, err := l.client.ListNodeBalancerNodes(ctx, nb.ID, currentNBCfg.ID, nil)
312+
if err != nil {
313+
// This error can be ignored, because if we fail to get nodes we can anyway rebuild the config from scratch,
314+
// it would just cause the NB to reload config even if the node list did not change, so we prefer to send IDs when it is posible.
315+
klog.Warningf("Unable to list existing nodebalancer nodes for NB %d config %d, error: %s", nb.ID, newNBCfg.ID, err)
316+
}
317+
for _, node := range currentNBNodes {
318+
oldNBNodeIDs[node.Address] = node.ID
319+
}
320+
klog.Infof("Nodebalancer %d had nodes %v", nb.ID, oldNBNodeIDs)
321+
} else {
322+
klog.Infof("No preexisting nodebalancer for port %v found.", port.Port)
323+
}
324+
// Add all of the Nodes to the config
325+
newNBNodes := make([]linodego.NodeBalancerConfigRebuildNodeOptions, 0, len(nodes))
326+
for _, node := range nodes {
327+
newNodeOpts := l.buildNodeBalancerNodeConfigRebuildOptions(node, port.NodePort)
328+
oldNodeID, ok := oldNBNodeIDs[newNodeOpts.Address]
329+
if ok {
330+
newNodeOpts.ID = oldNodeID
331+
} else {
332+
klog.Infof("No preexisting node id for %v found.", newNodeOpts.Address)
333+
}
334+
newNBNodes = append(newNBNodes, newNodeOpts)
335+
}
314336

315337
// If there's no existing config, create it
316338
var rebuildOpts linodego.NodeBalancerConfigRebuildOptions
@@ -652,7 +674,7 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam
652674
createOpt := config.GetCreateOptions()
653675

654676
for _, n := range nodes {
655-
createOpt.Nodes = append(createOpt.Nodes, l.buildNodeBalancerNodeCreateOptions(n, port.NodePort))
677+
createOpt.Nodes = append(createOpt.Nodes, l.buildNodeBalancerNodeConfigRebuildOptions(n, port.NodePort).NodeBalancerNodeCreateOptions)
656678
}
657679

658680
configs = append(configs, &createOpt)
@@ -672,14 +694,16 @@ func coerceString(s string, minLen, maxLen int, padding string) string {
672694
return s
673695
}
674696

675-
func (l *loadbalancers) buildNodeBalancerNodeCreateOptions(node *v1.Node, nodePort int32) linodego.NodeBalancerNodeCreateOptions {
676-
return linodego.NodeBalancerNodeCreateOptions{
677-
Address: fmt.Sprintf("%v:%v", getNodePrivateIP(node), nodePort),
678-
// NodeBalancer backends must be 3-32 chars in length
679-
// If < 3 chars, pad node name with "node-" prefix
680-
Label: coerceString(node.Name, 3, 32, "node-"),
681-
Mode: "accept",
682-
Weight: 100,
697+
func (l *loadbalancers) buildNodeBalancerNodeConfigRebuildOptions(node *v1.Node, nodePort int32) linodego.NodeBalancerConfigRebuildNodeOptions {
698+
return linodego.NodeBalancerConfigRebuildNodeOptions{
699+
NodeBalancerNodeCreateOptions: linodego.NodeBalancerNodeCreateOptions{
700+
Address: fmt.Sprintf("%v:%v", getNodePrivateIP(node), nodePort),
701+
// NodeBalancer backends must be 3-32 chars in length
702+
// If < 3 chars, pad node name with "node-" prefix
703+
Label: coerceString(node.Name, 3, 32, "node-"),
704+
Mode: "accept",
705+
Weight: 100,
706+
},
683707
}
684708
}
685709

0 commit comments

Comments
 (0)