1package customizations
2
3import (
4	"github.com/aws/smithy-go/middleware"
5
6	"github.com/aws/aws-sdk-go-v2/aws"
7	"github.com/aws/aws-sdk-go-v2/service/internal/s3shared"
8
9	internalendpoints "github.com/aws/aws-sdk-go-v2/service/s3control/internal/endpoints"
10)
11
12// EndpointResolver interface for resolving service endpoints.
13type EndpointResolver interface {
14	ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
15}
16
17// EndpointResolverOptions is the service endpoint resolver options
18type EndpointResolverOptions = internalendpoints.Options
19
20// UpdateEndpointParameterAccessor represents accessor functions used by the middleware
21type UpdateEndpointParameterAccessor struct {
22	// GetARNInput points to a function that processes an input and returns ARN as string ptr,
23	// and bool indicating if ARN is supported or set.
24	GetARNInput func(interface{}) (*string, bool)
25
26	// GetOutpostIDInput points to a function that processes an input and returns a outpostID as string ptr,
27	// and bool indicating if outpostID is supported or set.
28	GetOutpostIDInput func(interface{}) (*string, bool)
29
30	// CopyInput creates a copy of input to be modified, this ensures the original input is not modified.
31	CopyInput func(interface{}) (interface{}, error)
32
33	// BackfillAccountID points to a function that validates the input for accountID. If absent, it populates the
34	// accountID. If present, but different than passed in accountID value throws an error
35	BackfillAccountID func(interface{}, string) error
36
37	// UpdateARNField points to a function that takes in a copy of input, updates the ARN field with
38	// the provided value and returns any error
39	UpdateARNField func(interface{}, string) error
40}
41
42// UpdateEndpointOptions provides the options for the UpdateEndpoint middleware setup.
43type UpdateEndpointOptions struct {
44
45	// Accessor are parameter accessors used by the middleware
46	Accessor UpdateEndpointParameterAccessor
47
48	// UseARNRegion indicates if region parsed from an ARN should be used.
49	UseARNRegion bool
50
51	// UseDualstack instructs if s3 dualstack endpoint config is enabled
52	UseDualstack bool
53
54	// EndpointResolver used to resolve endpoints. This may be a custom endpoint resolver
55	EndpointResolver EndpointResolver
56
57	// EndpointResolverOptions used by endpoint resolver
58	EndpointResolverOptions EndpointResolverOptions
59}
60
61// UpdateEndpoint adds the middleware to the middleware stack based on the UpdateEndpointOptions.
62func UpdateEndpoint(stack *middleware.Stack, options UpdateEndpointOptions) (err error) {
63	// validate and backfill account id from ARN
64	err = stack.Initialize.Add(&BackfillInput{
65		CopyInput:         options.Accessor.CopyInput,
66		BackfillAccountID: options.Accessor.BackfillAccountID,
67	}, middleware.Before)
68	if err != nil {
69		return err
70	}
71
72	// initial arn look up middleware should be before BackfillInput
73	err = stack.Initialize.Insert(&s3shared.ARNLookup{
74		GetARNValue: options.Accessor.GetARNInput,
75	}, (*BackfillInput)(nil).ID(), middleware.Before)
76	if err != nil {
77		return err
78	}
79
80	// process arn
81	err = stack.Serialize.Insert(&processARNResource{
82		CopyInput:               options.Accessor.CopyInput,
83		UpdateARNField:          options.Accessor.UpdateARNField,
84		UseARNRegion:            options.UseARNRegion,
85		UseDualstack:            options.UseDualstack,
86		EndpointResolver:        options.EndpointResolver,
87		EndpointResolverOptions: options.EndpointResolverOptions,
88	}, "OperationSerializer", middleware.Before)
89	if err != nil {
90		return err
91	}
92
93	// outpostID middleware
94	err = stack.Serialize.Insert(&processOutpostIDMiddleware{
95		GetOutpostID: options.Accessor.GetOutpostIDInput,
96		UseDualstack: options.UseDualstack,
97	}, (*processARNResource)(nil).ID(), middleware.Before)
98	if err != nil {
99		return err
100	}
101
102	// enable dual stack support
103	err = stack.Serialize.Insert(&s3shared.EnableDualstack{
104		UseDualstack:     options.UseDualstack,
105		DefaultServiceID: "s3-control",
106	}, "OperationSerializer", middleware.After)
107	if err != nil {
108		return err
109	}
110	return err
111}
112