...

Source file src/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go

Documentation: github.com/aws/aws-sdk-go-v2/service/ecr

     1  // Code generated by smithy-go-codegen DO NOT EDIT.
     2  
     3  package ecr
     4  
     5  import (
     6  	"context"
     7  	"errors"
     8  	"fmt"
     9  	"github.com/aws/aws-sdk-go-v2/aws"
    10  	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
    11  	"github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn"
    12  	internalendpoints "github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints"
    13  	smithyendpoints "github.com/aws/smithy-go/endpoints"
    14  	"github.com/aws/smithy-go/middleware"
    15  	"github.com/aws/smithy-go/ptr"
    16  	smithyhttp "github.com/aws/smithy-go/transport/http"
    17  	"net/http"
    18  	"net/url"
    19  	"strings"
    20  )
    21  
    22  // EndpointResolverOptions is the service endpoint resolver options
    23  type EndpointResolverOptions = internalendpoints.Options
    24  
    25  // EndpointResolver interface for resolving service endpoints.
    26  type EndpointResolver interface {
    27  	ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
    28  }
    29  
    30  var _ EndpointResolver = &internalendpoints.Resolver{}
    31  
    32  // NewDefaultEndpointResolver constructs a new service endpoint resolver
    33  func NewDefaultEndpointResolver() *internalendpoints.Resolver {
    34  	return internalendpoints.New()
    35  }
    36  
    37  // EndpointResolverFunc is a helper utility that wraps a function so it satisfies
    38  // the EndpointResolver interface. This is useful when you want to add additional
    39  // endpoint resolving logic, or stub out specific endpoints with custom values.
    40  type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error)
    41  
    42  func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
    43  	return fn(region, options)
    44  }
    45  
    46  // EndpointResolverFromURL returns an EndpointResolver configured using the
    47  // provided endpoint url. By default, the resolved endpoint resolver uses the
    48  // client region as signing region, and the endpoint source is set to
    49  // EndpointSourceCustom.You can provide functional options to configure endpoint
    50  // values for the resolved endpoint.
    51  func EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver {
    52  	e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom}
    53  	for _, fn := range optFns {
    54  		fn(&e)
    55  	}
    56  
    57  	return EndpointResolverFunc(
    58  		func(region string, options EndpointResolverOptions) (aws.Endpoint, error) {
    59  			if len(e.SigningRegion) == 0 {
    60  				e.SigningRegion = region
    61  			}
    62  			return e, nil
    63  		},
    64  	)
    65  }
    66  
    67  type ResolveEndpoint struct {
    68  	Resolver EndpointResolver
    69  	Options  EndpointResolverOptions
    70  }
    71  
    72  func (*ResolveEndpoint) ID() string {
    73  	return "ResolveEndpoint"
    74  }
    75  
    76  func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
    77  	out middleware.SerializeOutput, metadata middleware.Metadata, err error,
    78  ) {
    79  	if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
    80  		return next.HandleSerialize(ctx, in)
    81  	}
    82  
    83  	req, ok := in.Request.(*smithyhttp.Request)
    84  	if !ok {
    85  		return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
    86  	}
    87  
    88  	if m.Resolver == nil {
    89  		return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
    90  	}
    91  
    92  	eo := m.Options
    93  	eo.Logger = middleware.GetLogger(ctx)
    94  
    95  	var endpoint aws.Endpoint
    96  	endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo)
    97  	if err != nil {
    98  		nf := (&aws.EndpointNotFoundError{})
    99  		if errors.As(err, &nf) {
   100  			ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false)
   101  			return next.HandleSerialize(ctx, in)
   102  		}
   103  		return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
   104  	}
   105  
   106  	req.URL, err = url.Parse(endpoint.URL)
   107  	if err != nil {
   108  		return out, metadata, fmt.Errorf("failed to parse endpoint URL: %w", err)
   109  	}
   110  
   111  	if len(awsmiddleware.GetSigningName(ctx)) == 0 {
   112  		signingName := endpoint.SigningName
   113  		if len(signingName) == 0 {
   114  			signingName = "ecr"
   115  		}
   116  		ctx = awsmiddleware.SetSigningName(ctx, signingName)
   117  	}
   118  	ctx = awsmiddleware.SetEndpointSource(ctx, endpoint.Source)
   119  	ctx = smithyhttp.SetHostnameImmutable(ctx, endpoint.HostnameImmutable)
   120  	ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion)
   121  	ctx = awsmiddleware.SetPartitionID(ctx, endpoint.PartitionID)
   122  	return next.HandleSerialize(ctx, in)
   123  }
   124  func addResolveEndpointMiddleware(stack *middleware.Stack, o Options) error {
   125  	return stack.Serialize.Insert(&ResolveEndpoint{
   126  		Resolver: o.EndpointResolver,
   127  		Options:  o.EndpointOptions,
   128  	}, "OperationSerializer", middleware.Before)
   129  }
   130  
   131  func removeResolveEndpointMiddleware(stack *middleware.Stack) error {
   132  	_, err := stack.Serialize.Remove((&ResolveEndpoint{}).ID())
   133  	return err
   134  }
   135  
   136  type wrappedEndpointResolver struct {
   137  	awsResolver aws.EndpointResolverWithOptions
   138  }
   139  
   140  func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
   141  	return w.awsResolver.ResolveEndpoint(ServiceID, region, options)
   142  }
   143  
   144  type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error)
   145  
   146  func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) {
   147  	return a(service, region)
   148  }
   149  
   150  var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil)
   151  
   152  // withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver.
   153  // If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error,
   154  // and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked
   155  // via its middleware.
   156  //
   157  // If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated.
   158  func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver {
   159  	var resolver aws.EndpointResolverWithOptions
   160  
   161  	if awsResolverWithOptions != nil {
   162  		resolver = awsResolverWithOptions
   163  	} else if awsResolver != nil {
   164  		resolver = awsEndpointResolverAdaptor(awsResolver.ResolveEndpoint)
   165  	}
   166  
   167  	return &wrappedEndpointResolver{
   168  		awsResolver: resolver,
   169  	}
   170  }
   171  
   172  func finalizeClientEndpointResolverOptions(options *Options) {
   173  	options.EndpointOptions.LogDeprecated = options.ClientLogMode.IsDeprecatedUsage()
   174  
   175  	if len(options.EndpointOptions.ResolvedRegion) == 0 {
   176  		const fipsInfix = "-fips-"
   177  		const fipsPrefix = "fips-"
   178  		const fipsSuffix = "-fips"
   179  
   180  		if strings.Contains(options.Region, fipsInfix) ||
   181  			strings.Contains(options.Region, fipsPrefix) ||
   182  			strings.Contains(options.Region, fipsSuffix) {
   183  			options.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
   184  				options.Region, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "")
   185  			options.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
   186  		}
   187  	}
   188  
   189  }
   190  
   191  func resolveEndpointResolverV2(options *Options) {
   192  	if options.EndpointResolverV2 == nil {
   193  		options.EndpointResolverV2 = NewDefaultEndpointResolverV2()
   194  	}
   195  }
   196  
   197  // Utility function to aid with translating pseudo-regions to classical regions
   198  // with the appropriate setting indicated by the pseudo-region
   199  func mapPseudoRegion(pr string) (region string, fips aws.FIPSEndpointState) {
   200  	const fipsInfix = "-fips-"
   201  	const fipsPrefix = "fips-"
   202  	const fipsSuffix = "-fips"
   203  
   204  	if strings.Contains(pr, fipsInfix) ||
   205  		strings.Contains(pr, fipsPrefix) ||
   206  		strings.Contains(pr, fipsSuffix) {
   207  		region = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
   208  			pr, fipsInfix, "-"), fipsPrefix, ""), fipsSuffix, "")
   209  		fips = aws.FIPSEndpointStateEnabled
   210  	} else {
   211  		region = pr
   212  	}
   213  
   214  	return region, fips
   215  }
   216  
   217  // builtInParameterResolver is the interface responsible for resolving BuiltIn
   218  // values during the sourcing of EndpointParameters
   219  type builtInParameterResolver interface {
   220  	ResolveBuiltIns(*EndpointParameters) error
   221  }
   222  
   223  // builtInResolver resolves modeled BuiltIn values using only the members defined
   224  // below.
   225  type builtInResolver struct {
   226  	// The AWS region used to dispatch the request.
   227  	Region string
   228  
   229  	// Sourced BuiltIn value in a historical enabled or disabled state.
   230  	UseDualStack aws.DualStackEndpointState
   231  
   232  	// Sourced BuiltIn value in a historical enabled or disabled state.
   233  	UseFIPS aws.FIPSEndpointState
   234  
   235  	// Base endpoint that can potentially be modified during Endpoint resolution.
   236  	Endpoint *string
   237  }
   238  
   239  // Invoked at runtime to resolve BuiltIn Values. Only resolution code specific to
   240  // each BuiltIn value is generated.
   241  func (b *builtInResolver) ResolveBuiltIns(params *EndpointParameters) error {
   242  
   243  	region, _ := mapPseudoRegion(b.Region)
   244  	if len(region) == 0 {
   245  		return fmt.Errorf("Could not resolve AWS::Region")
   246  	} else {
   247  		params.Region = aws.String(region)
   248  	}
   249  	if b.UseDualStack == aws.DualStackEndpointStateEnabled {
   250  		params.UseDualStack = aws.Bool(true)
   251  	} else {
   252  		params.UseDualStack = aws.Bool(false)
   253  	}
   254  	if b.UseFIPS == aws.FIPSEndpointStateEnabled {
   255  		params.UseFIPS = aws.Bool(true)
   256  	} else {
   257  		params.UseFIPS = aws.Bool(false)
   258  	}
   259  	params.Endpoint = b.Endpoint
   260  	return nil
   261  }
   262  
   263  // EndpointParameters provides the parameters that influence how endpoints are
   264  // resolved.
   265  type EndpointParameters struct {
   266  	// The AWS region used to dispatch the request.
   267  	//
   268  	// Parameter is
   269  	// required.
   270  	//
   271  	// AWS::Region
   272  	Region *string
   273  
   274  	// When true, use the dual-stack endpoint. If the configured endpoint does not
   275  	// support dual-stack, dispatching the request MAY return an error.
   276  	//
   277  	// Defaults to
   278  	// false if no value is provided.
   279  	//
   280  	// AWS::UseDualStack
   281  	UseDualStack *bool
   282  
   283  	// When true, send this request to the FIPS-compliant regional endpoint. If the
   284  	// configured endpoint does not have a FIPS compliant endpoint, dispatching the
   285  	// request will return an error.
   286  	//
   287  	// Defaults to false if no value is
   288  	// provided.
   289  	//
   290  	// AWS::UseFIPS
   291  	UseFIPS *bool
   292  
   293  	// Override the endpoint used to send this request
   294  	//
   295  	// Parameter is
   296  	// required.
   297  	//
   298  	// SDK::Endpoint
   299  	Endpoint *string
   300  }
   301  
   302  // ValidateRequired validates required parameters are set.
   303  func (p EndpointParameters) ValidateRequired() error {
   304  	if p.UseDualStack == nil {
   305  		return fmt.Errorf("parameter UseDualStack is required")
   306  	}
   307  
   308  	if p.UseFIPS == nil {
   309  		return fmt.Errorf("parameter UseFIPS is required")
   310  	}
   311  
   312  	return nil
   313  }
   314  
   315  // WithDefaults returns a shallow copy of EndpointParameterswith default values
   316  // applied to members where applicable.
   317  func (p EndpointParameters) WithDefaults() EndpointParameters {
   318  	if p.UseDualStack == nil {
   319  		p.UseDualStack = ptr.Bool(false)
   320  	}
   321  
   322  	if p.UseFIPS == nil {
   323  		p.UseFIPS = ptr.Bool(false)
   324  	}
   325  	return p
   326  }
   327  
   328  // EndpointResolverV2 provides the interface for resolving service endpoints.
   329  type EndpointResolverV2 interface {
   330  	// ResolveEndpoint attempts to resolve the endpoint with the provided options,
   331  	// returning the endpoint if found. Otherwise an error is returned.
   332  	ResolveEndpoint(ctx context.Context, params EndpointParameters) (
   333  		smithyendpoints.Endpoint, error,
   334  	)
   335  }
   336  
   337  // resolver provides the implementation for resolving endpoints.
   338  type resolver struct{}
   339  
   340  func NewDefaultEndpointResolverV2() EndpointResolverV2 {
   341  	return &resolver{}
   342  }
   343  
   344  // ResolveEndpoint attempts to resolve the endpoint with the provided options,
   345  // returning the endpoint if found. Otherwise an error is returned.
   346  func (r *resolver) ResolveEndpoint(
   347  	ctx context.Context, params EndpointParameters,
   348  ) (
   349  	endpoint smithyendpoints.Endpoint, err error,
   350  ) {
   351  	params = params.WithDefaults()
   352  	if err = params.ValidateRequired(); err != nil {
   353  		return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err)
   354  	}
   355  	_UseDualStack := *params.UseDualStack
   356  	_UseFIPS := *params.UseFIPS
   357  
   358  	if exprVal := params.Endpoint; exprVal != nil {
   359  		_Endpoint := *exprVal
   360  		_ = _Endpoint
   361  		if _UseFIPS == true {
   362  			return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported")
   363  		}
   364  		if _UseDualStack == true {
   365  			return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported")
   366  		}
   367  		uriString := _Endpoint
   368  
   369  		uri, err := url.Parse(uriString)
   370  		if err != nil {
   371  			return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   372  		}
   373  
   374  		return smithyendpoints.Endpoint{
   375  			URI:     *uri,
   376  			Headers: http.Header{},
   377  		}, nil
   378  	}
   379  	if exprVal := params.Region; exprVal != nil {
   380  		_Region := *exprVal
   381  		_ = _Region
   382  		if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil {
   383  			_PartitionResult := *exprVal
   384  			_ = _PartitionResult
   385  			if _UseFIPS == true {
   386  				if _UseDualStack == true {
   387  					if true == _PartitionResult.SupportsFIPS {
   388  						if true == _PartitionResult.SupportsDualStack {
   389  							uriString := func() string {
   390  								var out strings.Builder
   391  								out.WriteString("https://api.ecr-fips.")
   392  								out.WriteString(_Region)
   393  								out.WriteString(".")
   394  								out.WriteString(_PartitionResult.DualStackDnsSuffix)
   395  								return out.String()
   396  							}()
   397  
   398  							uri, err := url.Parse(uriString)
   399  							if err != nil {
   400  								return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   401  							}
   402  
   403  							return smithyendpoints.Endpoint{
   404  								URI:     *uri,
   405  								Headers: http.Header{},
   406  							}, nil
   407  						}
   408  					}
   409  					return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both")
   410  				}
   411  			}
   412  			if _UseFIPS == true {
   413  				if true == _PartitionResult.SupportsFIPS {
   414  					if "aws" == _PartitionResult.Name {
   415  						uriString := func() string {
   416  							var out strings.Builder
   417  							out.WriteString("https://ecr-fips.")
   418  							out.WriteString(_Region)
   419  							out.WriteString(".amazonaws.com")
   420  							return out.String()
   421  						}()
   422  
   423  						uri, err := url.Parse(uriString)
   424  						if err != nil {
   425  							return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   426  						}
   427  
   428  						return smithyendpoints.Endpoint{
   429  							URI:     *uri,
   430  							Headers: http.Header{},
   431  						}, nil
   432  					}
   433  					if "aws-us-gov" == _PartitionResult.Name {
   434  						uriString := func() string {
   435  							var out strings.Builder
   436  							out.WriteString("https://ecr-fips.")
   437  							out.WriteString(_Region)
   438  							out.WriteString(".amazonaws.com")
   439  							return out.String()
   440  						}()
   441  
   442  						uri, err := url.Parse(uriString)
   443  						if err != nil {
   444  							return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   445  						}
   446  
   447  						return smithyendpoints.Endpoint{
   448  							URI:     *uri,
   449  							Headers: http.Header{},
   450  						}, nil
   451  					}
   452  					uriString := func() string {
   453  						var out strings.Builder
   454  						out.WriteString("https://api.ecr-fips.")
   455  						out.WriteString(_Region)
   456  						out.WriteString(".")
   457  						out.WriteString(_PartitionResult.DnsSuffix)
   458  						return out.String()
   459  					}()
   460  
   461  					uri, err := url.Parse(uriString)
   462  					if err != nil {
   463  						return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   464  					}
   465  
   466  					return smithyendpoints.Endpoint{
   467  						URI:     *uri,
   468  						Headers: http.Header{},
   469  					}, nil
   470  				}
   471  				return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS")
   472  			}
   473  			if _UseDualStack == true {
   474  				if true == _PartitionResult.SupportsDualStack {
   475  					uriString := func() string {
   476  						var out strings.Builder
   477  						out.WriteString("https://api.ecr.")
   478  						out.WriteString(_Region)
   479  						out.WriteString(".")
   480  						out.WriteString(_PartitionResult.DualStackDnsSuffix)
   481  						return out.String()
   482  					}()
   483  
   484  					uri, err := url.Parse(uriString)
   485  					if err != nil {
   486  						return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   487  					}
   488  
   489  					return smithyendpoints.Endpoint{
   490  						URI:     *uri,
   491  						Headers: http.Header{},
   492  					}, nil
   493  				}
   494  				return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack")
   495  			}
   496  			uriString := func() string {
   497  				var out strings.Builder
   498  				out.WriteString("https://api.ecr.")
   499  				out.WriteString(_Region)
   500  				out.WriteString(".")
   501  				out.WriteString(_PartitionResult.DnsSuffix)
   502  				return out.String()
   503  			}()
   504  
   505  			uri, err := url.Parse(uriString)
   506  			if err != nil {
   507  				return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
   508  			}
   509  
   510  			return smithyendpoints.Endpoint{
   511  				URI:     *uri,
   512  				Headers: http.Header{},
   513  			}, nil
   514  		}
   515  		return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.")
   516  	}
   517  	return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region")
   518  }
   519  

View as plain text