From 6326eb222400251bbbe3f31d1034ba3d1008ae93 Mon Sep 17 00:00:00 2001 From: Will Hegedus Date: Tue, 28 Nov 2023 13:47:31 -0500 Subject: [PATCH] feat: pad nodebalancer backend names Nodebalancers must have a name that is 3-32 characters in length. This adds support to pad the node name if it's too short, since in Kubernetes it's valid to have node names of only 1 or 2 characters. --- cloud/linode/loadbalancers.go | 10 +++++-- cloud/linode/loadbalancers_test.go | 42 ++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index c0b0917e..052569a7 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -601,9 +601,14 @@ func (l *loadbalancers) buildLoadBalancerRequest(ctx context.Context, clusterNam return l.createNodeBalancer(ctx, clusterName, service, configs) } -func trimString(s string, maxLen int) string { +func coerceString(s string, minLen, maxLen int, padding string) string { + if len(padding) == 0 { + padding = "x" + } if len(s) > maxLen { return s[:maxLen] + } else if len(s) < minLen { + return coerceString(fmt.Sprintf("%s%s", padding, s), minLen, maxLen, padding) } return s } @@ -612,7 +617,8 @@ func (l *loadbalancers) buildNodeBalancerNodeCreateOptions(node *v1.Node, nodePo return linodego.NodeBalancerNodeCreateOptions{ Address: fmt.Sprintf("%v:%v", getNodeInternalIP(node), nodePort), // NodeBalancer backends must be 3-32 chars in length - Label: trimString(node.Name, 32), + // If < 3 chars, pad node name with "node-" prefix + Label: coerceString(node.Name, 3, 32, "node-"), Mode: "accept", Weight: 100, } diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index 7620fe68..f4cbe5f6 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -1852,3 +1852,45 @@ func addTLSSecret(t *testing.T, kubeClient kubernetes.Interface) { t.Fatalf("failed to add TLS secret: %s\n", err) } } + +func Test_LoadbalNodeNameCoercion(t *testing.T) { + type testCase struct { + nodeName string + padding string + expectedOutput string + } + testCases := []testCase{ + { + nodeName: "n", + padding: "z", + expectedOutput: "zzn", + }, + { + nodeName: "n", + padding: "node-", + expectedOutput: "node-n", + }, + { + nodeName: "n", + padding: "", + expectedOutput: "xxn", + }, + { + nodeName: "infra-logging-controlplane-3-atl1-us-prod", + padding: "node-", + expectedOutput: "infra-logging-controlplane-3-atl", + }, + { + nodeName: "node1", + padding: "node-", + expectedOutput: "node1", + }, + } + + for _, tc := range testCases { + if out := coerceString(tc.nodeName, 3, 32, tc.padding); out != tc.expectedOutput { + t.Fatalf("Expected loadbal backend name to be %s (got: %s)", tc.expectedOutput, out) + } + } + +}