From 70fd33996ad4bf8286b8bc6c025896b23cfe5417 Mon Sep 17 00:00:00 2001 From: Glenn Pratt Date: Fri, 28 Jun 2024 13:20:12 -0700 Subject: [PATCH] Add option for global NodeBalancer tags --- cloud/linode/cloud.go | 1 + cloud/linode/loadbalancers.go | 2 ++ cloud/linode/loadbalancers_test.go | 37 ++++++++++++++++++++++-------- main.go | 1 + 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/cloud/linode/cloud.go b/cloud/linode/cloud.go index f1138988..3f88ce7b 100644 --- a/cloud/linode/cloud.go +++ b/cloud/linode/cloud.go @@ -37,6 +37,7 @@ var Options struct { VPCName string LoadBalancerType string BGPNodeSelector string + NodeBalancerTags []string } // vpcDetails is set when VPCName options flag is set. diff --git a/cloud/linode/loadbalancers.go b/cloud/linode/loadbalancers.go index 4ff829c7..292768d7 100644 --- a/cloud/linode/loadbalancers.go +++ b/cloud/linode/loadbalancers.go @@ -599,6 +599,8 @@ func (l *loadbalancers) GetLoadBalancerTags(_ context.Context, clusterName strin tags = append(tags, clusterName) } + tags = append(tags, Options.NodeBalancerTags...) + tagStr, ok := service.GetAnnotations()[annotations.AnnLinodeLoadBalancerTags] if ok { return append(tags, strings.Split(tagStr, ",")...) diff --git a/cloud/linode/loadbalancers_test.go b/cloud/linode/loadbalancers_test.go index 806ce25b..c1bdda33 100644 --- a/cloud/linode/loadbalancers_test.go +++ b/cloud/linode/loadbalancers_test.go @@ -150,6 +150,10 @@ func TestCCMLoadBalancers(t *testing.T) { name: "Create Load Balancer With Invalid Firewall ACL - NO Allow Or Deny", f: testCreateNodeBalanceWithNoAllowOrDenyList, }, + { + name: "Create Load Balancer With Global Tags set", + f: testCreateNodeBalancerWithGlobalTags, + }, { name: "Update Load Balancer - Add Node", f: testUpdateLoadBalancerAddNode, @@ -274,7 +278,7 @@ func stubService(fake *fake.Clientset, service *v1.Service) { _, _ = fake.CoreV1().Services("").Create(context.TODO(), service, metav1.CreateOptions{}) } -func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, annMap map[string]string) error { +func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, annMap map[string]string, expectedTags []string) error { svc := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: randString(), @@ -341,7 +345,9 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, a t.Logf("actual: %v", nb.ClientConnThrottle) } - expectedTags := []string{"linodelb", "fake", "test", "yolo"} + if len(expectedTags) == 0 { + expectedTags = []string{"linodelb", "fake", "test", "yolo"} + } if !reflect.DeepEqual(nb.Tags, expectedTags) { t.Error("unexpected Tags") t.Logf("expected: %v", expectedTags) @@ -366,7 +372,7 @@ func testCreateNodeBalancer(t *testing.T, client *linodego.Client, _ *fakeAPI, a } func testCreateNodeBalancerWithOutFirewall(t *testing.T, client *linodego.Client, f *fakeAPI) { - err := testCreateNodeBalancer(t, client, f, nil) + err := testCreateNodeBalancer(t, client, f, nil, nil) if err != nil { t.Fatalf("expected a nil error, got %v", err) } @@ -377,7 +383,7 @@ func testCreateNodeBalanceWithNoAllowOrDenyList(t *testing.T, client *linodego.C annotations.AnnLinodeCloudFirewallACL: `{}`, } - err := testCreateNodeBalancer(t, client, f, annotations) + err := testCreateNodeBalancer(t, client, f, annotations, nil) if err == nil || !stderrors.Is(err, firewall.ErrInvalidFWConfig) { t.Fatalf("expected a %v error, got %v", firewall.ErrInvalidFWConfig, err) } @@ -395,7 +401,7 @@ func testCreateNodeBalanceWithBothAllowOrDenyList(t *testing.T, client *linodego }`, } - err := testCreateNodeBalancer(t, client, f, annotations) + err := testCreateNodeBalancer(t, client, f, annotations, nil) if err == nil || !stderrors.Is(err, firewall.ErrInvalidFWConfig) { t.Fatalf("expected a %v error, got %v", firewall.ErrInvalidFWConfig, err) } @@ -410,7 +416,7 @@ func testCreateNodeBalancerWithAllowList(t *testing.T, client *linodego.Client, }`, } - err := testCreateNodeBalancer(t, client, f, annotations) + err := testCreateNodeBalancer(t, client, f, annotations, nil) if err != nil { t.Fatalf("expected a non-nil error, got %v", err) } @@ -425,7 +431,7 @@ func testCreateNodeBalancerWithDenyList(t *testing.T, client *linodego.Client, f }`, } - err := testCreateNodeBalancer(t, client, f, annotations) + err := testCreateNodeBalancer(t, client, f, annotations, nil) if err != nil { t.Fatalf("expected a non-nil error, got %v", err) } @@ -435,7 +441,7 @@ func testCreateNodeBalancerWithFirewall(t *testing.T, client *linodego.Client, f annotations := map[string]string{ annotations.AnnLinodeCloudFirewallID: "123", } - err := testCreateNodeBalancer(t, client, f, annotations) + err := testCreateNodeBalancer(t, client, f, annotations, nil) if err != nil { t.Fatalf("expected a nil error, got %v", err) } @@ -446,12 +452,25 @@ func testCreateNodeBalancerWithInvalidFirewall(t *testing.T, client *linodego.Cl annotations.AnnLinodeCloudFirewallID: "qwerty", } expectedError := "strconv.Atoi: parsing \"qwerty\": invalid syntax" - err := testCreateNodeBalancer(t, client, f, annotations) + err := testCreateNodeBalancer(t, client, f, annotations, nil) if err.Error() != expectedError { t.Fatalf("expected a %s error, got %v", expectedError, err) } } +func testCreateNodeBalancerWithGlobalTags(t *testing.T, client *linodego.Client, f *fakeAPI) { + original := Options.NodeBalancerTags + defer func() { + Options.NodeBalancerTags = original + }() + Options.NodeBalancerTags = []string{"foobar"} + expectedTags := []string{"linodelb", "foobar", "fake", "test", "yolo"} + err := testCreateNodeBalancer(t, client, f, nil, expectedTags) + if err != nil { + t.Fatalf("expected a nil error, got %v", err) + } +} + func testUpdateLoadBalancerAddNode(t *testing.T, client *linodego.Client, f *fakeAPI) { svc := &v1.Service{ ObjectMeta: metav1.ObjectMeta{ diff --git a/main.go b/main.go index 2e99b10a..a1a505bf 100644 --- a/main.go +++ b/main.go @@ -82,6 +82,7 @@ func main() { command.Flags().StringVar(&linode.Options.VPCName, "vpc-name", "", "vpc name whose routes will be managed by route-controller") command.Flags().StringVar(&linode.Options.LoadBalancerType, "load-balancer-type", "nodebalancer", "configures which type of load-balancing to use for LoadBalancer Services (options: nodebalancer, cilium-bgp)") command.Flags().StringVar(&linode.Options.BGPNodeSelector, "bgp-node-selector", "", "node selector to use to perform shared IP fail-over with BGP (e.g. cilium-bgp-peering=true") + command.Flags().StringSliceVar(&linode.Options.NodeBalancerTags, "nodebalancer-tags", []string{}, "tags to apply to all Nodebalancers") // Set static flags command.Flags().VisitAll(func(fl *pflag.Flag) {