From b1596b563e1926c0f1e757e31a0a2e5df01b1559 Mon Sep 17 00:00:00 2001 From: Peter Rifel Date: Fri, 29 Mar 2024 22:21:58 -0500 Subject: [PATCH] Migrate elbv2 to aws-sdk-go-v2 --- cloudmock/aws/mockelbv2/api.go | 18 +-- cloudmock/aws/mockelbv2/listeners.go | 42 +++---- cloudmock/aws/mockelbv2/loadbalancers.go | 94 +++++++-------- cloudmock/aws/mockelbv2/tags.go | 32 +++-- cloudmock/aws/mockelbv2/targetgroups.go | 60 ++++------ pkg/model/awsmodel/api_loadbalancer.go | 37 +++--- pkg/model/awsmodel/bastion.go | 22 ++-- pkg/resources/aws/aws.go | 15 ++- pkg/testutils/integrationtestharness.go | 8 +- .../cloudup/awstasks/network_load_balancer.go | 109 +++++++++--------- .../networkloadbalancer_attributes.go | 28 +++-- .../awstasks/networkloadbalancerlistener.go | 63 +++++----- upup/pkg/fi/cloudup/awstasks/targetgroup.go | 85 +++++++------- upup/pkg/fi/cloudup/awsup/aws_cloud.go | 76 ++++++------ upup/pkg/fi/cloudup/awsup/aws_utils.go | 10 +- .../fi/cloudup/awsup/elbv2_loadbalancers.go | 52 ++++----- .../fi/cloudup/awsup/elbv2_targetgroups.go | 46 +++----- upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go | 9 +- util/pkg/awsinterfaces/elbv2.go | 47 ++++++++ 19 files changed, 430 insertions(+), 423 deletions(-) create mode 100644 util/pkg/awsinterfaces/elbv2.go diff --git a/cloudmock/aws/mockelbv2/api.go b/cloudmock/aws/mockelbv2/api.go index 290280e136eac..6296b53df9037 100644 --- a/cloudmock/aws/mockelbv2/api.go +++ b/cloudmock/aws/mockelbv2/api.go @@ -20,13 +20,13 @@ import ( "sync" "k8s.io/kops/cloudmock/aws/mockec2" + "k8s.io/kops/util/pkg/awsinterfaces" - "github.com/aws/aws-sdk-go/service/elbv2" - "github.com/aws/aws-sdk-go/service/elbv2/elbv2iface" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" ) type MockELBV2 struct { - elbv2iface.ELBV2API + awsinterfaces.ELBV2API mutex sync.Mutex @@ -37,20 +37,20 @@ type MockELBV2 struct { tgCount int Listeners map[string]*listener listenerCount int - LBAttributes map[string][]*elbv2.LoadBalancerAttribute + LBAttributes map[string][]elbv2types.LoadBalancerAttribute - Tags map[string]*elbv2.TagDescription + Tags map[string]elbv2types.TagDescription } type loadBalancer struct { - description elbv2.LoadBalancer + description elbv2types.LoadBalancer } type targetGroup struct { - description elbv2.TargetGroup - attributes []*elbv2.TargetGroupAttribute + description elbv2types.TargetGroup + attributes []elbv2types.TargetGroupAttribute } type listener struct { - description elbv2.Listener + description elbv2types.Listener } diff --git a/cloudmock/aws/mockelbv2/listeners.go b/cloudmock/aws/mockelbv2/listeners.go index 89fbfc7303c13..a4a0e54f0ccc7 100644 --- a/cloudmock/aws/mockelbv2/listeners.go +++ b/cloudmock/aws/mockelbv2/listeners.go @@ -17,47 +17,47 @@ limitations under the License. package mockelbv2 import ( + "context" "fmt" "strings" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" ) -func (m *MockELBV2) DescribeListenersPagesWithContext(ctx aws.Context, request *elbv2.DescribeListenersInput, callback func(*elbv2.DescribeListenersOutput, bool) bool, options ...request.Option) error { +func (m *MockELBV2) DescribeListeners(ctx context.Context, request *elbv2.DescribeListenersInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeListenersOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DescribeListenersPagesWithContext v2 %v", request) page := &elbv2.DescribeListenersOutput{ - Listeners: make([]*elbv2.Listener, 0), + Listeners: make([]elbv2types.Listener, 0), } for _, l := range m.Listeners { listener := l.description - if aws.StringValue(request.LoadBalancerArn) == aws.StringValue(listener.LoadBalancerArn) { - page.Listeners = append(page.Listeners, &listener) + if aws.ToString(request.LoadBalancerArn) == aws.ToString(listener.LoadBalancerArn) { + page.Listeners = append(page.Listeners, listener) } else { for _, reqARN := range request.ListenerArns { - if aws.StringValue(reqARN) == aws.StringValue(listener.ListenerArn) { - page.Listeners = append(page.Listeners, &listener) + if reqARN == aws.ToString(listener.ListenerArn) { + page.Listeners = append(page.Listeners, listener) } } } } - callback(page, true) - return nil + return page, nil } -func (m *MockELBV2) CreateListenerWithContext(ctx aws.Context, request *elbv2.CreateListenerInput, opts ...request.Option) (*elbv2.CreateListenerOutput, error) { +func (m *MockELBV2) CreateListener(ctx context.Context, request *elbv2.CreateListenerInput, optFns ...func(*elbv2.Options)) (*elbv2.CreateListenerOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("CreateListenerWithContext v2 %v", request) - l := elbv2.Listener{ + l := elbv2types.Listener{ DefaultActions: request.DefaultActions, LoadBalancerArn: request.LoadBalancerArn, Port: request.Port, @@ -66,9 +66,9 @@ func (m *MockELBV2) CreateListenerWithContext(ctx aws.Context, request *elbv2.Cr SslPolicy: request.SslPolicy, } - lbARN := aws.StringValue(request.LoadBalancerArn) + lbARN := aws.ToString(request.LoadBalancerArn) if _, ok := m.LoadBalancers[lbARN]; !ok { - return nil, fmt.Errorf("LoadBalancerArn not found %v", aws.StringValue(request.LoadBalancerArn)) + return nil, fmt.Errorf("LoadBalancerArn not found %v", aws.ToString(request.LoadBalancerArn)) } m.listenerCount++ @@ -79,32 +79,32 @@ func (m *MockELBV2) CreateListenerWithContext(ctx aws.Context, request *elbv2.Cr m.Listeners = make(map[string]*listener) } - tgARN := aws.StringValue(l.DefaultActions[0].TargetGroupArn) + tgARN := aws.ToString(l.DefaultActions[0].TargetGroupArn) if _, ok := m.TargetGroups[tgARN]; ok { found := false for _, lb := range m.TargetGroups[tgARN].description.LoadBalancerArns { - if aws.StringValue(lb) == lbARN { + if lb == lbARN { found = true break } } if !found { - m.TargetGroups[tgARN].description.LoadBalancerArns = append(m.TargetGroups[tgARN].description.LoadBalancerArns, aws.String(lbARN)) + m.TargetGroups[tgARN].description.LoadBalancerArns = append(m.TargetGroups[tgARN].description.LoadBalancerArns, lbARN) } } m.Listeners[arn] = &listener{description: l} - return &elbv2.CreateListenerOutput{Listeners: []*elbv2.Listener{&l}}, nil + return &elbv2.CreateListenerOutput{Listeners: []elbv2types.Listener{l}}, nil } -func (m *MockELBV2) DeleteListenerWithContext(ctx aws.Context, request *elbv2.DeleteListenerInput, opts ...request.Option) (*elbv2.DeleteListenerOutput, error) { +func (m *MockELBV2) DeleteListener(ctx context.Context, request *elbv2.DeleteListenerInput, optFns ...func(*elbv2.Options)) (*elbv2.DeleteListenerOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DeleteListenerWithContext v2 %v", request) - lARN := aws.StringValue(request.ListenerArn) + lARN := aws.ToString(request.ListenerArn) if _, ok := m.Listeners[lARN]; !ok { return nil, fmt.Errorf("Listener not found %v", lARN) } diff --git a/cloudmock/aws/mockelbv2/loadbalancers.go b/cloudmock/aws/mockelbv2/loadbalancers.go index ea9ecc5c9bd66..93426e047c717 100644 --- a/cloudmock/aws/mockelbv2/loadbalancers.go +++ b/cloudmock/aws/mockelbv2/loadbalancers.go @@ -20,14 +20,14 @@ import ( "context" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/aws/aws-sdk-go/service/elbv2" "k8s.io/klog/v2" ) -func (m *MockELBV2) DescribeLoadBalancers(request *elbv2.DescribeLoadBalancersInput) (*elbv2.DescribeLoadBalancersOutput, error) { +func (m *MockELBV2) DescribeLoadBalancers(ctx context.Context, request *elbv2.DescribeLoadBalancersInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeLoadBalancersOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() @@ -40,13 +40,13 @@ func (m *MockELBV2) DescribeLoadBalancers(request *elbv2.DescribeLoadBalancersIn klog.Fatalf("Marker not implemented") } - var elbs []*elbv2.LoadBalancer + var elbs []elbv2types.LoadBalancer for _, elb := range m.LoadBalancers { match := false if len(request.LoadBalancerArns) > 0 { for _, name := range request.LoadBalancerArns { - if aws.StringValue(elb.description.LoadBalancerArn) == aws.StringValue(name) { + if aws.ToString(elb.description.LoadBalancerArn) == name { match = true } } @@ -55,7 +55,7 @@ func (m *MockELBV2) DescribeLoadBalancers(request *elbv2.DescribeLoadBalancersIn } if match { - elbs = append(elbs, &elb.description) + elbs = append(elbs, elb.description) } } @@ -64,59 +64,43 @@ func (m *MockELBV2) DescribeLoadBalancers(request *elbv2.DescribeLoadBalancersIn }, nil } -func (m *MockELBV2) DescribeLoadBalancersPages(request *elbv2.DescribeLoadBalancersInput, callback func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool)) error { - // For the mock, we just send everything in one page - page, err := m.DescribeLoadBalancers(request) - if err != nil { - return err - } - - callback(page, false) - - return nil -} - -func (m *MockELBV2) DescribeLoadBalancersPagesWithContext(ctx context.Context, request *elbv2.DescribeLoadBalancersInput, callback func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool), opts ...request.Option) error { - return m.DescribeLoadBalancersPages(request, callback) -} - -func (m *MockELBV2) CreateLoadBalancer(request *elbv2.CreateLoadBalancerInput) (*elbv2.CreateLoadBalancerOutput, error) { +func (m *MockELBV2) CreateLoadBalancer(ctx context.Context, request *elbv2.CreateLoadBalancerInput, optFns ...func(*elbv2.Options)) (*elbv2.CreateLoadBalancerOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("CreateLoadBalancer v2 %v", request) - lb := elbv2.LoadBalancer{ + lb := elbv2types.LoadBalancer{ LoadBalancerName: request.Name, Scheme: request.Scheme, SecurityGroups: request.SecurityGroups, Type: request.Type, IpAddressType: request.IpAddressType, - DNSName: aws.String(fmt.Sprintf("%v.amazonaws.com", aws.StringValue(request.Name))), + DNSName: aws.String(fmt.Sprintf("%v.amazonaws.com", aws.ToString(request.Name))), CanonicalHostedZoneId: aws.String("HZ123456"), } - zones := make([]*elbv2.AvailabilityZone, 0) + zones := make([]elbv2types.AvailabilityZone, 0) vpc := "vpc-1" for _, subnet := range request.Subnets { - zones = append(zones, &elbv2.AvailabilityZone{ - SubnetId: subnet, + zones = append(zones, elbv2types.AvailabilityZone{ + SubnetId: aws.String(subnet), }) subnetsOutput, err := m.EC2.DescribeSubnets(&ec2.DescribeSubnetsInput{ - SubnetIds: []*string{subnet}, + SubnetIds: []*string{aws.String(subnet)}, }) if err == nil { vpc = *subnetsOutput.Subnets[0].VpcId } } for _, subnetMapping := range request.SubnetMappings { - var lbAddrs []*elbv2.LoadBalancerAddress + var lbAddrs []elbv2types.LoadBalancerAddress if subnetMapping.PrivateIPv4Address != nil { - lbAddrs = append(lbAddrs, &elbv2.LoadBalancerAddress{PrivateIPv4Address: subnetMapping.PrivateIPv4Address}) + lbAddrs = append(lbAddrs, elbv2types.LoadBalancerAddress{PrivateIPv4Address: subnetMapping.PrivateIPv4Address}) } if subnetMapping.AllocationId != nil { - lbAddrs = append(lbAddrs, &elbv2.LoadBalancerAddress{AllocationId: subnetMapping.AllocationId}) + lbAddrs = append(lbAddrs, elbv2types.LoadBalancerAddress{AllocationId: subnetMapping.AllocationId}) } - zones = append(zones, &elbv2.AvailabilityZone{ + zones = append(zones, elbv2types.AvailabilityZone{ SubnetId: subnetMapping.SubnetId, LoadBalancerAddresses: lbAddrs, }) @@ -132,7 +116,7 @@ func (m *MockELBV2) CreateLoadBalancer(request *elbv2.CreateLoadBalancerInput) ( lb.VpcId = aws.String(vpc) m.lbCount++ - arn := fmt.Sprintf("arn:aws-test:elasticloadbalancing:us-test-1:000000000000:loadbalancer/net/%v/%v", aws.StringValue(request.Name), m.lbCount) + arn := fmt.Sprintf("arn:aws-test:elasticloadbalancing:us-test-1:000000000000:loadbalancer/net/%v/%v", aws.ToString(request.Name), m.lbCount) lb.LoadBalancerArn = aws.String(arn) @@ -140,52 +124,52 @@ func (m *MockELBV2) CreateLoadBalancer(request *elbv2.CreateLoadBalancerInput) ( m.LoadBalancers = make(map[string]*loadBalancer) } if m.LBAttributes == nil { - m.LBAttributes = make(map[string][]*elbv2.LoadBalancerAttribute) + m.LBAttributes = make(map[string][]elbv2types.LoadBalancerAttribute) } if m.Tags == nil { - m.Tags = make(map[string]*elbv2.TagDescription) + m.Tags = make(map[string]elbv2types.TagDescription) } m.LoadBalancers[arn] = &loadBalancer{description: lb} - m.LBAttributes[arn] = make([]*elbv2.LoadBalancerAttribute, 0) - m.Tags[arn] = &elbv2.TagDescription{ + m.LBAttributes[arn] = make([]elbv2types.LoadBalancerAttribute, 0) + m.Tags[arn] = elbv2types.TagDescription{ ResourceArn: aws.String(arn), Tags: request.Tags, } - return &elbv2.CreateLoadBalancerOutput{LoadBalancers: []*elbv2.LoadBalancer{&lb}}, nil + return &elbv2.CreateLoadBalancerOutput{LoadBalancers: []elbv2types.LoadBalancer{lb}}, nil } -func (m *MockELBV2) DescribeLoadBalancerAttributes(request *elbv2.DescribeLoadBalancerAttributesInput) (*elbv2.DescribeLoadBalancerAttributesOutput, error) { +func (m *MockELBV2) DescribeLoadBalancerAttributes(ctx context.Context, request *elbv2.DescribeLoadBalancerAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeLoadBalancerAttributesOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DescribeLoadBalancerAttributes v2 %v", request) - if attr, ok := m.LBAttributes[aws.StringValue(request.LoadBalancerArn)]; ok { + if attr, ok := m.LBAttributes[aws.ToString(request.LoadBalancerArn)]; ok { return &elbv2.DescribeLoadBalancerAttributesOutput{ Attributes: attr, }, nil } - return nil, fmt.Errorf("LoadBalancerNotFound: %v", aws.StringValue(request.LoadBalancerArn)) + return nil, fmt.Errorf("LoadBalancerNotFound: %v", aws.ToString(request.LoadBalancerArn)) } -func (m *MockELBV2) ModifyLoadBalancerAttributes(request *elbv2.ModifyLoadBalancerAttributesInput) (*elbv2.ModifyLoadBalancerAttributesOutput, error) { +func (m *MockELBV2) ModifyLoadBalancerAttributes(ctx context.Context, request *elbv2.ModifyLoadBalancerAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.ModifyLoadBalancerAttributesOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("ModifyLoadBalancerAttributes v2 %v", request) if m.LBAttributes == nil { - m.LBAttributes = make(map[string][]*elbv2.LoadBalancerAttribute) + m.LBAttributes = make(map[string][]elbv2types.LoadBalancerAttribute) } - arn := aws.StringValue(request.LoadBalancerArn) + arn := aws.ToString(request.LoadBalancerArn) if _, ok := m.LBAttributes[arn]; ok { for _, reqAttr := range request.Attributes { found := false for _, lbAttr := range m.LBAttributes[arn] { - if aws.StringValue(reqAttr.Key) == aws.StringValue(lbAttr.Key) { + if aws.ToString(reqAttr.Key) == aws.ToString(lbAttr.Key) { lbAttr.Value = reqAttr.Value found = true } @@ -198,39 +182,39 @@ func (m *MockELBV2) ModifyLoadBalancerAttributes(request *elbv2.ModifyLoadBalanc Attributes: m.LBAttributes[arn], }, nil } - return nil, fmt.Errorf("LoadBalancerNotFound: %v", aws.StringValue(request.LoadBalancerArn)) + return nil, fmt.Errorf("LoadBalancerNotFound: %v", aws.ToString(request.LoadBalancerArn)) } -func (m *MockELBV2) SetSecurityGroups(request *elbv2.SetSecurityGroupsInput) (*elbv2.SetSecurityGroupsOutput, error) { +func (m *MockELBV2) SetSecurityGroups(ctx context.Context, request *elbv2.SetSecurityGroupsInput, optFns ...func(*elbv2.Options)) (*elbv2.SetSecurityGroupsOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() - arn := aws.StringValue(request.LoadBalancerArn) + arn := aws.ToString(request.LoadBalancerArn) if lb, ok := m.LoadBalancers[arn]; ok { lb.description.SecurityGroups = request.SecurityGroups return &elbv2.SetSecurityGroupsOutput{ SecurityGroupIds: request.SecurityGroups, }, nil } - return nil, fmt.Errorf("LoadBalancerNotFound: %v", aws.StringValue(request.LoadBalancerArn)) + return nil, fmt.Errorf("LoadBalancerNotFound: %v", aws.ToString(request.LoadBalancerArn)) } -func (m *MockELBV2) SetSubnets(request *elbv2.SetSubnetsInput) (*elbv2.SetSubnetsOutput, error) { +func (m *MockELBV2) SetSubnets(ctx context.Context, request *elbv2.SetSubnetsInput, optFns ...func(*elbv2.Options)) (*elbv2.SetSubnetsOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Fatalf("elbv2.SetSubnets() not implemented") return nil, nil } -func (m *MockELBV2) DeleteLoadBalancer(request *elbv2.DeleteLoadBalancerInput) (*elbv2.DeleteLoadBalancerOutput, error) { +func (m *MockELBV2) DeleteLoadBalancer(ctx context.Context, request *elbv2.DeleteLoadBalancerInput, optFns ...func(*elbv2.Options)) (*elbv2.DeleteLoadBalancerOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DeleteLoadBalancer %v", request) - arn := aws.StringValue(request.LoadBalancerArn) + arn := aws.ToString(request.LoadBalancerArn) delete(m.LoadBalancers, arn) for listenerARN, listener := range m.Listeners { - if aws.StringValue(listener.description.LoadBalancerArn) == arn { + if aws.ToString(listener.description.LoadBalancerArn) == arn { delete(m.Listeners, listenerARN) } } diff --git a/cloudmock/aws/mockelbv2/tags.go b/cloudmock/aws/mockelbv2/tags.go index 2004dbf9a6d8a..02d197fc1ffd1 100644 --- a/cloudmock/aws/mockelbv2/tags.go +++ b/cloudmock/aws/mockelbv2/tags.go @@ -19,39 +19,39 @@ package mockelbv2 import ( "context" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" ) -func (m *MockELBV2) AddTags(request *elbv2.AddTagsInput) (*elbv2.AddTagsOutput, error) { +func (m *MockELBV2) AddTags(ctx context.Context, request *elbv2.AddTagsInput, optFns ...func(*elbv2.Options)) (*elbv2.AddTagsOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("AddTags v2 %v", request) if m.Tags == nil { - m.Tags = make(map[string]*elbv2.TagDescription) + m.Tags = make(map[string]elbv2types.TagDescription) } - for _, reqARN := range request.ResourceArns { - arn := aws.StringValue(reqARN) + for _, arn := range request.ResourceArns { if t, ok := m.Tags[arn]; ok { for _, reqTag := range request.Tags { found := false for _, tag := range t.Tags { - if aws.StringValue(reqTag.Key) == aws.StringValue(tag.Key) { + if aws.ToString(reqTag.Key) == aws.ToString(tag.Key) { tag.Value = reqTag.Value } } if !found { - m.Tags[arn].Tags = append(m.Tags[arn].Tags, reqTag) + tags := m.Tags[arn] + tags.Tags = append(m.Tags[arn].Tags, reqTag) } } } else { - m.Tags[arn] = &elbv2.TagDescription{ - ResourceArn: reqARN, + m.Tags[arn] = elbv2types.TagDescription{ + ResourceArn: aws.String(arn), Tags: request.Tags, } } @@ -60,25 +60,21 @@ func (m *MockELBV2) AddTags(request *elbv2.AddTagsInput) (*elbv2.AddTagsOutput, return &elbv2.AddTagsOutput{}, nil } -func (m *MockELBV2) DescribeTagsWithContext(ctx aws.Context, request *elbv2.DescribeTagsInput, opts ...request.Option) (*elbv2.DescribeTagsOutput, error) { +func (m *MockELBV2) DescribeTags(ctx context.Context, request *elbv2.DescribeTagsInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTagsOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DescribeTags v2 %v", request) resp := &elbv2.DescribeTagsOutput{ - TagDescriptions: make([]*elbv2.TagDescription, 0), + TagDescriptions: make([]elbv2types.TagDescription, 0), } for tagARN, tagDesc := range m.Tags { for _, reqARN := range request.ResourceArns { - if tagARN == aws.StringValue(reqARN) { + if tagARN == reqARN { resp.TagDescriptions = append(resp.TagDescriptions, tagDesc) } } } return resp, nil } - -func (m *MockELBV2) DescribeTags(request *elbv2.DescribeTagsInput) (*elbv2.DescribeTagsOutput, error) { - return m.DescribeTagsWithContext(context.TODO(), request) -} diff --git a/cloudmock/aws/mockelbv2/targetgroups.go b/cloudmock/aws/mockelbv2/targetgroups.go index 652f9f0a4f249..991ca25c8cab3 100644 --- a/cloudmock/aws/mockelbv2/targetgroups.go +++ b/cloudmock/aws/mockelbv2/targetgroups.go @@ -20,14 +20,13 @@ import ( "context" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/aws/request" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" ) -func (m *MockELBV2) DescribeTargetGroupsWithContext(ctx context.Context, request *elbv2.DescribeTargetGroupsInput, opts ...request.Option) (*elbv2.DescribeTargetGroupsOutput, error) { +func (m *MockELBV2) DescribeTargetGroups(ctx context.Context, request *elbv2.DescribeTargetGroupsInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTargetGroupsOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() @@ -40,23 +39,23 @@ func (m *MockELBV2) DescribeTargetGroupsWithContext(ctx context.Context, request klog.Fatalf("Marker not implemented") } - var tgs []*elbv2.TargetGroup + var tgs []elbv2types.TargetGroup for _, tg := range m.TargetGroups { match := false if len(request.TargetGroupArns) > 0 { for _, name := range request.TargetGroupArns { - if aws.StringValue(tg.description.TargetGroupArn) == aws.StringValue(name) { + if aws.ToString(tg.description.TargetGroupArn) == name { match = true } } } else if request.LoadBalancerArn != nil { - if len(tg.description.LoadBalancerArns) > 0 && aws.StringValue(tg.description.LoadBalancerArns[0]) == aws.StringValue(request.LoadBalancerArn) { + if len(tg.description.LoadBalancerArns) > 0 && tg.description.LoadBalancerArns[0] == aws.ToString(request.LoadBalancerArn) { match = true } } else if len(request.Names) > 0 { for _, name := range request.Names { - if aws.StringValue(tg.description.TargetGroupName) == aws.StringValue(name) { + if aws.ToString(tg.description.TargetGroupName) == name { match = true } } @@ -65,12 +64,12 @@ func (m *MockELBV2) DescribeTargetGroupsWithContext(ctx context.Context, request } if match { - tgs = append(tgs, &tg.description) + tgs = append(tgs, tg.description) } } if len(tgs) == 0 && len(request.TargetGroupArns) > 0 || request.LoadBalancerArn != nil { - return nil, awserr.New(elbv2.ErrCodeTargetGroupNotFoundException, "target group not found", nil) + return nil, &elbv2types.TargetGroupNotFoundException{} } return &elbv2.DescribeTargetGroupsOutput{ @@ -78,28 +77,13 @@ func (m *MockELBV2) DescribeTargetGroupsWithContext(ctx context.Context, request }, nil } -func (m *MockELBV2) DescribeTargetGroupsPagesWithContext(ctx context.Context, request *elbv2.DescribeTargetGroupsInput, callback func(p *elbv2.DescribeTargetGroupsOutput, lastPage bool) (shouldContinue bool), opt ...request.Option) error { - page, err := m.DescribeTargetGroupsWithContext(ctx, request) - if err != nil { - return err - } - - callback(page, false) - - return nil -} - -func (m *MockELBV2) DescribeTargetGroupsPages(request *elbv2.DescribeTargetGroupsInput, callback func(p *elbv2.DescribeTargetGroupsOutput, lastPage bool) (shouldContinue bool)) error { - return m.DescribeTargetGroupsPagesWithContext(context.TODO(), request, callback) -} - -func (m *MockELBV2) CreateTargetGroup(request *elbv2.CreateTargetGroupInput) (*elbv2.CreateTargetGroupOutput, error) { +func (m *MockELBV2) CreateTargetGroup(ctx context.Context, request *elbv2.CreateTargetGroupInput, optFns ...func(*elbv2.Options)) (*elbv2.CreateTargetGroupOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("CreateTargetGroup %v", request) - tg := elbv2.TargetGroup{ + tg := elbv2types.TargetGroup{ TargetGroupName: request.Name, Port: request.Port, Protocol: request.Protocol, @@ -109,52 +93,52 @@ func (m *MockELBV2) CreateTargetGroup(request *elbv2.CreateTargetGroupInput) (*e } m.tgCount++ - arn := fmt.Sprintf("arn:aws-test:elasticloadbalancing:us-test-1:000000000000:targetgroup/%v/%v", aws.StringValue(request.Name), m.tgCount) + arn := fmt.Sprintf("arn:aws-test:elasticloadbalancing:us-test-1:000000000000:targetgroup/%v/%v", aws.ToString(request.Name), m.tgCount) tg.TargetGroupArn = aws.String(arn) if m.TargetGroups == nil { m.TargetGroups = make(map[string]*targetGroup) } if m.Tags == nil { - m.Tags = make(map[string]*elbv2.TagDescription) + m.Tags = make(map[string]elbv2types.TagDescription) } m.TargetGroups[arn] = &targetGroup{description: tg} - m.Tags[arn] = &elbv2.TagDescription{ + m.Tags[arn] = elbv2types.TagDescription{ ResourceArn: aws.String(arn), Tags: request.Tags, } - return &elbv2.CreateTargetGroupOutput{TargetGroups: []*elbv2.TargetGroup{&tg}}, nil + return &elbv2.CreateTargetGroupOutput{TargetGroups: []elbv2types.TargetGroup{tg}}, nil } -func (m *MockELBV2) DeleteTargetGroup(request *elbv2.DeleteTargetGroupInput) (*elbv2.DeleteTargetGroupOutput, error) { +func (m *MockELBV2) DeleteTargetGroup(ctx context.Context, request *elbv2.DeleteTargetGroupInput, optFns ...func(*elbv2.Options)) (*elbv2.DeleteTargetGroupOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DeleteTargetGroup %v", request) - arn := aws.StringValue(request.TargetGroupArn) + arn := aws.ToString(request.TargetGroupArn) delete(m.TargetGroups, arn) return &elbv2.DeleteTargetGroupOutput{}, nil } -func (m *MockELBV2) DescribeTargetGroupAttributes(request *elbv2.DescribeTargetGroupAttributesInput) (*elbv2.DescribeTargetGroupAttributesOutput, error) { +func (m *MockELBV2) DescribeTargetGroupAttributes(ctx context.Context, request *elbv2.DescribeTargetGroupAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTargetGroupAttributesOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("DescribeTargetGroupAttributes %v", request) - arn := aws.StringValue(request.TargetGroupArn) + arn := aws.ToString(request.TargetGroupArn) return &elbv2.DescribeTargetGroupAttributesOutput{Attributes: m.TargetGroups[arn].attributes}, nil } -func (m *MockELBV2) ModifyTargetGroupAttributes(request *elbv2.ModifyTargetGroupAttributesInput) (*elbv2.ModifyTargetGroupAttributesOutput, error) { +func (m *MockELBV2) ModifyTargetGroupAttributes(ctx context.Context, request *elbv2.ModifyTargetGroupAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.ModifyTargetGroupAttributesOutput, error) { m.mutex.Lock() defer m.mutex.Unlock() klog.Infof("ModifyTargetGroupAttributes %v", request) - arn := aws.StringValue(request.TargetGroupArn) + arn := aws.ToString(request.TargetGroupArn) m.TargetGroups[arn].attributes = request.Attributes return &elbv2.ModifyTargetGroupAttributesOutput{Attributes: request.Attributes}, nil } diff --git a/pkg/model/awsmodel/api_loadbalancer.go b/pkg/model/awsmodel/api_loadbalancer.go index 36386b15dd117..ee6143c7faccd 100644 --- a/pkg/model/awsmodel/api_loadbalancer.go +++ b/pkg/model/awsmodel/api_loadbalancer.go @@ -21,6 +21,7 @@ import ( "sort" "time" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" @@ -208,7 +209,7 @@ func (b *APILoadBalancerBuilder) Build(c *fi.CloudupModelBuilderContext) error { Tags: tags, WellKnownServices: []wellknownservices.WellKnownService{wellknownservices.KubeAPIServer}, VPC: b.LinkToVPC(), - Type: fi.PtrTo("network"), + Type: elbv2types.LoadBalancerTypeEnumNetwork, } // Wait for all load balancer components to be created (including network interfaces needed for NoneDNS). @@ -265,10 +266,10 @@ func (b *APILoadBalancerBuilder) Build(c *fi.CloudupModelBuilderContext) error { switch lbSpec.Type { case kops.LoadBalancerTypeInternal: clb.Scheme = fi.PtrTo("internal") - nlb.Scheme = fi.PtrTo("internal") + nlb.Scheme = elbv2types.LoadBalancerSchemeEnumInternal case kops.LoadBalancerTypePublic: clb.Scheme = nil - nlb.Scheme = fi.PtrTo("internet-facing") + nlb.Scheme = elbv2types.LoadBalancerSchemeEnumInternetFacing default: return fmt.Errorf("unknown load balancer Type: %q", lbSpec.Type) } @@ -314,12 +315,12 @@ func (b *APILoadBalancerBuilder) Build(c *fi.CloudupModelBuilderContext) error { Lifecycle: b.Lifecycle, VPC: b.LinkToVPC(), Tags: groupTags, - Protocol: fi.PtrTo("TCP"), - Port: fi.PtrTo(int64(443)), + Protocol: elbv2types.ProtocolEnumTcp, + Port: fi.PtrTo(int32(443)), Attributes: groupAttrs, - Interval: fi.PtrTo(int64(10)), - HealthyThreshold: fi.PtrTo(int64(2)), - UnhealthyThreshold: fi.PtrTo(int64(2)), + Interval: fi.PtrTo(int32(10)), + HealthyThreshold: fi.PtrTo(int32(2)), + UnhealthyThreshold: fi.PtrTo(int32(2)), Shared: fi.PtrTo(false), } tg.CreateNewRevisionsWith(nlb) @@ -338,12 +339,12 @@ func (b *APILoadBalancerBuilder) Build(c *fi.CloudupModelBuilderContext) error { Lifecycle: b.Lifecycle, VPC: b.LinkToVPC(), Tags: groupTags, - Protocol: fi.PtrTo("TCP"), - Port: fi.PtrTo(int64(wellknownports.KopsControllerPort)), + Protocol: elbv2types.ProtocolEnumTcp, + Port: fi.PtrTo(int32(wellknownports.KopsControllerPort)), Attributes: groupAttrs, - Interval: fi.PtrTo(int64(10)), - HealthyThreshold: fi.PtrTo(int64(2)), - UnhealthyThreshold: fi.PtrTo(int64(2)), + Interval: fi.PtrTo(int32(10)), + HealthyThreshold: fi.PtrTo(int32(2)), + UnhealthyThreshold: fi.PtrTo(int32(2)), Shared: fi.PtrTo(false), } tg.CreateNewRevisionsWith(nlb) @@ -362,12 +363,12 @@ func (b *APILoadBalancerBuilder) Build(c *fi.CloudupModelBuilderContext) error { Lifecycle: b.Lifecycle, VPC: b.LinkToVPC(), Tags: tlsGroupTags, - Protocol: fi.PtrTo("TLS"), - Port: fi.PtrTo(int64(443)), + Protocol: elbv2types.ProtocolEnumTls, + Port: fi.PtrTo(int32(443)), Attributes: groupAttrs, - Interval: fi.PtrTo(int64(10)), - HealthyThreshold: fi.PtrTo(int64(2)), - UnhealthyThreshold: fi.PtrTo(int64(2)), + Interval: fi.PtrTo(int32(10)), + HealthyThreshold: fi.PtrTo(int32(2)), + UnhealthyThreshold: fi.PtrTo(int32(2)), Shared: fi.PtrTo(false), } secondaryTG.CreateNewRevisionsWith(nlb) diff --git a/pkg/model/awsmodel/bastion.go b/pkg/model/awsmodel/bastion.go index e616db32e2cfe..aed6f454881d0 100644 --- a/pkg/model/awsmodel/bastion.go +++ b/pkg/model/awsmodel/bastion.go @@ -20,6 +20,8 @@ import ( "fmt" "sort" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" @@ -347,18 +349,18 @@ func (b *BastionModelBuilder) Build(c *fi.CloudupModelBuilderContext) error { }, Tags: tags, VPC: b.LinkToVPC(), - Type: fi.PtrTo("network"), - IpAddressType: fi.PtrTo("ipv4"), + Type: elbv2types.LoadBalancerTypeEnumNetwork, + IpAddressType: elbv2types.IpAddressTypeIpv4, } if useIPv6ForBastion(b) { - nlb.IpAddressType = fi.PtrTo("dualstack") + nlb.IpAddressType = elbv2types.IpAddressTypeDualstack } // Set the NLB Scheme according to load balancer Type switch bastionLoadBalancerType { case kops.LoadBalancerTypeInternal: - nlb.Scheme = fi.PtrTo("internal") + nlb.Scheme = elbv2types.LoadBalancerSchemeEnumInternal case kops.LoadBalancerTypePublic: - nlb.Scheme = fi.PtrTo("internet-facing") + nlb.Scheme = elbv2types.LoadBalancerSchemeEnumInternetFacing default: return fmt.Errorf("unhandled bastion LoadBalancer type %q", bastionLoadBalancerType) } @@ -379,12 +381,12 @@ func (b *BastionModelBuilder) Build(c *fi.CloudupModelBuilderContext) error { Lifecycle: b.Lifecycle, VPC: b.LinkToVPC(), Tags: sshGroupTags, - Protocol: fi.PtrTo("TCP"), - Port: fi.PtrTo(int64(22)), + Protocol: elbv2types.ProtocolEnumTcp, + Port: fi.PtrTo(int32(22)), Attributes: groupAttrs, - Interval: fi.PtrTo(int64(10)), - HealthyThreshold: fi.PtrTo(int64(2)), - UnhealthyThreshold: fi.PtrTo(int64(2)), + Interval: fi.PtrTo(int32(10)), + HealthyThreshold: fi.PtrTo(int32(2)), + UnhealthyThreshold: fi.PtrTo(int32(2)), Shared: fi.PtrTo(false), } tg.CreateNewRevisionsWith(nlb) diff --git a/pkg/resources/aws/aws.go b/pkg/resources/aws/aws.go index 0414b6172017a..8ee4f3438b2e6 100644 --- a/pkg/resources/aws/aws.go +++ b/pkg/resources/aws/aws.go @@ -23,13 +23,14 @@ import ( "strings" "sync" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "github.com/aws/aws-sdk-go-v2/service/iam" iamtypes "github.com/aws/aws-sdk-go-v2/service/iam/types" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/elb" - "github.com/aws/aws-sdk-go/service/elbv2" "github.com/aws/aws-sdk-go/service/route53" "github.com/aws/smithy-go" "k8s.io/apimachinery/pkg/util/sets" @@ -283,7 +284,7 @@ func matchesElbTags(tags map[string]string, actual []*elb.Tag) bool { return true } -func matchesElbV2Tags(tags map[string]string, actual []*elbv2.Tag) bool { +func matchesElbV2Tags(tags map[string]string, actual []elbv2types.Tag) bool { for k, v := range tags { found := false for _, a := range actual { @@ -1429,6 +1430,7 @@ func DeleteELB(cloud fi.Cloud, r *resources.Resource) error { } func DeleteELBV2(cloud fi.Cloud, r *resources.Resource) error { + ctx := context.TODO() c := cloud.(awsup.AWSCloud) id := r.ID @@ -1436,7 +1438,7 @@ func DeleteELBV2(cloud fi.Cloud, r *resources.Resource) error { request := &elbv2.DeleteLoadBalancerInput{ LoadBalancerArn: aws.String(id), } - _, err := c.ELBV2().DeleteLoadBalancer(request) + _, err := c.ELBV2().DeleteLoadBalancer(ctx, request) if err != nil { if IsDependencyViolation(err) { return err @@ -1447,6 +1449,7 @@ func DeleteELBV2(cloud fi.Cloud, r *resources.Resource) error { } func DeleteTargetGroup(cloud fi.Cloud, r *resources.Resource) error { + ctx := context.TODO() c := cloud.(awsup.AWSCloud) id := r.ID @@ -1454,7 +1457,7 @@ func DeleteTargetGroup(cloud fi.Cloud, r *resources.Resource) error { request := &elbv2.DeleteTargetGroupInput{ TargetGroupArn: aws.String(id), } - _, err := c.ELBV2().DeleteTargetGroup(request) + _, err := c.ELBV2().DeleteTargetGroup(ctx, request) if err != nil { if IsDependencyViolation(err) { return err @@ -1591,7 +1594,7 @@ func ListELBV2s(cloud fi.Cloud, vpcID, clusterName string) ([]*resources.Resourc var blocks []string for _, sg := range elb.SecurityGroups { - blocks = append(blocks, "security-group:"+aws.StringValue(sg)) + blocks = append(blocks, "security-group:"+sg) } blocks = append(blocks, "vpc:"+aws.StringValue(elb.VpcId)) @@ -2160,7 +2163,7 @@ func FindELBName(tags []*elb.Tag) string { return "" } -func FindELBV2Name(tags []*elbv2.Tag) string { +func FindELBV2Name(tags []elbv2types.Tag) string { if name, found := awsup.FindELBV2Tag(tags, "Name"); found { return name } diff --git a/pkg/testutils/integrationtestharness.go b/pkg/testutils/integrationtestharness.go index 6c39114c39e18..37c319f66937d 100644 --- a/pkg/testutils/integrationtestharness.go +++ b/pkg/testutils/integrationtestharness.go @@ -27,10 +27,10 @@ import ( "k8s.io/kops/cloudmock/aws/mockeventbridge" "k8s.io/kops/cloudmock/aws/mocksqs" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" "github.com/aws/aws-sdk-go-v2/service/iam" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" - "github.com/aws/aws-sdk-go/service/elbv2" "github.com/aws/aws-sdk-go/service/route53" "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors" "github.com/gophercloud/gophercloud/openstack/dns/v2/zones" @@ -257,13 +257,13 @@ func (h *IntegrationTestHarness) SetupMockAWS() *awsup.MockAWSCloud { AllocationId: aws.String("eipalloc-b2345678"), }, "nat-b2345678") - mockELBV2.CreateTargetGroup(&elbv2.CreateTargetGroupInput{ + mockELBV2.CreateTargetGroup(ctx, &elbv2.CreateTargetGroupInput{ Name: aws.String("my-external-tg-1"), }) - mockELBV2.CreateTargetGroup(&elbv2.CreateTargetGroupInput{ + mockELBV2.CreateTargetGroup(ctx, &elbv2.CreateTargetGroupInput{ Name: aws.String("my-external-tg-2"), }) - mockELBV2.CreateTargetGroup(&elbv2.CreateTargetGroupInput{ + mockELBV2.CreateTargetGroup(ctx, &elbv2.CreateTargetGroupInput{ Name: aws.String("my-external-tg-3"), }) diff --git a/upup/pkg/fi/cloudup/awstasks/network_load_balancer.go b/upup/pkg/fi/cloudup/awstasks/network_load_balancer.go index f1a847ebe8aa5..116777eb06241 100644 --- a/upup/pkg/fi/cloudup/awstasks/network_load_balancer.go +++ b/upup/pkg/fi/cloudup/awstasks/network_load_balancer.go @@ -24,9 +24,10 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "github.com/aws/aws-sdk-go/service/elb" - "github.com/aws/aws-sdk-go/service/elbv2" "github.com/aws/aws-sdk-go/service/route53" "k8s.io/klog/v2" "k8s.io/kops/pkg/truncate" @@ -62,15 +63,15 @@ type NetworkLoadBalancer struct { SubnetMappings []*SubnetMapping SecurityGroups []*SecurityGroup - Scheme *string + Scheme elbv2types.LoadBalancerSchemeEnum CrossZoneLoadBalancing *bool - IpAddressType *string + IpAddressType elbv2types.IpAddressType Tags map[string]string - Type *string + Type elbv2types.LoadBalancerTypeEnum VPC *VPC AccessLog *NetworkLoadBalancerAccessLog @@ -104,26 +105,26 @@ func (e *NetworkLoadBalancer) CompareWithID() *string { return e.Name } -func findNetworkLoadBalancerByAlias(cloud awsup.AWSCloud, alias *route53.AliasTarget) (*elbv2.LoadBalancer, error) { +func findNetworkLoadBalancerByAlias(cloud awsup.AWSCloud, alias *route53.AliasTarget) (*elbv2types.LoadBalancer, error) { ctx := context.TODO() // TODO: Any way to avoid listing all NLBs? request := &elbv2.DescribeLoadBalancersInput{} - dnsName := aws.StringValue(alias.DNSName) + dnsName := aws.ToString(alias.DNSName) matchDnsName := strings.TrimSuffix(dnsName, ".") if matchDnsName == "" { return nil, fmt.Errorf("DNSName not set on AliasTarget") } - matchHostedZoneId := aws.StringValue(alias.HostedZoneId) + matchHostedZoneId := aws.ToString(alias.HostedZoneId) - found, err := describeNetworkLoadBalancers(ctx, cloud, request, func(lb *elbv2.LoadBalancer) bool { - if matchHostedZoneId != aws.StringValue(lb.CanonicalHostedZoneId) { + found, err := describeNetworkLoadBalancers(ctx, cloud, request, func(lb elbv2types.LoadBalancer) bool { + if matchHostedZoneId != aws.ToString(lb.CanonicalHostedZoneId) { return false } - lbDnsName := aws.StringValue(lb.DNSName) + lbDnsName := aws.ToString(lb.DNSName) lbDnsName = strings.TrimSuffix(lbDnsName, ".") return lbDnsName == matchDnsName || "dualstack."+lbDnsName == matchDnsName }) @@ -139,22 +140,22 @@ func findNetworkLoadBalancerByAlias(cloud awsup.AWSCloud, alias *route53.AliasTa return nil, fmt.Errorf("Found multiple NLBs with DNSName %q", dnsName) } - return found[0], nil + return &found[0], nil } -func describeNetworkLoadBalancers(ctx context.Context, cloud awsup.AWSCloud, request *elbv2.DescribeLoadBalancersInput, filter func(*elbv2.LoadBalancer) bool) ([]*elbv2.LoadBalancer, error) { - var found []*elbv2.LoadBalancer - err := cloud.ELBV2().DescribeLoadBalancersPagesWithContext(ctx, request, func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) (shouldContinue bool) { - for _, lb := range p.LoadBalancers { +func describeNetworkLoadBalancers(ctx context.Context, cloud awsup.AWSCloud, request *elbv2.DescribeLoadBalancersInput, filter func(elbv2types.LoadBalancer) bool) ([]elbv2types.LoadBalancer, error) { + var found []elbv2types.LoadBalancer + paginator := elbv2.NewDescribeLoadBalancersPaginator(cloud.ELBV2(), request) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return nil, fmt.Errorf("listing NLBs: %v", err) + } + for _, lb := range page.LoadBalancers { if filter(lb) { found = append(found, lb) } } - - return true - }) - if err != nil { - return nil, fmt.Errorf("error listing NLBs: %v", err) } return found, nil @@ -216,14 +217,14 @@ func (e *NetworkLoadBalancer) Find(c *fi.CloudupContext) (*NetworkLoadBalancer, actual.Tags = make(map[string]string) for _, tag := range latest.Tags { - k := aws.StringValue(tag.Key) + k := aws.ToString(tag.Key) if strings.HasPrefix(k, "aws:cloudformation:") { continue } if k == awsup.KopsResourceRevisionTag { continue } - actual.Tags[k] = aws.StringValue(tag.Value) + actual.Tags[k] = aws.ToString(tag.Value) } for _, az := range lb.AvailabilityZones { @@ -248,11 +249,11 @@ func (e *NetworkLoadBalancer) Find(c *fi.CloudupContext) (*NetworkLoadBalancer, } for _, sg := range lb.SecurityGroups { - actual.SecurityGroups = append(actual.SecurityGroups, &SecurityGroup{ID: sg}) + actual.SecurityGroups = append(actual.SecurityGroups, &SecurityGroup{ID: aws.String(sg)}) } { - lbAttributes, err := findNetworkLoadBalancerAttributes(cloud, loadBalancerArn) + lbAttributes, err := findNetworkLoadBalancerAttributes(ctx, cloud, loadBalancerArn) if err != nil { return nil, err } @@ -310,7 +311,7 @@ func (e *NetworkLoadBalancer) Find(c *fi.CloudupContext) (*NetworkLoadBalancer, } // An existing internal NLB can't be updated to dualstack. - if fi.ValueOf(actual.Scheme) == elbv2.LoadBalancerSchemeEnumInternal && fi.ValueOf(actual.IpAddressType) == elbv2.IpAddressTypeIpv4 { + if actual.Scheme == elbv2types.LoadBalancerSchemeEnumInternal && actual.IpAddressType == elbv2types.IpAddressTypeIpv4 { e.IpAddressType = actual.IpAddressType } @@ -320,7 +321,7 @@ func (e *NetworkLoadBalancer) Find(c *fi.CloudupContext) (*NetworkLoadBalancer, actual.LoadBalancerBaseName = e.LoadBalancerBaseName // Store state for other tasks - e.loadBalancerArn = aws.StringValue(lb.LoadBalancerArn) + e.loadBalancerArn = aws.ToString(lb.LoadBalancerArn) actual.loadBalancerArn = e.loadBalancerArn e.revision, _ = latest.GetTag(awsup.KopsResourceRevisionTag) actual.revision = e.revision @@ -370,9 +371,9 @@ func (e *NetworkLoadBalancer) FindAddresses(c *fi.CloudupContext) ([]string, err } if cluster.UsesNoneDNS() { - nis, err := cloud.FindELBV2NetworkInterfacesByName(fi.ValueOf(e.VPC.ID), aws.StringValue(lb.LoadBalancer.LoadBalancerName)) + nis, err := cloud.FindELBV2NetworkInterfacesByName(fi.ValueOf(e.VPC.ID), aws.ToString(lb.LoadBalancer.LoadBalancerName)) if err != nil { - return nil, fmt.Errorf("failed to find network interfaces matching %q: %w", aws.StringValue(lb.LoadBalancer.LoadBalancerName), err) + return nil, fmt.Errorf("failed to find network interfaces matching %q: %w", aws.ToString(lb.LoadBalancer.LoadBalancerName), err) } for _, ni := range nis { if fi.ValueOf(ni.PrivateIpAddress) != "" { @@ -396,11 +397,11 @@ func (e *NetworkLoadBalancer) Normalize(c *fi.CloudupContext) error { // We need to sort our arrays consistently, so we don't get spurious changes sort.Stable(OrderSubnetMappingsByName(e.SubnetMappings)) - e.IpAddressType = fi.PtrTo("dualstack") + e.IpAddressType = elbv2types.IpAddressTypeDualstack for _, subnet := range e.SubnetMappings { for _, clusterSubnet := range c.T.Cluster.Spec.Networking.Subnets { if clusterSubnet.Name == fi.ValueOf(subnet.Subnet.ShortName) && clusterSubnet.IPv6CIDR == "" { - e.IpAddressType = fi.PtrTo("ipv4") + e.IpAddressType = elbv2types.IpAddressTypeIpv4 } } } @@ -501,7 +502,7 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne request.Tags = awsup.ELBv2Tags(tags) for _, subnetMapping := range e.SubnetMappings { - request.SubnetMappings = append(request.SubnetMappings, &elbv2.SubnetMapping{ + request.SubnetMappings = append(request.SubnetMappings, elbv2types.SubnetMapping{ SubnetId: subnetMapping.Subnet.ID, AllocationId: subnetMapping.AllocationID, PrivateIPv4Address: subnetMapping.PrivateIPv4Address, @@ -509,12 +510,12 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne } for _, sg := range e.SecurityGroups { - request.SecurityGroups = append(request.SecurityGroups, sg.ID) + request.SecurityGroups = append(request.SecurityGroups, aws.ToString(sg.ID)) } klog.V(2).Infof("Creating NLB %q", loadBalancerName) - response, err := t.Cloud.ELBV2().CreateLoadBalancer(request) + response, err := t.Cloud.ELBV2().CreateLoadBalancer(ctx, request) if err != nil { return fmt.Errorf("error creating NLB %q: %w", loadBalancerName, err) } @@ -526,7 +527,7 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne e.DNSName = lb.DNSName e.HostedZoneId = lb.CanonicalHostedZoneId e.VPC = &VPC{ID: lb.VpcId} - loadBalancerArn = aws.StringValue(lb.LoadBalancerArn) + loadBalancerArn = aws.ToString(lb.LoadBalancerArn) e.loadBalancerArn = loadBalancerArn e.revision = revision } @@ -534,10 +535,10 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne if e.waitForLoadBalancerReady { klog.Infof("Waiting for load balancer %q to be created...", loadBalancerName) request := &elbv2.DescribeLoadBalancersInput{ - Names: []*string{&loadBalancerName}, + Names: []string{loadBalancerName}, } - err := t.Cloud.ELBV2().WaitUntilLoadBalancerAvailableWithContext(ctx, request) + err := elbv2.NewLoadBalancerAvailableWaiter(t.Cloud.ELBV2()).Wait(ctx, request, 15*time.Minute) if err != nil { return fmt.Errorf("error waiting for NLB %q: %w", loadBalancerName, err) } @@ -546,12 +547,12 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne } else { loadBalancerArn = a.loadBalancerArn - if changes.IpAddressType != nil { + if len(changes.IpAddressType) > 0 { request := &elbv2.SetIpAddressTypeInput{ IpAddressType: e.IpAddressType, LoadBalancerArn: &loadBalancerArn, } - if _, err := t.Cloud.ELBV2().SetIpAddressType(request); err != nil { + if _, err := t.Cloud.ELBV2().SetIpAddressType(ctx, request); err != nil { return fmt.Errorf("error setting the IP addresses type: %v", err) } } @@ -568,14 +569,14 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne } } - var awsSubnetMappings []*elbv2.SubnetMapping + var awsSubnetMappings []elbv2types.SubnetMapping hasChanges := false for _, s := range e.SubnetMappings { aIP, ok := actualSubnets[*s.Subnet.ID] if !ok || (fi.ValueOf(s.PrivateIPv4Address) != fi.ValueOf(aIP) && fi.ValueOf(s.AllocationID) != fi.ValueOf(aIP)) { hasChanges = true } - awsSubnetMappings = append(awsSubnetMappings, &elbv2.SubnetMapping{ + awsSubnetMappings = append(awsSubnetMappings, elbv2types.SubnetMapping{ SubnetId: s.Subnet.ID, AllocationId: s.AllocationID, PrivateIPv4Address: s.PrivateIPv4Address, @@ -584,11 +585,11 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne if hasChanges { request := &elbv2.SetSubnetsInput{} - request.SetLoadBalancerArn(loadBalancerArn) - request.SetSubnetMappings(awsSubnetMappings) + request.LoadBalancerArn = aws.String(loadBalancerArn) + request.SubnetMappings = awsSubnetMappings klog.V(2).Infof("Attaching Load Balancer to new subnets") - if _, err := t.Cloud.ELBV2().SetSubnets(request); err != nil { + if _, err := t.Cloud.ELBV2().SetSubnets(ctx, request); err != nil { return fmt.Errorf("error attaching load balancer to new subnets: %v", err) } } @@ -599,11 +600,11 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne LoadBalancerArn: &loadBalancerArn, } for _, sg := range e.SecurityGroups { - request.SecurityGroups = append(request.SecurityGroups, sg.ID) + request.SecurityGroups = append(request.SecurityGroups, aws.ToString(sg.ID)) } klog.V(2).Infof("Updating Load Balancer Security Groups") - if _, err := t.Cloud.ELBV2().SetSecurityGroups(request); err != nil { + if _, err := t.Cloud.ELBV2().SetSecurityGroups(ctx, request); err != nil { return fmt.Errorf("Error updating security groups on Load Balancer: %v", err) } } @@ -627,8 +628,8 @@ func (_ *NetworkLoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Ne type terraformNetworkLoadBalancer struct { Name string `cty:"name"` Internal bool `cty:"internal"` - Type string `cty:"load_balancer_type"` - IPAddressType *string `cty:"ip_address_type"` + Type elbv2types.LoadBalancerTypeEnum `cty:"load_balancer_type"` + IPAddressType *elbv2types.IpAddressType `cty:"ip_address_type"` SecurityGroups []*terraformWriter.Literal `cty:"security_groups"` SubnetMappings []terraformNetworkLoadBalancerSubnetMapping `cty:"subnet_mapping"` CrossZoneLoadBalancing bool `cty:"enable_cross_zone_load_balancing"` @@ -646,13 +647,13 @@ type terraformNetworkLoadBalancerSubnetMapping struct { func (_ *NetworkLoadBalancer) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *NetworkLoadBalancer) error { nlbTF := &terraformNetworkLoadBalancer{ Name: *e.LoadBalancerBaseName, - Internal: fi.ValueOf(e.Scheme) == elbv2.LoadBalancerSchemeEnumInternal, - Type: elbv2.LoadBalancerTypeEnumNetwork, + Internal: e.Scheme == elbv2types.LoadBalancerSchemeEnumInternal, + Type: elbv2types.LoadBalancerTypeEnumNetwork, Tags: e.Tags, CrossZoneLoadBalancing: fi.ValueOf(e.CrossZoneLoadBalancing), } - if fi.ValueOf(e.IpAddressType) == "dualstack" { - nlbTF.IPAddressType = e.IpAddressType + if e.IpAddressType == elbv2types.IpAddressTypeDualstack { + nlbTF.IPAddressType = &e.IpAddressType } for _, subnetMapping := range e.SubnetMappings { @@ -712,7 +713,7 @@ func (e *NetworkLoadBalancer) FindDeletions(context *fi.CloudupContext) ([]fi.Cl } if lb != nil { - klog.V(4).Infof("Found CLB %v", aws.StringValue(lb.LoadBalancerName)) + klog.V(4).Infof("Found CLB %v", aws.ToString(lb.LoadBalancerName)) deletions = append(deletions, &deleteClassicLoadBalancer{LoadBalancerName: e.CLBName}) } } @@ -778,7 +779,7 @@ func (d *deleteNLB) Delete(t fi.CloudupTarget) error { arn := d.obj.ARN() klog.V(2).Infof("deleting load balancer %q", arn) - if _, err := awsTarget.Cloud.ELBV2().DeleteLoadBalancerWithContext(ctx, &elbv2.DeleteLoadBalancerInput{ + if _, err := awsTarget.Cloud.ELBV2().DeleteLoadBalancer(ctx, &elbv2.DeleteLoadBalancerInput{ LoadBalancerArn: &arn, }); err != nil { return fmt.Errorf("error deleting ELB LoadBalancer %q: %w", arn, err) diff --git a/upup/pkg/fi/cloudup/awstasks/networkloadbalancer_attributes.go b/upup/pkg/fi/cloudup/awstasks/networkloadbalancer_attributes.go index 08fb732983705..74a6ea51085c6 100644 --- a/upup/pkg/fi/cloudup/awstasks/networkloadbalancer_attributes.go +++ b/upup/pkg/fi/cloudup/awstasks/networkloadbalancer_attributes.go @@ -17,11 +17,13 @@ limitations under the License. package awstasks import ( + "context" "fmt" "strconv" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/awsup" @@ -43,12 +45,12 @@ type terraformNetworkLoadBalancerAccessLog struct { S3BucketPrefix *string `cty:"prefix"` } -func findNetworkLoadBalancerAttributes(cloud awsup.AWSCloud, LoadBalancerArn string) ([]*elbv2.LoadBalancerAttribute, error) { +func findNetworkLoadBalancerAttributes(ctx context.Context, cloud awsup.AWSCloud, LoadBalancerArn string) ([]elbv2types.LoadBalancerAttribute, error) { request := &elbv2.DescribeLoadBalancerAttributesInput{ LoadBalancerArn: aws.String(LoadBalancerArn), } - response, err := cloud.ELBV2().DescribeLoadBalancerAttributes(request) + response, err := cloud.ELBV2().DescribeLoadBalancerAttributes(ctx, request) if err != nil { return nil, err } @@ -67,6 +69,8 @@ func findNetworkLoadBalancerAttributes(cloud awsup.AWSCloud, LoadBalancerArn str } func (_ *NetworkLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget, a, e, changes *NetworkLoadBalancer, loadBalancerArn string) error { + ctx := context.TODO() + if changes.CrossZoneLoadBalancing == nil && changes.AccessLog == nil { klog.V(4).Infof("No LoadBalancerAttribute changes; skipping update") return nil @@ -76,33 +80,33 @@ func (_ *NetworkLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget LoadBalancerArn: aws.String(loadBalancerArn), } - var attributes []*elbv2.LoadBalancerAttribute + var attributes []elbv2types.LoadBalancerAttribute - attribute := &elbv2.LoadBalancerAttribute{} + attribute := elbv2types.LoadBalancerAttribute{} attribute.Key = aws.String("load_balancing.cross_zone.enabled") if e.CrossZoneLoadBalancing == nil { attribute.Value = aws.String("false") } else { - attribute.Value = aws.String(strconv.FormatBool(aws.BoolValue(e.CrossZoneLoadBalancing))) + attribute.Value = aws.String(strconv.FormatBool(aws.ToBool(e.CrossZoneLoadBalancing))) } attributes = append(attributes, attribute) if e.AccessLog != nil { - attr := &elbv2.LoadBalancerAttribute{ + attr := elbv2types.LoadBalancerAttribute{ Key: aws.String("access_logs.s3.enabled"), - Value: aws.String(strconv.FormatBool(aws.BoolValue(e.AccessLog.Enabled))), + Value: aws.String(strconv.FormatBool(aws.ToBool(e.AccessLog.Enabled))), } attributes = append(attributes, attr) } if e.AccessLog != nil && e.AccessLog.S3BucketName != nil { - attr := &elbv2.LoadBalancerAttribute{ + attr := elbv2types.LoadBalancerAttribute{ Key: aws.String("access_logs.s3.bucket"), Value: e.AccessLog.S3BucketName, } attributes = append(attributes, attr) } if e.AccessLog != nil && e.AccessLog.S3BucketPrefix != nil { - attr := &elbv2.LoadBalancerAttribute{ + attr := elbv2types.LoadBalancerAttribute{ Key: aws.String("access_logs.s3.prefix"), Value: e.AccessLog.S3BucketPrefix, } @@ -113,7 +117,7 @@ func (_ *NetworkLoadBalancer) modifyLoadBalancerAttributes(t *awsup.AWSAPITarget klog.V(2).Infof("Configuring NLB attributes for NLB %q", loadBalancerArn) - response, err := t.Cloud.ELBV2().ModifyLoadBalancerAttributes(request) + response, err := t.Cloud.ELBV2().ModifyLoadBalancerAttributes(ctx, request) if err != nil { return fmt.Errorf("error configuring NLB attributes for NLB %q: %v", loadBalancerArn, err) } diff --git a/upup/pkg/fi/cloudup/awstasks/networkloadbalancerlistener.go b/upup/pkg/fi/cloudup/awstasks/networkloadbalancerlistener.go index 79b366fc2f36b..9845a945f0e96 100644 --- a/upup/pkg/fi/cloudup/awstasks/networkloadbalancerlistener.go +++ b/upup/pkg/fi/cloudup/awstasks/networkloadbalancerlistener.go @@ -20,8 +20,9 @@ import ( "context" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" "k8s.io/kops/upup/pkg/fi" "k8s.io/kops/upup/pkg/fi/cloudup/awsup" @@ -67,23 +68,25 @@ func (e *NetworkLoadBalancerListener) Find(c *fi.CloudupContext) (*NetworkLoadBa return nil, nil } - var l *elbv2.Listener + var l *elbv2types.Listener { request := &elbv2.DescribeListenersInput{ LoadBalancerArn: &loadBalancerArn, } // TODO: Move to lbInfo? - var allListeners []*elbv2.Listener - if err := cloud.ELBV2().DescribeListenersPagesWithContext(ctx, request, func(page *elbv2.DescribeListenersOutput, lastPage bool) bool { + var allListeners []elbv2types.Listener + paginator := elbv2.NewDescribeListenersPaginator(cloud.ELBV2(), request) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return nil, fmt.Errorf("error querying for NLB listeners :%v", err) + } allListeners = append(allListeners, page.Listeners...) - return true - }); err != nil { - return nil, fmt.Errorf("error querying for NLB listeners :%v", err) } - var matches []*elbv2.Listener + var matches []elbv2types.Listener for _, listener := range allListeners { - if aws.Int64Value(listener.Port) == int64(e.Port) { + if aws.ToInt32(listener.Port) == int32(e.Port) { matches = append(matches, listener) } } @@ -93,17 +96,17 @@ func (e *NetworkLoadBalancerListener) Find(c *fi.CloudupContext) (*NetworkLoadBa if len(matches) > 1 { return nil, fmt.Errorf("found multiple listeners matching %+v", e) } - l = matches[0] + l = &matches[0] } actual := &NetworkLoadBalancerListener{} - actual.listenerArn = aws.StringValue(l.ListenerArn) + actual.listenerArn = aws.ToString(l.ListenerArn) - actual.Port = int(aws.Int64Value(l.Port)) + actual.Port = int(aws.ToInt32(l.Port)) if len(l.Certificates) != 0 { - actual.SSLCertificateID = aws.StringValue(l.Certificates[0].CertificateArn) // What if there is more then one certificate, can we just grab the default certificate? we don't set it as default, we only set the one. + actual.SSLCertificateID = aws.ToString(l.Certificates[0].CertificateArn) // What if there is more then one certificate, can we just grab the default certificate? we don't set it as default, we only set the one. if l.SslPolicy != nil { - actual.SSLPolicy = aws.StringValue(l.SslPolicy) + actual.SSLPolicy = aws.ToString(l.SslPolicy) } } @@ -157,7 +160,7 @@ func (*NetworkLoadBalancerListener) RenderAWS(t *awsup.AWSAPITarget, a, e, chang klog.Warningf("deleting ELB listener %q for required changes (%+v)", a.listenerArn, changes) // delete the listener before recreating it - _, err := t.Cloud.ELBV2().DeleteListenerWithContext(ctx, &elbv2.DeleteListenerInput{ + _, err := t.Cloud.ELBV2().DeleteListener(ctx, &elbv2.DeleteListenerInput{ ListenerArn: &a.listenerArn, }) if err != nil { @@ -175,31 +178,31 @@ func (*NetworkLoadBalancerListener) RenderAWS(t *awsup.AWSAPITarget, a, e, chang return fmt.Errorf("target group not yet created (arn not set)") } request := &elbv2.CreateListenerInput{ - DefaultActions: []*elbv2.Action{ + DefaultActions: []elbv2types.Action{ { TargetGroupArn: aws.String(targetGroupARN), - Type: aws.String(elbv2.ActionTypeEnumForward), + Type: elbv2types.ActionTypeEnumForward, }, }, LoadBalancerArn: aws.String(loadBalancerArn), - Port: aws.Int64(int64(e.Port)), + Port: aws.Int32(int32(e.Port)), } if e.SSLCertificateID != "" { - request.Certificates = []*elbv2.Certificate{} - request.Certificates = append(request.Certificates, &elbv2.Certificate{ + request.Certificates = []elbv2types.Certificate{} + request.Certificates = append(request.Certificates, elbv2types.Certificate{ CertificateArn: aws.String(e.SSLCertificateID), }) - request.Protocol = aws.String(elbv2.ProtocolEnumTls) + request.Protocol = elbv2types.ProtocolEnumTls if e.SSLPolicy != "" { request.SslPolicy = aws.String(e.SSLPolicy) } } else { - request.Protocol = aws.String(elbv2.ProtocolEnumTcp) + request.Protocol = elbv2types.ProtocolEnumTcp } klog.V(2).Infof("Creating Listener for NLB with port %v", e.Port) - _, err := t.Cloud.ELBV2().CreateListenerWithContext(ctx, request) + _, err := t.Cloud.ELBV2().CreateListener(ctx, request) if err != nil { return fmt.Errorf("creating listener for NLB on port %v: %w", e.Port, err) } @@ -211,15 +214,15 @@ func (*NetworkLoadBalancerListener) RenderAWS(t *awsup.AWSAPITarget, a, e, chang type terraformNetworkLoadBalancerListener struct { LoadBalancer *terraformWriter.Literal `cty:"load_balancer_arn"` Port int64 `cty:"port"` - Protocol string `cty:"protocol"` + Protocol elbv2types.ProtocolEnum `cty:"protocol"` CertificateARN *string `cty:"certificate_arn"` SSLPolicy *string `cty:"ssl_policy"` DefaultAction []terraformNetworkLoadBalancerListenerAction `cty:"default_action"` } type terraformNetworkLoadBalancerListenerAction struct { - Type string `cty:"type"` - TargetGroupARN *terraformWriter.Literal `cty:"target_group_arn"` + Type elbv2types.ActionTypeEnum `cty:"type"` + TargetGroupARN *terraformWriter.Literal `cty:"target_group_arn"` } func (_ *NetworkLoadBalancerListener) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *NetworkLoadBalancerListener) error { @@ -231,19 +234,19 @@ func (_ *NetworkLoadBalancerListener) RenderTerraform(t *terraform.TerraformTarg Port: int64(e.Port), DefaultAction: []terraformNetworkLoadBalancerListenerAction{ { - Type: elbv2.ActionTypeEnumForward, + Type: elbv2types.ActionTypeEnumForward, TargetGroupARN: e.TargetGroup.TerraformLink(), }, }, } if e.SSLCertificateID != "" { listenerTF.CertificateARN = &e.SSLCertificateID - listenerTF.Protocol = elbv2.ProtocolEnumTls + listenerTF.Protocol = elbv2types.ProtocolEnumTls if e.SSLPolicy != "" { listenerTF.SSLPolicy = &e.SSLPolicy } } else { - listenerTF.Protocol = elbv2.ProtocolEnumTcp + listenerTF.Protocol = elbv2types.ProtocolEnumTcp } err := t.RenderResource("aws_lb_listener", e.TerraformName(), listenerTF) diff --git a/upup/pkg/fi/cloudup/awstasks/targetgroup.go b/upup/pkg/fi/cloudup/awstasks/targetgroup.go index d7b6ab1c353e5..79ebccb9a19b0 100644 --- a/upup/pkg/fi/cloudup/awstasks/targetgroup.go +++ b/upup/pkg/fi/cloudup/awstasks/targetgroup.go @@ -18,12 +18,13 @@ package awstasks import ( "context" + "errors" "fmt" "strconv" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/awserr" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" "k8s.io/kops/pkg/truncate" "k8s.io/kops/upup/pkg/fi" @@ -49,8 +50,8 @@ type TargetGroup struct { Lifecycle fi.Lifecycle VPC *VPC Tags map[string]string - Port *int64 - Protocol *string + Port *int32 + Protocol elbv2types.ProtocolEnum // networkLoadBalancer, if set, will create a new Target Group for each revision of the Network Load Balancer networkLoadBalancer *NetworkLoadBalancer @@ -63,9 +64,9 @@ type TargetGroup struct { Attributes map[string]string - Interval *int64 - HealthyThreshold *int64 - UnhealthyThreshold *int64 + Interval *int32 + HealthyThreshold *int32 + UnhealthyThreshold *int32 info *awsup.TargetGroupInfo revision string @@ -112,7 +113,7 @@ func (e *TargetGroup) findLatestTargetGroupByName(ctx context.Context, cloud aws var latestRevision int for _, targetGroup := range targetGroups { // We accept the name tag _or_ the TargetGroupName itself, to allow matching groups that might predate tagging. - if aws.StringValue(targetGroup.TargetGroup.TargetGroupName) != name && targetGroup.NameTag() != name { + if aws.ToString(targetGroup.TargetGroup.TargetGroupName) != name && targetGroup.NameTag() != name { continue } revisionTag, _ := targetGroup.GetTag(awsup.KopsResourceRevisionTag) @@ -151,7 +152,7 @@ func (e *TargetGroup) findLatestTargetGroupByName(ctx context.Context, cloud aws // Record deletions for later for _, targetGroup := range targetGroups { - if aws.StringValue(targetGroup.TargetGroup.TargetGroupName) != name && targetGroup.NameTag() != name { + if aws.ToString(targetGroup.TargetGroup.TargetGroupName) != name && targetGroup.NameTag() != name { continue } if latest != nil && latest.ARN == targetGroup.ARN { @@ -166,19 +167,22 @@ func (e *TargetGroup) findLatestTargetGroupByName(ctx context.Context, cloud aws func (e *TargetGroup) findTargetGroupByARN(ctx context.Context, cloud awsup.AWSCloud) (*awsup.TargetGroupInfo, error) { request := &elbv2.DescribeTargetGroupsInput{} - request.TargetGroupArns = []*string{e.ARN} + request.TargetGroupArns = []string{aws.ToString(e.ARN)} - var targetGroups []*elbv2.TargetGroup - if err := cloud.ELBV2().DescribeTargetGroupsPagesWithContext(ctx, request, func(page *elbv2.DescribeTargetGroupsOutput, lastPage bool) bool { - targetGroups = append(targetGroups, page.TargetGroups...) - return true - }); err != nil { - if aerr, ok := err.(awserr.Error); ok && aerr.Code() == elbv2.ErrCodeTargetGroupNotFoundException { - if !fi.ValueOf(e.Shared) { - return nil, nil + var targetGroups []elbv2types.TargetGroup + paginator := elbv2.NewDescribeTargetGroupsPaginator(cloud.ELBV2(), request) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + var nfe *elbv2types.TargetGroupNotFoundException + if errors.As(err, &nfe) { + if !fi.ValueOf(e.Shared) { + return nil, nil + } } + return nil, fmt.Errorf("error describing targetgroup %s: %w", *e.ARN, err) } - return nil, fmt.Errorf("error describing targetgroup %s: %w", *e.ARN, err) + targetGroups = append(targetGroups, page.TargetGroups...) } if len(targetGroups) > 1 { return nil, fmt.Errorf("found %d TargetGroups with ID %q, expected 1", len(targetGroups), fi.ValueOf(e.Name)) @@ -187,8 +191,8 @@ func (e *TargetGroup) findTargetGroupByARN(ctx context.Context, cloud awsup.AWSC } tg := targetGroups[0] - tagResponse, err := cloud.ELBV2().DescribeTagsWithContext(ctx, &elbv2.DescribeTagsInput{ - ResourceArns: []*string{tg.TargetGroupArn}, + tagResponse, err := cloud.ELBV2().DescribeTags(ctx, &elbv2.DescribeTagsInput{ + ResourceArns: []string{aws.ToString(tg.TargetGroupArn)}, }) if err != nil { return nil, err @@ -196,7 +200,7 @@ func (e *TargetGroup) findTargetGroupByARN(ctx context.Context, cloud awsup.AWSC info := &awsup.TargetGroupInfo{ TargetGroup: tg, - ARN: aws.StringValue(tg.TargetGroupArn), + ARN: aws.ToString(tg.TargetGroupArn), } for _, t := range tagResponse.TagDescriptions { @@ -263,7 +267,7 @@ func (e *TargetGroup) Find(c *fi.CloudupContext) (*TargetGroup, error) { } actual.Tags = tags - attrResp, err := cloud.ELBV2().DescribeTargetGroupAttributes(&elbv2.DescribeTargetGroupAttributesInput{ + attrResp, err := cloud.ELBV2().DescribeTargetGroupAttributes(ctx, &elbv2.DescribeTargetGroupAttributesInput{ TargetGroupArn: tg.TargetGroupArn, }) if err != nil { @@ -306,6 +310,7 @@ func (s *TargetGroup) CheckChanges(a, e, changes *TargetGroup) error { } func (_ *TargetGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *TargetGroup) error { + ctx := context.TODO() shared := fi.ValueOf(e.Shared) if shared { return nil @@ -360,12 +365,12 @@ func (_ *TargetGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *TargetGrou } klog.V(2).Infof("Creating Target Group for NLB") - response, err := t.Cloud.ELBV2().CreateTargetGroup(request) + response, err := t.Cloud.ELBV2().CreateTargetGroup(ctx, request) if err != nil { return fmt.Errorf("creating NLB target group: %w", err) } - if err := ModifyTargetGroupAttributes(t.Cloud, response.TargetGroups[0].TargetGroupArn, e.Attributes); err != nil { + if err := ModifyTargetGroupAttributes(ctx, t.Cloud, response.TargetGroups[0].TargetGroupArn, e.Attributes); err != nil { return err } @@ -378,7 +383,7 @@ func (_ *TargetGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *TargetGrou if err := t.AddELBV2Tags(fi.ValueOf(a.ARN), e.Tags); err != nil { return err } - if err := ModifyTargetGroupAttributes(t.Cloud, a.ARN, e.Attributes); err != nil { + if err := ModifyTargetGroupAttributes(ctx, t.Cloud, a.ARN, e.Attributes); err != nil { return err } } @@ -386,19 +391,19 @@ func (_ *TargetGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *TargetGrou return nil } -func ModifyTargetGroupAttributes(cloud awsup.AWSCloud, arn *string, attributes map[string]string) error { +func ModifyTargetGroupAttributes(ctx context.Context, cloud awsup.AWSCloud, arn *string, attributes map[string]string) error { klog.V(2).Infof("Modifying Target Group attributes for NLB") attrReq := &elbv2.ModifyTargetGroupAttributesInput{ - Attributes: []*elbv2.TargetGroupAttribute{}, + Attributes: []elbv2types.TargetGroupAttribute{}, TargetGroupArn: arn, } for k, v := range attributes { - attrReq.Attributes = append(attrReq.Attributes, &elbv2.TargetGroupAttribute{ + attrReq.Attributes = append(attrReq.Attributes, elbv2types.TargetGroupAttribute{ Key: fi.PtrTo(k), Value: fi.PtrTo(v), }) } - if _, err := cloud.ELBV2().ModifyTargetGroupAttributes(attrReq); err != nil { + if _, err := cloud.ELBV2().ModifyTargetGroupAttributes(ctx, attrReq); err != nil { return fmt.Errorf("error modifying target group attributes for NLB : %v", err) } return nil @@ -415,8 +420,8 @@ func (a OrderTargetGroupsByName) Less(i, j int) bool { type terraformTargetGroup struct { Name string `cty:"name"` - Port int64 `cty:"port"` - Protocol string `cty:"protocol"` + Port int32 `cty:"port"` + Protocol elbv2types.ProtocolEnum `cty:"protocol"` VPCID *terraformWriter.Literal `cty:"vpc_id"` ConnectionTermination string `cty:"connection_termination"` DeregistrationDelay string `cty:"deregistration_delay"` @@ -425,10 +430,10 @@ type terraformTargetGroup struct { } type terraformTargetGroupHealthCheck struct { - Interval int64 `cty:"interval"` - HealthyThreshold int64 `cty:"healthy_threshold"` - UnhealthyThreshold int64 `cty:"unhealthy_threshold"` - Protocol string `cty:"protocol"` + Interval int32 `cty:"interval"` + HealthyThreshold int32 `cty:"healthy_threshold"` + UnhealthyThreshold int32 `cty:"unhealthy_threshold"` + Protocol elbv2types.ProtocolEnum `cty:"protocol"` } func (_ *TargetGroup) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *TargetGroup) error { @@ -444,14 +449,14 @@ func (_ *TargetGroup) RenderTerraform(t *terraform.TerraformTarget, a, e, change tf := &terraformTargetGroup{ Name: *e.Name, Port: *e.Port, - Protocol: *e.Protocol, + Protocol: e.Protocol, VPCID: e.VPC.TerraformLink(), Tags: e.Tags, HealthCheck: terraformTargetGroupHealthCheck{ Interval: *e.Interval, HealthyThreshold: *e.HealthyThreshold, UnhealthyThreshold: *e.UnhealthyThreshold, - Protocol: elbv2.ProtocolEnumTcp, + Protocol: elbv2types.ProtocolEnumTcp, }, } @@ -512,7 +517,7 @@ func (d *deleteTargetGroup) Delete(t fi.CloudupTarget) error { arn := d.obj.ARN klog.V(2).Infof("deleting target group %q", arn) - if _, err := awsTarget.Cloud.ELBV2().DeleteTargetGroupWithContext(ctx, &elbv2.DeleteTargetGroupInput{ + if _, err := awsTarget.Cloud.ELBV2().DeleteTargetGroup(ctx, &elbv2.DeleteTargetGroupInput{ TargetGroupArn: &arn, }); err != nil { return fmt.Errorf("error deleting ELB TargetGroup %q: %w", arn, err) diff --git a/upup/pkg/fi/cloudup/awsup/aws_cloud.go b/upup/pkg/fi/cloudup/awsup/aws_cloud.go index 9f6aecede2519..1999cad4e07ff 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_cloud.go +++ b/upup/pkg/fi/cloudup/awsup/aws_cloud.go @@ -34,6 +34,8 @@ import ( "github.com/aws/aws-sdk-go-v2/aws/arn" "github.com/aws/aws-sdk-go-v2/aws/retry" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "github.com/aws/aws-sdk-go-v2/service/iam" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" @@ -46,8 +48,6 @@ import ( "github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/elb/elbiface" - "github.com/aws/aws-sdk-go/service/elbv2" - "github.com/aws/aws-sdk-go/service/elbv2/elbv2iface" "github.com/aws/aws-sdk-go/service/route53" "github.com/aws/aws-sdk-go/service/route53/route53iface" "github.com/aws/aws-sdk-go/service/sts" @@ -129,7 +129,7 @@ type AWSCloud interface { EC2() ec2iface.EC2API IAM() awsinterfaces.IAMAPI ELB() elbiface.ELBAPI - ELBV2() elbv2iface.ELBV2API + ELBV2() awsinterfaces.ELBV2API Autoscaling() autoscalingiface.AutoScalingAPI Route53() route53iface.Route53API Spotinst() spotinst.Cloud @@ -164,7 +164,7 @@ type AWSCloud interface { FindELBByNameTag(findNameTag string) (*elb.LoadBalancerDescription, error) DescribeELBTags(loadBalancerNames []string) (map[string][]*elb.Tag, error) // TODO: Remove, replace with awsup.ListELBV2LoadBalancers - DescribeELBV2Tags(loadBalancerNames []string) (map[string][]*elbv2.Tag, error) + DescribeELBV2Tags(loadBalancerNames []string) (map[string][]elbv2types.Tag, error) FindELBV2NetworkInterfacesByName(vpcID string, loadBalancerName string) ([]*ec2.NetworkInterface, error) // DescribeInstance is a helper that queries for the specified instance by id @@ -198,7 +198,7 @@ type awsCloudImplementation struct { ec2 *ec2.EC2 iam *iam.Client elb *elb.ELB - elbv2 *elbv2.ELBV2 + elbv2 *elbv2.Client autoscaling *autoscaling.AutoScaling route53 *route53.Route53 spotinst spotinst.Cloud @@ -345,16 +345,7 @@ func NewAWSCloud(region string, tags map[string]string) (AWSCloud, error) { c.elb.Handlers.Send.PushFront(requestLogger) c.addHandlers(region, &c.elb.Handlers) - sess, err = session.NewSessionWithOptions(session.Options{ - Config: *config, - SharedConfigState: session.SharedConfigEnable, - }) - if err != nil { - return c, err - } - c.elbv2 = elbv2.New(sess, config) - c.elbv2.Handlers.Send.PushFront(requestLogger) - c.addHandlers(region, &c.elbv2.Handlers) + c.elbv2 = elbv2.NewFromConfig(cfgV2) sess, err = session.NewSessionWithOptions(session.Options{ Config: *config, @@ -650,7 +641,7 @@ func deregisterInstance(ctx context.Context, c AWSCloud, i *cloudinstances.Cloud if len(targetGroupArns) != 0 { eg.Go(func() error { - return deregisterInstanceFromTargetGroups(c, targetGroupArns, i.ID) + return deregisterInstanceFromTargetGroups(ctx, c, targetGroupArns, i.ID) }) } @@ -706,13 +697,13 @@ func deregisterInstanceFromClassicLoadBalancer(c AWSCloud, loadBalancerNames []s // deregisterInstanceFromTargetGroups ensures that instances are fully unused in the corresponding targetGroups before instance termination. // this ensures that connections are fully drained from the instance before terminating. -func deregisterInstanceFromTargetGroups(c AWSCloud, targetGroupArns []string, instanceId string) error { +func deregisterInstanceFromTargetGroups(ctx context.Context, c AWSCloud, targetGroupArns []string, instanceId string) error { eg, _ := errgroup.WithContext(context.Background()) for _, targetGroupArn := range targetGroupArns { arn := targetGroupArn eg.Go(func() error { - return deregisterInstanceFromTargetGroup(c, arn, instanceId) + return deregisterInstanceFromTargetGroup(ctx, c, arn, instanceId) }) } @@ -723,15 +714,15 @@ func deregisterInstanceFromTargetGroups(c AWSCloud, targetGroupArns []string, in return nil } -func deregisterInstanceFromTargetGroup(c AWSCloud, targetGroupArn string, instanceId string) error { +func deregisterInstanceFromTargetGroup(ctx context.Context, c AWSCloud, targetGroupArn string, instanceId string) error { klog.Infof("Deregistering instance from targetGroup: %s", targetGroupArn) for { instanceDraining := false - response, err := c.ELBV2().DescribeTargetHealth(&elbv2.DescribeTargetHealthInput{ + response, err := c.ELBV2().DescribeTargetHealth(ctx, &elbv2.DescribeTargetHealthInput{ TargetGroupArn: aws.String(targetGroupArn), - Targets: []*elbv2.TargetDescription{{ + Targets: []elbv2types.TargetDescription{{ Id: aws.String(instanceId), }}, }) @@ -742,10 +733,10 @@ func deregisterInstanceFromTargetGroup(c AWSCloud, targetGroupArn string, instan // there will be only one target in the DescribeTargetHealth response. // DescribeTargetHealth response will contain a target even if the targetId doesn't exist. // all other states besides TargetHealthStateUnused means that the instance may still be serving traffic. - if aws.StringValue(response.TargetHealthDescriptions[0].TargetHealth.State) != elbv2.TargetHealthStateEnumUnused { - _, err = c.ELBV2().DeregisterTargets(&elbv2.DeregisterTargetsInput{ + if response.TargetHealthDescriptions[0].TargetHealth.State != elbv2types.TargetHealthStateEnumUnused { + _, err = c.ELBV2().DeregisterTargets(ctx, &elbv2.DeregisterTargetsInput{ TargetGroupArn: aws.String(targetGroupArn), - Targets: []*elbv2.TargetDescription{{ + Targets: []elbv2types.TargetDescription{{ Id: aws.String(instanceId), }}, }) @@ -1666,21 +1657,22 @@ func (c *awsCloudImplementation) RemoveELBV2Tags(ResourceArn string, tags map[st } func removeELBV2Tags(c AWSCloud, ResourceArn string, tags map[string]string) error { + ctx := context.TODO() if len(tags) == 0 { return nil } - elbTagKeysOnly := []*string{} + elbTagKeysOnly := []string{} for k := range tags { - elbTagKeysOnly = append(elbTagKeysOnly, aws.String(k)) + elbTagKeysOnly = append(elbTagKeysOnly, k) } request := &elbv2.RemoveTagsInput{ TagKeys: elbTagKeysOnly, - ResourceArns: []*string{&ResourceArn}, + ResourceArns: []string{ResourceArn}, } - _, err := c.ELBV2().RemoveTags(request) + _, err := c.ELBV2().RemoveTags(ctx, request) if err != nil { return fmt.Errorf("error creating tags on %v: %v", ResourceArn, err) } @@ -1693,12 +1685,13 @@ func (c *awsCloudImplementation) GetELBV2Tags(ResourceArn string) (map[string]st } func getELBV2Tags(c AWSCloud, ResourceArn string) (map[string]string, error) { + ctx := context.TODO() tags := map[string]string{} request := &elbv2.DescribeTagsInput{ - ResourceArns: []*string{&ResourceArn}, + ResourceArns: []string{ResourceArn}, } - response, err := c.ELBV2().DescribeTags(request) + response, err := c.ELBV2().DescribeTags(ctx, request) if err != nil { return nil, fmt.Errorf("error listing tags on %v: %v", ResourceArn, err) } @@ -1717,20 +1710,21 @@ func (c *awsCloudImplementation) CreateELBV2Tags(ResourceArn string, tags map[st } func createELBV2Tags(c AWSCloud, ResourceArn string, tags map[string]string) error { + ctx := context.TODO() if len(tags) == 0 { return nil } - elbv2Tags := []*elbv2.Tag{} + elbv2Tags := []elbv2types.Tag{} for k, v := range tags { - elbv2Tags = append(elbv2Tags, &elbv2.Tag{Key: aws.String(k), Value: aws.String(v)}) + elbv2Tags = append(elbv2Tags, elbv2types.Tag{Key: aws.String(k), Value: aws.String(v)}) } request := &elbv2.AddTagsInput{ Tags: elbv2Tags, - ResourceArns: []*string{&ResourceArn}, + ResourceArns: []string{ResourceArn}, } - _, err := c.ELBV2().AddTags(request) + _, err := c.ELBV2().AddTags(ctx, request) if err != nil { return fmt.Errorf("error creating tags on %v: %v", ResourceArn, err) } @@ -1912,24 +1906,24 @@ func findELBV2NetworkInterfaces(c AWSCloud, vpcID, lbName string) ([]*ec2.Networ return found, nil } -func (c *awsCloudImplementation) DescribeELBV2Tags(loadBalancerArns []string) (map[string][]*elbv2.Tag, error) { +func (c *awsCloudImplementation) DescribeELBV2Tags(loadBalancerArns []string) (map[string][]elbv2types.Tag, error) { return describeELBV2Tags(c, loadBalancerArns) } -func describeELBV2Tags(c AWSCloud, loadBalancerArns []string) (map[string][]*elbv2.Tag, error) { +func describeELBV2Tags(c AWSCloud, loadBalancerArns []string) (map[string][]elbv2types.Tag, error) { // TODO: Filter by cluster? - + ctx := context.TODO() request := &elbv2.DescribeTagsInput{} - request.ResourceArns = aws.StringSlice(loadBalancerArns) + request.ResourceArns = loadBalancerArns // TODO: Cache? klog.V(2).Infof("Querying ELBV2 api for tags for %s", loadBalancerArns) - response, err := c.ELBV2().DescribeTags(request) + response, err := c.ELBV2().DescribeTags(ctx, request) if err != nil { return nil, err } - tagMap := make(map[string][]*elbv2.Tag) + tagMap := make(map[string][]elbv2types.Tag) for _, tagset := range response.TagDescriptions { tagMap[aws.StringValue(tagset.ResourceArn)] = tagset.Tags } @@ -2185,7 +2179,7 @@ func (c *awsCloudImplementation) ELB() elbiface.ELBAPI { return c.elb } -func (c *awsCloudImplementation) ELBV2() elbv2iface.ELBV2API { +func (c *awsCloudImplementation) ELBV2() awsinterfaces.ELBV2API { return c.elbv2 } diff --git a/upup/pkg/fi/cloudup/awsup/aws_utils.go b/upup/pkg/fi/cloudup/awsup/aws_utils.go index 38fe2ef9f7702..0213b05bffda0 100644 --- a/upup/pkg/fi/cloudup/awsup/aws_utils.go +++ b/upup/pkg/fi/cloudup/awsup/aws_utils.go @@ -28,12 +28,12 @@ import ( awsconfig "github.com/aws/aws-sdk-go-v2/config" ec2v2 "github.com/aws/aws-sdk-go-v2/service/ec2" ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/awserr" "github.com/aws/aws-sdk-go/service/autoscaling" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/elb" - elbv2 "github.com/aws/aws-sdk-go/service/elbv2" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/truncate" @@ -143,7 +143,7 @@ func FindELBTag(tags []*elb.Tag, key string) (string, bool) { } // FindELBV2Tag find the value of the tag with the specified key -func FindELBV2Tag(tags []*elbv2.Tag, key string) (string, bool) { +func FindELBV2Tag(tags []elbv2types.Tag, key string) (string, bool) { for _, tag := range tags { if key == aws.StringValue(tag.Key) { return aws.StringValue(tag.Value), true @@ -188,13 +188,13 @@ func EC2TagSpecification(resourceType string, tags map[string]string) []*ec2.Tag } // ELBv2Tags converts a map of tags to ELBv2 Tags -func ELBv2Tags(tags map[string]string) []*elbv2.Tag { +func ELBv2Tags(tags map[string]string) []elbv2types.Tag { if len(tags) == 0 { return nil } - elbv2Tags := make([]*elbv2.Tag, 0) + elbv2Tags := make([]elbv2types.Tag, 0) for k, v := range tags { - elbv2Tags = append(elbv2Tags, &elbv2.Tag{ + elbv2Tags = append(elbv2Tags, elbv2types.Tag{ Key: aws.String(k), Value: aws.String(v), }) diff --git a/upup/pkg/fi/cloudup/awsup/elbv2_loadbalancers.go b/upup/pkg/fi/cloudup/awsup/elbv2_loadbalancers.go index 7598e9225e046..978703dcbd811 100644 --- a/upup/pkg/fi/cloudup/awsup/elbv2_loadbalancers.go +++ b/upup/pkg/fi/cloudup/awsup/elbv2_loadbalancers.go @@ -18,17 +18,17 @@ package awsup import ( "context" - "errors" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" ) type LoadBalancerInfo struct { - LoadBalancer *elbv2.LoadBalancer - Tags []*elbv2.Tag + LoadBalancer elbv2types.LoadBalancer + Tags []elbv2types.Tag arn string } @@ -46,8 +46,8 @@ func (i *LoadBalancerInfo) NameTag() string { // GetTag returns the value of the tag with the given key. func (i *LoadBalancerInfo) GetTag(key string) (string, bool) { for _, tag := range i.Tags { - if aws.StringValue(tag.Key) == key { - return aws.StringValue(tag.Value), true + if aws.ToString(tag.Key) == key { + return aws.ToString(tag.Value), true } } return "", false @@ -59,35 +59,35 @@ func ListELBV2LoadBalancers(ctx context.Context, cloud AWSCloud) ([]*LoadBalance request := &elbv2.DescribeLoadBalancersInput{} // ELBV2 DescribeTags has a limit of 20 names, so we set the page size here to 20 also - request.PageSize = aws.Int64(20) + request.PageSize = aws.Int32(20) byARN := make(map[string]*LoadBalancerInfo) - var errs []error - err := cloud.ELBV2().DescribeLoadBalancersPagesWithContext(ctx, request, func(p *elbv2.DescribeLoadBalancersOutput, lastPage bool) bool { - if len(p.LoadBalancers) == 0 { - return true + paginator := elbv2.NewDescribeLoadBalancersPaginator(cloud.ELBV2(), request) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return nil, fmt.Errorf("listing ELB LoadBalancers: %w", err) } tagRequest := &elbv2.DescribeTagsInput{} - for _, elb := range p.LoadBalancers { - arn := aws.StringValue(elb.LoadBalancerArn) + for _, elb := range page.LoadBalancers { + arn := aws.ToString(elb.LoadBalancerArn) byARN[arn] = &LoadBalancerInfo{LoadBalancer: elb, arn: arn} // TODO: Any way to filter by cluster here? - tagRequest.ResourceArns = append(tagRequest.ResourceArns, elb.LoadBalancerArn) + tagRequest.ResourceArns = append(tagRequest.ResourceArns, aws.ToString(elb.LoadBalancerArn)) } - tagResponse, err := cloud.ELBV2().DescribeTags(tagRequest) + tagResponse, err := cloud.ELBV2().DescribeTags(ctx, tagRequest) if err != nil { - errs = append(errs, fmt.Errorf("listing ELB tags: %w", err)) - return false + return nil, fmt.Errorf("listing ELB tags: %w", err) } for _, t := range tagResponse.TagDescriptions { - arn := aws.StringValue(t.ResourceArn) + arn := aws.ToString(t.ResourceArn) info := byARN[arn] if info == nil { @@ -96,14 +96,6 @@ func ListELBV2LoadBalancers(ctx context.Context, cloud AWSCloud) ([]*LoadBalance info.Tags = append(info.Tags, t.Tags...) } - - return true - }) - if err != nil { - return nil, fmt.Errorf("listing ELB LoadBalancers: %w", err) - } - if len(errs) != 0 { - return nil, fmt.Errorf("listing ELB LoadBalancers: %w", errors.Join(errs...)) } cloudTags := cloud.Tags() @@ -118,12 +110,12 @@ func ListELBV2LoadBalancers(ctx context.Context, cloud AWSCloud) ([]*LoadBalance return results, nil } -func MatchesElbV2Tags(tags map[string]string, actual []*elbv2.Tag) bool { +func MatchesElbV2Tags(tags map[string]string, actual []elbv2types.Tag) bool { for k, v := range tags { found := false for _, a := range actual { - if aws.StringValue(a.Key) == k { - if aws.StringValue(a.Value) == v { + if aws.ToString(a.Key) == k { + if aws.ToString(a.Value) == v { found = true break } diff --git a/upup/pkg/fi/cloudup/awsup/elbv2_targetgroups.go b/upup/pkg/fi/cloudup/awsup/elbv2_targetgroups.go index 89b43c18bdf57..33971eb29fef5 100644 --- a/upup/pkg/fi/cloudup/awsup/elbv2_targetgroups.go +++ b/upup/pkg/fi/cloudup/awsup/elbv2_targetgroups.go @@ -18,17 +18,17 @@ package awsup import ( "context" - "errors" "fmt" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/aws/aws-sdk-go-v2/aws" + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "k8s.io/klog/v2" ) type TargetGroupInfo struct { - TargetGroup *elbv2.TargetGroup - Tags []*elbv2.Tag + TargetGroup elbv2types.TargetGroup + Tags []elbv2types.Tag // ARN holds the arn (amazon id) of the target group. ARN string @@ -43,8 +43,8 @@ func (i *TargetGroupInfo) NameTag() string { // GetTag returns the value of the tag with the given key. func (i *TargetGroupInfo) GetTag(key string) (string, bool) { for _, tag := range i.Tags { - if aws.StringValue(tag.Key) == key { - return aws.StringValue(tag.Value), true + if aws.ToString(tag.Key) == key { + return aws.ToString(tag.Value), true } } return "", false @@ -55,33 +55,33 @@ func ListELBV2TargetGroups(ctx context.Context, cloud AWSCloud) ([]*TargetGroupI request := &elbv2.DescribeTargetGroupsInput{} // ELBV2 DescribeTags has a limit of 20 names, so we set the page size here to 20 also - request.PageSize = aws.Int64(20) + request.PageSize = aws.Int32(20) byARN := make(map[string]*TargetGroupInfo) - var errs []error - err := cloud.ELBV2().DescribeTargetGroupsPagesWithContext(ctx, request, func(p *elbv2.DescribeTargetGroupsOutput, lastPage bool) bool { - if len(p.TargetGroups) == 0 { - return true + paginator := elbv2.NewDescribeTargetGroupsPaginator(cloud.ELBV2(), request) + for paginator.HasMorePages() { + page, err := paginator.NextPage(ctx) + if err != nil { + return nil, fmt.Errorf("listing ELB TargetGroups: %w", err) } tagRequest := &elbv2.DescribeTagsInput{} - for _, tg := range p.TargetGroups { - arn := aws.StringValue(tg.TargetGroupArn) + for _, tg := range page.TargetGroups { + arn := aws.ToString(tg.TargetGroupArn) byARN[arn] = &TargetGroupInfo{TargetGroup: tg, ARN: arn} - tagRequest.ResourceArns = append(tagRequest.ResourceArns, tg.TargetGroupArn) + tagRequest.ResourceArns = append(tagRequest.ResourceArns, aws.ToString(tg.TargetGroupArn)) } - tagResponse, err := cloud.ELBV2().DescribeTagsWithContext(ctx, tagRequest) + tagResponse, err := cloud.ELBV2().DescribeTags(ctx, tagRequest) if err != nil { - errs = append(errs, fmt.Errorf("listing ELB tags: %w", err)) - return false + return nil, fmt.Errorf("listing ELB tags: %w", err) } for _, t := range tagResponse.TagDescriptions { - arn := aws.StringValue(t.ResourceArn) + arn := aws.ToString(t.ResourceArn) info := byARN[arn] if info == nil { @@ -90,14 +90,6 @@ func ListELBV2TargetGroups(ctx context.Context, cloud AWSCloud) ([]*TargetGroupI info.Tags = append(info.Tags, t.Tags...) } - - return true - }) - if err != nil { - return nil, fmt.Errorf("listing ELB TargetGroups: %w", err) - } - if len(errs) != 0 { - return nil, fmt.Errorf("listing ELB TargetGroups: %w", errors.Join(errs...)) } cloudTags := cloud.Tags() diff --git a/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go b/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go index 54426c9e63c4d..cbf102c7bd622 100644 --- a/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go +++ b/upup/pkg/fi/cloudup/awsup/mock_aws_cloud.go @@ -21,6 +21,7 @@ import ( "fmt" ec2types "github.com/aws/aws-sdk-go-v2/service/ec2/types" + elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface" @@ -28,8 +29,6 @@ import ( "github.com/aws/aws-sdk-go/service/ec2/ec2iface" "github.com/aws/aws-sdk-go/service/elb" "github.com/aws/aws-sdk-go/service/elb/elbiface" - "github.com/aws/aws-sdk-go/service/elbv2" - "github.com/aws/aws-sdk-go/service/elbv2/elbv2iface" "github.com/aws/aws-sdk-go/service/route53/route53iface" v1 "k8s.io/api/core/v1" "k8s.io/klog/v2" @@ -81,7 +80,7 @@ type MockCloud struct { MockIAM awsinterfaces.IAMAPI MockRoute53 route53iface.Route53API MockELB elbiface.ELBAPI - MockELBV2 elbv2iface.ELBV2API + MockELBV2 awsinterfaces.ELBV2API MockSpotinst spotinst.Cloud MockSQS awsinterfaces.SQSAPI MockEventBridge awsinterfaces.EventBridgeAPI @@ -209,7 +208,7 @@ func (c *MockAWSCloud) DescribeELBTags(loadBalancerNames []string) (map[string][ return describeELBTags(c, loadBalancerNames) } -func (c *MockAWSCloud) DescribeELBV2Tags(loadBalancerArns []string) (map[string][]*elbv2.Tag, error) { +func (c *MockAWSCloud) DescribeELBV2Tags(loadBalancerArns []string) (map[string][]elbv2types.Tag, error) { return describeELBV2Tags(c, loadBalancerArns) } @@ -257,7 +256,7 @@ func (c *MockAWSCloud) ELB() elbiface.ELBAPI { return c.MockELB } -func (c *MockAWSCloud) ELBV2() elbv2iface.ELBV2API { +func (c *MockAWSCloud) ELBV2() awsinterfaces.ELBV2API { if c.MockELBV2 == nil { klog.Fatalf("MockAWSCloud MockELBV2 not set") } diff --git a/util/pkg/awsinterfaces/elbv2.go b/util/pkg/awsinterfaces/elbv2.go new file mode 100644 index 0000000000000..bffc9e8b1643a --- /dev/null +++ b/util/pkg/awsinterfaces/elbv2.go @@ -0,0 +1,47 @@ +/* +Copyright 2024 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package awsinterfaces + +import ( + "context" + + elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2" +) + +type ELBV2API interface { + AddTags(ctx context.Context, input *elbv2.AddTagsInput, optFns ...func(*elbv2.Options)) (*elbv2.AddTagsOutput, error) + CreateListener(ctx context.Context, input *elbv2.CreateListenerInput, optFns ...func(*elbv2.Options)) (*elbv2.CreateListenerOutput, error) + CreateLoadBalancer(ctx context.Context, input *elbv2.CreateLoadBalancerInput, optFns ...func(*elbv2.Options)) (*elbv2.CreateLoadBalancerOutput, error) + CreateTargetGroup(ctx context.Context, input *elbv2.CreateTargetGroupInput, optFns ...func(*elbv2.Options)) (*elbv2.CreateTargetGroupOutput, error) + DeleteListener(ctx context.Context, input *elbv2.DeleteListenerInput, optFns ...func(*elbv2.Options)) (*elbv2.DeleteListenerOutput, error) + DeleteLoadBalancer(ctx context.Context, input *elbv2.DeleteLoadBalancerInput, optFns ...func(*elbv2.Options)) (*elbv2.DeleteLoadBalancerOutput, error) + DeleteTargetGroup(ctx context.Context, input *elbv2.DeleteTargetGroupInput, optFns ...func(*elbv2.Options)) (*elbv2.DeleteTargetGroupOutput, error) + DeregisterTargets(ctx context.Context, input *elbv2.DeregisterTargetsInput, optFns ...func(*elbv2.Options)) (*elbv2.DeregisterTargetsOutput, error) + DescribeListeners(ctx context.Context, input *elbv2.DescribeListenersInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeListenersOutput, error) + DescribeLoadBalancerAttributes(ctx context.Context, input *elbv2.DescribeLoadBalancerAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeLoadBalancerAttributesOutput, error) + DescribeLoadBalancers(ctx context.Context, input *elbv2.DescribeLoadBalancersInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeLoadBalancersOutput, error) + DescribeTags(ctx context.Context, input *elbv2.DescribeTagsInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTagsOutput, error) + DescribeTargetGroupAttributes(ctx context.Context, input *elbv2.DescribeTargetGroupAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTargetGroupAttributesOutput, error) + DescribeTargetGroups(ctx context.Context, input *elbv2.DescribeTargetGroupsInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTargetGroupsOutput, error) + DescribeTargetHealth(ctx context.Context, input *elbv2.DescribeTargetHealthInput, optFns ...func(*elbv2.Options)) (*elbv2.DescribeTargetHealthOutput, error) + ModifyLoadBalancerAttributes(ctx context.Context, input *elbv2.ModifyLoadBalancerAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.ModifyLoadBalancerAttributesOutput, error) + ModifyTargetGroupAttributes(ctx context.Context, input *elbv2.ModifyTargetGroupAttributesInput, optFns ...func(*elbv2.Options)) (*elbv2.ModifyTargetGroupAttributesOutput, error) + RemoveTags(ctx context.Context, input *elbv2.RemoveTagsInput, optFns ...func(*elbv2.Options)) (*elbv2.RemoveTagsOutput, error) + SetIpAddressType(ctx context.Context, input *elbv2.SetIpAddressTypeInput, optFns ...func(*elbv2.Options)) (*elbv2.SetIpAddressTypeOutput, error) + SetSecurityGroups(ctx context.Context, input *elbv2.SetSecurityGroupsInput, optFns ...func(*elbv2.Options)) (*elbv2.SetSecurityGroupsOutput, error) + SetSubnets(ctx context.Context, input *elbv2.SetSubnetsInput, optFns ...func(*elbv2.Options)) (*elbv2.SetSubnetsOutput, error) +}