Skip to content

Commit 25689d1

Browse files
committed
Error when node has no internal IP for nodebalancer backend
1 parent bc67c49 commit 25689d1

2 files changed

Lines changed: 70 additions & 12 deletions

File tree

cloud/linode/loadbalancers.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,11 @@ func (l *loadbalancers) updateNodeBalancer(
402402
subnetID = id
403403
}
404404
for _, node := range nodes {
405-
newNodeOpts := l.buildNodeBalancerNodeConfigRebuildOptions(node, port.NodePort, subnetID)
405+
newNodeOpts, err := l.buildNodeBalancerNodeConfigRebuildOptions(node, port.NodePort, subnetID)
406+
if err != nil {
407+
return err
408+
}
409+
406410
oldNodeID, ok := oldNBNodeIDs[newNodeOpts.Address]
407411
if ok {
408412
newNodeOpts.ID = oldNodeID
@@ -857,7 +861,12 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam
857861
createOpt := config.GetCreateOptions()
858862

859863
for _, n := range nodes {
860-
createOpt.Nodes = append(createOpt.Nodes, l.buildNodeBalancerNodeConfigRebuildOptions(n, port.NodePort, subnetID).NodeBalancerNodeCreateOptions)
864+
opts, err := l.buildNodeBalancerNodeConfigRebuildOptions(n, port.NodePort, subnetID)
865+
if err != nil {
866+
return nil, fmt.Errorf("error creating NodeBalancer config: %w", err)
867+
}
868+
869+
createOpt.Nodes = append(createOpt.Nodes, opts.NodeBalancerNodeCreateOptions)
861870
}
862871

863872
configs = append(configs, &createOpt)
@@ -877,10 +886,14 @@ func coerceString(str string, minLen, maxLen int, padding string) string {
877886
return str
878887
}
879888

880-
func (l *loadbalancers) buildNodeBalancerNodeConfigRebuildOptions(node *v1.Node, nodePort int32, subnetID int) linodego.NodeBalancerConfigRebuildNodeOptions {
889+
func (l *loadbalancers) buildNodeBalancerNodeConfigRebuildOptions(node *v1.Node, nodePort int32, subnetID int) (linodego.NodeBalancerConfigRebuildNodeOptions, error) {
890+
privateIP, err := getNodePrivateIP(node, subnetID)
891+
if err != nil {
892+
return linodego.NodeBalancerConfigRebuildNodeOptions{}, err
893+
}
881894
nodeOptions := linodego.NodeBalancerConfigRebuildNodeOptions{
882895
NodeBalancerNodeCreateOptions: linodego.NodeBalancerNodeCreateOptions{
883-
Address: fmt.Sprintf("%v:%v", getNodePrivateIP(node, subnetID), nodePort),
896+
Address: fmt.Sprintf("%v:%v", privateIP, nodePort),
884897
// NodeBalancer backends must be 3-32 chars in length
885898
// If < 3 chars, pad node name with "node-" prefix
886899
Label: coerceString(node.Name, 3, 32, "node-"),
@@ -891,7 +904,7 @@ func (l *loadbalancers) buildNodeBalancerNodeConfigRebuildOptions(node *v1.Node,
891904
if subnetID != 0 {
892905
nodeOptions.NodeBalancerNodeCreateOptions.SubnetID = subnetID
893906
}
894-
return nodeOptions
907+
return nodeOptions, nil
895908
}
896909

897910
func (l *loadbalancers) retrieveKubeClient() error {
@@ -1004,20 +1017,20 @@ func getPortConfigAnnotation(service *v1.Service, port int) (portConfigAnnotatio
10041017
// For services which don't have NodeBalancerBackendIPv4Range annotation,
10051018
// Backend IP can be overwritten to the one specified using AnnLinodeNodePrivateIP
10061019
// annotation over the NodeInternalIP.
1007-
func getNodePrivateIP(node *v1.Node, subnetID int) string {
1020+
func getNodePrivateIP(node *v1.Node, subnetID int) (string, error) {
10081021
if subnetID == 0 {
10091022
if address, exists := node.Annotations[annotations.AnnLinodeNodePrivateIP]; exists {
1010-
return address
1023+
return address, nil
10111024
}
10121025
}
10131026

10141027
klog.Infof("Node %s, assigned IP addresses: %v", node.Name, node.Status.Addresses)
10151028
for _, addr := range node.Status.Addresses {
10161029
if addr.Type == v1.NodeInternalIP {
1017-
return addr.Address
1030+
return addr.Address, nil
10181031
}
10191032
}
1020-
return ""
1033+
return "", fmt.Errorf("node %s has no internal IP or %s annotation", node.Name, annotations.AnnLinodeNodePrivateIP)
10211034
}
10221035

10231036
func getTLSCertInfo(ctx context.Context, kubeClient kubernetes.Interface, namespace string, config portConfig) (string, string, error) {

cloud/linode/loadbalancers_test.go

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,19 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, a
339339
t.Error("type assertion failed")
340340
}
341341
nodes := []*v1.Node{
342-
{ObjectMeta: metav1.ObjectMeta{Name: "node-1"}},
342+
{
343+
ObjectMeta: metav1.ObjectMeta{
344+
Name: "node-1",
345+
},
346+
Status: v1.NodeStatus{
347+
Addresses: []v1.NodeAddress{
348+
{
349+
Type: v1.NodeInternalIP,
350+
Address: "10.0.1.1",
351+
},
352+
},
353+
},
354+
},
343355
}
344356
nb, err := lb.buildLoadBalancerRequest(t.Context(), "linodelb", svc, nodes)
345357
if err != nil {
@@ -2949,6 +2961,7 @@ func Test_getNodePrivateIP(t *testing.T) {
29492961
node *v1.Node
29502962
address string
29512963
subnetID int
2964+
err error
29522965
}{
29532966
{
29542967
"node internal ip specified",
@@ -2964,6 +2977,7 @@ func Test_getNodePrivateIP(t *testing.T) {
29642977
},
29652978
"127.0.0.1",
29662979
0,
2980+
nil,
29672981
},
29682982
{
29692983
"node internal ip not specified",
@@ -2979,6 +2993,7 @@ func Test_getNodePrivateIP(t *testing.T) {
29792993
},
29802994
"",
29812995
0,
2996+
fmt.Errorf("node has no internal IP or %s annotation", annotations.AnnLinodeNodePrivateIP),
29822997
},
29832998
{
29842999
"node internal ip annotation present",
@@ -2999,6 +3014,7 @@ func Test_getNodePrivateIP(t *testing.T) {
29993014
},
30003015
"192.168.42.42",
30013016
0,
3017+
nil,
30023018
},
30033019
{
30043020
"node internal ip annotation present and subnet id is not zero",
@@ -3019,13 +3035,18 @@ func Test_getNodePrivateIP(t *testing.T) {
30193035
},
30203036
"10.0.1.1",
30213037
100,
3038+
nil,
30223039
},
30233040
}
30243041

30253042
for _, test := range testcases {
30263043
t.Run(test.name, func(t *testing.T) {
3027-
ip := getNodePrivateIP(test.node, test.subnetID)
3028-
if ip != test.address {
3044+
ip, err := getNodePrivateIP(test.node, test.subnetID)
3045+
if !reflect.DeepEqual(err, test.err) {
3046+
t.Error("unexpected error")
3047+
t.Logf("expected: %v", test.err)
3048+
t.Logf("actual: %v", err)
3049+
} else if ip != test.address {
30293050
t.Error("unexpected certificate")
30303051
t.Logf("expected: %q", test.address)
30313052
t.Logf("actual: %q", ip)
@@ -3061,16 +3082,40 @@ func testBuildLoadBalancerRequest(t *testing.T, client *linodego.Client, _ *fake
30613082
ObjectMeta: metav1.ObjectMeta{
30623083
Name: "node-1",
30633084
},
3085+
Status: v1.NodeStatus{
3086+
Addresses: []v1.NodeAddress{
3087+
{
3088+
Type: v1.NodeInternalIP,
3089+
Address: "10.0.1.1",
3090+
},
3091+
},
3092+
},
30643093
},
30653094
{
30663095
ObjectMeta: metav1.ObjectMeta{
30673096
Name: "node-2",
30683097
},
3098+
Status: v1.NodeStatus{
3099+
Addresses: []v1.NodeAddress{
3100+
{
3101+
Type: v1.NodeInternalIP,
3102+
Address: "10.0.1.2",
3103+
},
3104+
},
3105+
},
30693106
},
30703107
{
30713108
ObjectMeta: metav1.ObjectMeta{
30723109
Name: "node-3",
30733110
},
3111+
Status: v1.NodeStatus{
3112+
Addresses: []v1.NodeAddress{
3113+
{
3114+
Type: v1.NodeInternalIP,
3115+
Address: "10.0.1.3",
3116+
},
3117+
},
3118+
},
30743119
},
30753120
}
30763121

0 commit comments

Comments
 (0)