From 3ad303a09965df9e9e1fc52a3baf658a4a35ad24 Mon Sep 17 00:00:00 2001 From: Genevieve L'Esperance Date: Thu, 13 Feb 2020 10:38:48 -0500 Subject: [PATCH] Use elb/elbv2 lb tags to filter. Fixes #100 --- aws/elb/fakes/load_balancers_client.go | 22 ++++++++++++ aws/elb/load_balancer.go | 19 ++++++++++- aws/elb/load_balancer_test.go | 43 ++++++++++++++++++++++-- aws/elb/load_balancers.go | 2 ++ aws/elbv2/fakes/load_balancers_client.go | 22 ++++++++++++ aws/elbv2/load_balancer.go | 19 ++++++++++- aws/elbv2/load_balancer_test.go | 39 +++++++++++++++++++-- aws/elbv2/load_balancers.go | 2 ++ 8 files changed, 161 insertions(+), 7 deletions(-) diff --git a/aws/elb/fakes/load_balancers_client.go b/aws/elb/fakes/load_balancers_client.go index 3642b301..da7c46d7 100644 --- a/aws/elb/fakes/load_balancers_client.go +++ b/aws/elb/fakes/load_balancers_client.go @@ -31,6 +31,18 @@ type LoadBalancersClient struct { } Stub func(*awselb.DescribeLoadBalancersInput) (*awselb.DescribeLoadBalancersOutput, error) } + DescribeTagsCall struct { + sync.Mutex + CallCount int + Receives struct { + DescribeTagsInput *awselb.DescribeTagsInput + } + Returns struct { + DescribeTagsOutput *awselb.DescribeTagsOutput + Error error + } + Stub func(*awselb.DescribeTagsInput) (*awselb.DescribeTagsOutput, error) + } } func (f *LoadBalancersClient) DeleteLoadBalancer(param1 *awselb.DeleteLoadBalancerInput) (*awselb.DeleteLoadBalancerOutput, error) { @@ -53,3 +65,13 @@ func (f *LoadBalancersClient) DescribeLoadBalancers(param1 *awselb.DescribeLoadB } return f.DescribeLoadBalancersCall.Returns.DescribeLoadBalancersOutput, f.DescribeLoadBalancersCall.Returns.Error } +func (f *LoadBalancersClient) DescribeTags(param1 *awselb.DescribeTagsInput) (*awselb.DescribeTagsOutput, error) { + f.DescribeTagsCall.Lock() + defer f.DescribeTagsCall.Unlock() + f.DescribeTagsCall.CallCount++ + f.DescribeTagsCall.Receives.DescribeTagsInput = param1 + if f.DescribeTagsCall.Stub != nil { + return f.DescribeTagsCall.Stub(param1) + } + return f.DescribeTagsCall.Returns.DescribeTagsOutput, f.DescribeTagsCall.Returns.Error +} diff --git a/aws/elb/load_balancer.go b/aws/elb/load_balancer.go index 68b9f06f..09a746c4 100644 --- a/aws/elb/load_balancer.go +++ b/aws/elb/load_balancer.go @@ -2,6 +2,7 @@ package elb import ( "fmt" + "strings" awselb "github.com/aws/aws-sdk-go/service/elb" ) @@ -14,10 +15,26 @@ type LoadBalancer struct { } func NewLoadBalancer(client loadBalancersClient, name *string) LoadBalancer { + identifier := *name + + tagsOutput, err := client.DescribeTags(&awselb.DescribeTagsInput{LoadBalancerNames: []*string{name}}) + if err == nil && tagsOutput != nil && len(tagsOutput.TagDescriptions) == 1 { + tags := tagsOutput.TagDescriptions[0].Tags + + var extra []string + for _, t := range tags { + extra = append(extra, fmt.Sprintf("%s:%s", *t.Key, *t.Value)) + } + + if len(extra) > 0 { + identifier = fmt.Sprintf("%s (%s)", *name, strings.Join(extra, ", ")) + } + } + return LoadBalancer{ client: client, name: name, - identifier: *name, + identifier: identifier, rtype: "ELB Load Balancer", } } diff --git a/aws/elb/load_balancer_test.go b/aws/elb/load_balancer_test.go index 59dd78cd..332212e4 100644 --- a/aws/elb/load_balancer_test.go +++ b/aws/elb/load_balancer_test.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/aws/aws-sdk-go/aws" + awselb "github.com/aws/aws-sdk-go/service/elb" "github.com/genevieve/leftovers/aws/elb" "github.com/genevieve/leftovers/aws/elb/fakes" @@ -13,19 +14,53 @@ import ( var _ = Describe("LoadBalancer", func() { var ( + client *fakes.LoadBalancersClient + name *string + loadBalancer elb.LoadBalancer - client *fakes.LoadBalancersClient - name *string ) BeforeEach(func() { client = &fakes.LoadBalancersClient{} name = aws.String("the-name") + }) + + Describe("NewLoadBalancer", func() { + BeforeEach(func() { + tags := []*awselb.Tag{{Key: aws.String("the-key"), Value: aws.String("the-value")}} + client.DescribeTagsCall.Returns.DescribeTagsOutput = &awselb.DescribeTagsOutput{ + TagDescriptions: []*awselb.TagDescription{{ + LoadBalancerName: name, + Tags: tags, + }}, + } + }) + + It("returns the identifier", func() { + loadBalancer = elb.NewLoadBalancer(client, name) + Expect(client.DescribeTagsCall.CallCount).To(Equal(1)) + Expect(client.DescribeTagsCall.Receives.DescribeTagsInput.LoadBalancerNames[0]).To(Equal(name)) + + Expect(loadBalancer.Name()).To(Equal("the-name (the-key:the-value)")) + }) - loadBalancer = elb.NewLoadBalancer(client, name) + Context("when the describe tags call fails", func() { + BeforeEach(func() { + client.DescribeTagsCall.Returns.Error = errors.New("banana") + }) + + It("ignores it", func() { + loadBalancer = elb.NewLoadBalancer(client, name) + Expect(loadBalancer.Name()).To(Equal("the-name")) + }) + }) }) Describe("Delete", func() { + BeforeEach(func() { + loadBalancer = elb.NewLoadBalancer(client, name) + }) + It("deletes the load balancer", func() { err := loadBalancer.Delete() Expect(err).NotTo(HaveOccurred()) @@ -48,12 +83,14 @@ var _ = Describe("LoadBalancer", func() { Describe("Name", func() { It("returns the identifier", func() { + loadBalancer = elb.NewLoadBalancer(client, name) Expect(loadBalancer.Name()).To(Equal("the-name")) }) }) Describe("Type", func() { It("returns the type", func() { + loadBalancer = elb.NewLoadBalancer(client, name) Expect(loadBalancer.Type()).To(Equal("ELB Load Balancer")) }) }) diff --git a/aws/elb/load_balancers.go b/aws/elb/load_balancers.go index a86a428c..3e8a154c 100644 --- a/aws/elb/load_balancers.go +++ b/aws/elb/load_balancers.go @@ -12,6 +12,8 @@ import ( type loadBalancersClient interface { DescribeLoadBalancers(*awselb.DescribeLoadBalancersInput) (*awselb.DescribeLoadBalancersOutput, error) DeleteLoadBalancer(*awselb.DeleteLoadBalancerInput) (*awselb.DeleteLoadBalancerOutput, error) + + DescribeTags(*awselb.DescribeTagsInput) (*awselb.DescribeTagsOutput, error) } type LoadBalancers struct { diff --git a/aws/elbv2/fakes/load_balancers_client.go b/aws/elbv2/fakes/load_balancers_client.go index 1d5f17c7..2d9b808e 100644 --- a/aws/elbv2/fakes/load_balancers_client.go +++ b/aws/elbv2/fakes/load_balancers_client.go @@ -31,6 +31,18 @@ type LoadBalancersClient struct { } Stub func(*awselbv2.DescribeLoadBalancersInput) (*awselbv2.DescribeLoadBalancersOutput, error) } + DescribeTagsCall struct { + sync.Mutex + CallCount int + Receives struct { + DescribeTagsInput *awselbv2.DescribeTagsInput + } + Returns struct { + DescribeTagsOutput *awselbv2.DescribeTagsOutput + Error error + } + Stub func(*awselbv2.DescribeTagsInput) (*awselbv2.DescribeTagsOutput, error) + } } func (f *LoadBalancersClient) DeleteLoadBalancer(param1 *awselbv2.DeleteLoadBalancerInput) (*awselbv2.DeleteLoadBalancerOutput, error) { @@ -53,3 +65,13 @@ func (f *LoadBalancersClient) DescribeLoadBalancers(param1 *awselbv2.DescribeLoa } return f.DescribeLoadBalancersCall.Returns.DescribeLoadBalancersOutput, f.DescribeLoadBalancersCall.Returns.Error } +func (f *LoadBalancersClient) DescribeTags(param1 *awselbv2.DescribeTagsInput) (*awselbv2.DescribeTagsOutput, error) { + f.DescribeTagsCall.Lock() + defer f.DescribeTagsCall.Unlock() + f.DescribeTagsCall.CallCount++ + f.DescribeTagsCall.Receives.DescribeTagsInput = param1 + if f.DescribeTagsCall.Stub != nil { + return f.DescribeTagsCall.Stub(param1) + } + return f.DescribeTagsCall.Returns.DescribeTagsOutput, f.DescribeTagsCall.Returns.Error +} diff --git a/aws/elbv2/load_balancer.go b/aws/elbv2/load_balancer.go index bf9b877f..0364c403 100644 --- a/aws/elbv2/load_balancer.go +++ b/aws/elbv2/load_balancer.go @@ -2,6 +2,7 @@ package elbv2 import ( "fmt" + "strings" awselbv2 "github.com/aws/aws-sdk-go/service/elbv2" ) @@ -15,11 +16,27 @@ type LoadBalancer struct { } func NewLoadBalancer(client loadBalancersClient, name, arn *string) LoadBalancer { + identifier := *name + + tagsOutput, err := client.DescribeTags(&awselbv2.DescribeTagsInput{ResourceArns: []*string{arn}}) + if err == nil && tagsOutput != nil && len(tagsOutput.TagDescriptions) == 1 { + tags := tagsOutput.TagDescriptions[0].Tags + + var extra []string + for _, t := range tags { + extra = append(extra, fmt.Sprintf("%s:%s", *t.Key, *t.Value)) + } + + if len(extra) > 0 { + identifier = fmt.Sprintf("%s (%s)", *name, strings.Join(extra, ", ")) + } + } + return LoadBalancer{ client: client, name: name, arn: arn, - identifier: *name, + identifier: identifier, rtype: "ELBV2 Load Balancer", } } diff --git a/aws/elbv2/load_balancer_test.go b/aws/elbv2/load_balancer_test.go index a419bbbf..99a7996c 100644 --- a/aws/elbv2/load_balancer_test.go +++ b/aws/elbv2/load_balancer_test.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/aws/aws-sdk-go/aws" + awselbv2 "github.com/aws/aws-sdk-go/service/elbv2" "github.com/genevieve/leftovers/aws/elbv2" "github.com/genevieve/leftovers/aws/elbv2/fakes" @@ -23,11 +24,43 @@ var _ = Describe("LoadBalancer", func() { client = &fakes.LoadBalancersClient{} name = aws.String("the-name") arn = aws.String("the-arn") + }) + + Describe("NewLoadBalancer", func() { + BeforeEach(func() { + tags := []*awselbv2.Tag{{Key: aws.String("the-key"), Value: aws.String("the-value")}} + client.DescribeTagsCall.Returns.DescribeTagsOutput = &awselbv2.DescribeTagsOutput{ + TagDescriptions: []*awselbv2.TagDescription{{ + ResourceArn: arn, + Tags: tags, + }}, + } + }) + + It("returns the identifier", func() { + loadBalancer = elbv2.NewLoadBalancer(client, name, arn) + Expect(client.DescribeTagsCall.CallCount).To(Equal(1)) + Expect(client.DescribeTagsCall.Receives.DescribeTagsInput.ResourceArns[0]).To(Equal(arn)) + + Expect(loadBalancer.Name()).To(Equal("the-name (the-key:the-value)")) + }) - loadBalancer = elbv2.NewLoadBalancer(client, name, arn) + Context("when the describe tags call fails", func() { + BeforeEach(func() { + client.DescribeTagsCall.Returns.Error = errors.New("banana") + }) + + It("ignores it", func() { + loadBalancer = elbv2.NewLoadBalancer(client, name, arn) + Expect(loadBalancer.Name()).To(Equal("the-name")) + }) + }) }) Describe("Delete", func() { + BeforeEach(func() { + loadBalancer = elbv2.NewLoadBalancer(client, name, arn) + }) It("deletes the load balancer", func() { err := loadBalancer.Delete() Expect(err).NotTo(HaveOccurred()) @@ -50,12 +83,14 @@ var _ = Describe("LoadBalancer", func() { Describe("Name", func() { It("returns the identifier", func() { + loadBalancer = elbv2.NewLoadBalancer(client, name, arn) Expect(loadBalancer.Name()).To(Equal("the-name")) }) }) Describe("Type", func() { - It("returns \"load balancer\"", func() { + It("returns load balancer", func() { + loadBalancer = elbv2.NewLoadBalancer(client, name, arn) Expect(loadBalancer.Type()).To(Equal("ELBV2 Load Balancer")) }) }) diff --git a/aws/elbv2/load_balancers.go b/aws/elbv2/load_balancers.go index be3a1e30..7d01df4d 100644 --- a/aws/elbv2/load_balancers.go +++ b/aws/elbv2/load_balancers.go @@ -12,6 +12,8 @@ import ( type loadBalancersClient interface { DescribeLoadBalancers(*awselbv2.DescribeLoadBalancersInput) (*awselbv2.DescribeLoadBalancersOutput, error) DeleteLoadBalancer(*awselbv2.DeleteLoadBalancerInput) (*awselbv2.DeleteLoadBalancerOutput, error) + + DescribeTags(*awselbv2.DescribeTagsInput) (*awselbv2.DescribeTagsOutput, error) } type LoadBalancers struct {