mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 15:47:14 +01:00
Merge pull request #10258 from tthvo/CORS-4055-elb
CORS-4055, CORS-4078: migrate ELB/ELBv2 API calls to AWS SDK v2
This commit is contained in:
@@ -7,6 +7,8 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/credentials/stscreds"
|
||||
"github.com/aws/aws-sdk-go-v2/service/ec2"
|
||||
elb "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancing"
|
||||
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-v2/service/route53"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
@@ -33,6 +35,44 @@ func NewEC2Client(ctx context.Context, endpointOpts EndpointOptions, optFns ...f
|
||||
return ec2.NewFromConfig(cfg, ec2Opts...), nil
|
||||
}
|
||||
|
||||
// NewELBClient creates a new ELB (classic) client.
|
||||
func NewELBClient(ctx context.Context, endpointOpts EndpointOptions, optFns ...func(*elb.Options)) (*elb.Client, error) {
|
||||
cfg, err := GetConfigWithOptions(ctx, config.WithRegion(endpointOpts.Region))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
elbOpts := []func(*elb.Options){
|
||||
func(o *elb.Options) {
|
||||
o.EndpointResolverV2 = &ELBEndpointResolver{
|
||||
ServiceEndpointResolver: NewServiceEndpointResolver(endpointOpts),
|
||||
}
|
||||
},
|
||||
}
|
||||
elbOpts = append(elbOpts, optFns...)
|
||||
|
||||
return elb.NewFromConfig(cfg, elbOpts...), nil
|
||||
}
|
||||
|
||||
// NewELBV2Client creates a new ELBV2 client.
|
||||
func NewELBV2Client(ctx context.Context, endpointOpts EndpointOptions, optFns ...func(*elbv2.Options)) (*elbv2.Client, error) {
|
||||
cfg, err := GetConfigWithOptions(ctx, config.WithRegion(endpointOpts.Region))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
elbv2Opts := []func(*elbv2.Options){
|
||||
func(o *elbv2.Options) {
|
||||
o.EndpointResolverV2 = &ELBV2EndpointResolver{
|
||||
ServiceEndpointResolver: NewServiceEndpointResolver(endpointOpts),
|
||||
}
|
||||
},
|
||||
}
|
||||
elbv2Opts = append(elbv2Opts, optFns...)
|
||||
|
||||
return elbv2.NewFromConfig(cfg, elbv2Opts...), nil
|
||||
}
|
||||
|
||||
// NewIAMClient creates a new IAM API client.
|
||||
func NewIAMClient(ctx context.Context, endpointOpts EndpointOptions, optFns ...func(*iam.Options)) (*iam.Client, error) {
|
||||
cfg, err := GetConfigWithOptions(ctx, config.WithRegion(endpointOpts.Region))
|
||||
|
||||
@@ -3,6 +3,7 @@ package aws
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/ec2"
|
||||
@@ -30,24 +31,28 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
// v1Tov2ServiceIDMap maps v1 service ID to its v2 equivalent.
|
||||
v1Tov2ServiceIDMap = map[string]string{
|
||||
// In v1 sdk, a constant EndpointsID is exported in each service to look up the custom service endpoint.
|
||||
// For example: https://github.com/aws/aws-sdk-go/blob/070853e88d22854d2355c2543d0958a5f76ad407/service/resourcegroupstaggingapi/service.go#L33-L34
|
||||
// In v2 SDK, these constants are no longer available.
|
||||
// For backwards compatibility, we copy those constants from the SDK v1 and map it to ServiceID in SDK v2.
|
||||
compatServiceIDMap = map[string]string{
|
||||
"ec2": ec2.ServiceID,
|
||||
"elasticloadbalancing": elb.ServiceID,
|
||||
"elasticloadbalancingv2": elbv2.ServiceID,
|
||||
"iam": iam.ServiceID,
|
||||
"route53": route53.ServiceID,
|
||||
"s3": s3.ServiceID,
|
||||
"sts": sts.ServiceID,
|
||||
"resourcegroupstaggingapi": resourcegroupstaggingapi.ServiceID,
|
||||
"tagging": resourcegroupstaggingapi.ServiceID,
|
||||
"servicequotas": servicequotas.ServiceID,
|
||||
}
|
||||
// logELBv2FallbackOnce logs the ELBv2 fallback once.
|
||||
logELBv2FallbackOnce sync.Once
|
||||
)
|
||||
|
||||
// resolveServiceID converts a service ID in the SDK from v1 to v2.
|
||||
// If the service ID is not recognized, return as-is.
|
||||
// resolveServiceID returns the serviceID for service endpoint resolvers to look up the endpoint URL.
|
||||
// If the serviceID is an SDKv1 identifier, this converts it SDKv2. Otherwise, return as-is.
|
||||
func resolveServiceID(serviceID string) string {
|
||||
if v2serviceID, ok := v1Tov2ServiceIDMap[serviceID]; ok {
|
||||
if v2serviceID, ok := compatServiceIDMap[serviceID]; ok {
|
||||
return v2serviceID
|
||||
}
|
||||
return serviceID
|
||||
@@ -76,6 +81,23 @@ func NewServiceEndpointResolver(opts EndpointOptions) *ServiceEndpointResolver {
|
||||
for _, endpoint := range opts.Endpoints {
|
||||
endpointMap[resolveServiceID(endpoint.Name)] = endpoint
|
||||
}
|
||||
|
||||
// In v1 SDK, elb and elbv2 uses the same identifier, thus the same endpoint.
|
||||
// elbv2: https://github.com/aws/aws-sdk-go/blob/070853e88d22854d2355c2543d0958a5f76ad407/service/elbv2/service.go#L32-L33
|
||||
// elb: https://github.com/aws/aws-sdk-go/blob/070853e88d22854d2355c2543d0958a5f76ad407/service/elb/service.go#L32-L33
|
||||
// For backwards compatibility, if elbv2 endpoint is undefined, the elbv2 endpoint resolver should fall back to elb endpoint if any.
|
||||
if _, ok := endpointMap[elbv2.ServiceID]; !ok {
|
||||
if elbEp, ok := endpointMap[elb.ServiceID]; ok {
|
||||
logELBv2FallbackOnce.Do(func() {
|
||||
logrus.Infof("elbv2 endpoint is empty, using elb endpoint: %s", elbEp.URL)
|
||||
})
|
||||
endpointMap[elbv2.ServiceID] = typesaws.ServiceEndpoint{
|
||||
Name: elbv2.ServiceID,
|
||||
URL: elbEp.URL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &ServiceEndpointResolver{
|
||||
endpoints: endpointMap,
|
||||
endpointOptions: opts,
|
||||
@@ -103,6 +125,48 @@ func (s *EC2EndpointResolver) ResolveEndpoint(ctx context.Context, params ec2.En
|
||||
return ec2.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
|
||||
}
|
||||
|
||||
// ELBEndpointResolver implements EndpointResolverV2 interface for ELB (classic).
|
||||
type ELBEndpointResolver struct {
|
||||
*ServiceEndpointResolver
|
||||
}
|
||||
|
||||
// ResolveEndpoint for ELB.
|
||||
func (s *ELBEndpointResolver) ResolveEndpoint(ctx context.Context, params elb.EndpointParameters) (smithyendpoints.Endpoint, error) {
|
||||
params.UseDualStack = aws.Bool(s.endpointOptions.UseDualStack)
|
||||
params.UseFIPS = aws.Bool(s.endpointOptions.UseFIPS)
|
||||
|
||||
// If custom endpoint not found, return default endpoint for the service.
|
||||
endpoint, ok := s.endpoints[elb.ServiceID]
|
||||
if !ok {
|
||||
return elb.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
|
||||
}
|
||||
|
||||
params.Endpoint = aws.String(endpoint.URL)
|
||||
params.Region = aws.String(s.endpointOptions.Region)
|
||||
return elb.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
|
||||
}
|
||||
|
||||
// ELBV2EndpointResolver implements EndpointResolverV2 interface for ELBV2.
|
||||
type ELBV2EndpointResolver struct {
|
||||
*ServiceEndpointResolver
|
||||
}
|
||||
|
||||
// ResolveEndpoint for ELBV2.
|
||||
func (s *ELBV2EndpointResolver) ResolveEndpoint(ctx context.Context, params elbv2.EndpointParameters) (smithyendpoints.Endpoint, error) {
|
||||
params.UseDualStack = aws.Bool(s.endpointOptions.UseDualStack)
|
||||
params.UseFIPS = aws.Bool(s.endpointOptions.UseFIPS)
|
||||
|
||||
// If custom endpoint not found, return default endpoint for the service.
|
||||
endpoint, ok := s.endpoints[elbv2.ServiceID]
|
||||
if !ok {
|
||||
return elbv2.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
|
||||
}
|
||||
|
||||
params.Endpoint = aws.String(endpoint.URL)
|
||||
params.Region = aws.String(s.endpointOptions.Region)
|
||||
return elbv2.NewDefaultEndpointResolverV2().ResolveEndpoint(ctx, params)
|
||||
}
|
||||
|
||||
// IAMEndpointResolver implements EndpointResolverV2 interface for IAM.
|
||||
type IAMEndpointResolver struct {
|
||||
*ServiceEndpointResolver
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
configv2 "github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/ec2"
|
||||
elbv2 "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2"
|
||||
elbv2types "github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2/types"
|
||||
@@ -275,19 +274,13 @@ func getHostedZoneIDForNLB(ctx context.Context, ic *installconfig.InstallConfig,
|
||||
return hzID, nil
|
||||
}
|
||||
|
||||
cfg, err := configv2.LoadDefaultConfig(ctx, configv2.WithRegion(ic.Config.Platform.AWS.Region))
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to load AWS config: %w", err)
|
||||
}
|
||||
|
||||
client := elbv2.NewFromConfig(cfg, func(options *elbv2.Options) {
|
||||
options.Region = ic.Config.Platform.AWS.Region
|
||||
for _, endpoint := range ic.Config.AWS.ServiceEndpoints {
|
||||
if strings.EqualFold(endpoint.Name, "elasticloadbalancing") {
|
||||
options.BaseEndpoint = aws.String(endpoint.URL)
|
||||
}
|
||||
}
|
||||
client, err := awsconfig.NewELBV2Client(ctx, awsconfig.EndpointOptions{
|
||||
Region: ic.Config.AWS.Region,
|
||||
Endpoints: ic.Config.AWS.ServiceEndpoints,
|
||||
})
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to create elbv2 client: %w", err)
|
||||
}
|
||||
|
||||
// If the HostedZoneID is not known, query from the LoadBalancer
|
||||
input := elbv2.DescribeLoadBalancersInput{
|
||||
|
||||
Reference in New Issue
Block a user