File: endpoint.go

package info (click to toggle)
golang-github-aws-aws-sdk-go-v2 1.24.1-2~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 554,032 kB
  • sloc: java: 15,941; makefile: 419; sh: 175
file content (143 lines) | stat: -rw-r--r-- 4,373 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package customizations

import (
	"context"
	"fmt"
	"net/url"
	"strings"

	"github.com/aws/aws-sdk-go-v2/aws"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	"github.com/aws/aws-sdk-go-v2/internal/v4a"
	"github.com/aws/aws-sdk-go-v2/service/eventbridge/internal/endpoints"
	"github.com/aws/smithy-go"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

// EndpointResolver interface for resolving service endpoints.
type EndpointResolver interface {
	ResolveEndpoint(region string, options endpoints.Options) (aws.Endpoint, error)
}

// UpdateEndpointOptions provides configuration options for the UpdateEndpoint middleware.
type UpdateEndpointOptions struct {
	GetEndpointIDFromInput  func(interface{}) (*string, bool)
	EndpointResolver        EndpointResolver
	EndpointResolverOptions endpoints.Options
}

// UpdateEndpoint is a middleware that handles routing an EventBridge operation to a multi-region endpoint.
func UpdateEndpoint(stack *middleware.Stack, options UpdateEndpointOptions) error {
	const serializerID = "OperationSerializer"

	return stack.Serialize.Insert(&updateEndpoint{
		getEndpointIDFromInput:  options.GetEndpointIDFromInput,
		endpointResolver:        options.EndpointResolver,
		endpointResolverOptions: options.EndpointResolverOptions,
	}, serializerID, middleware.Before)
}

type updateEndpoint struct {
	getEndpointIDFromInput  func(interface{}) (*string, bool)
	endpointResolver        EndpointResolver
	endpointResolverOptions endpoints.Options
}

func (u *updateEndpoint) ID() string {
	return "EventBridge:UpdateEndpoint"
}

func (u *updateEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (out middleware.SerializeOutput, metadata middleware.Metadata, err error) {
	if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
		return next.HandleSerialize(ctx, in)
	}

	// If getEndpointIDFromInput is nil but the middleware got attached just skip to the next handler
	if u.getEndpointIDFromInput == nil {
		return next.HandleSerialize(ctx, in)
	}

	value, ok := u.getEndpointIDFromInput(in.Parameters)
	if !ok || value == nil {
		return next.HandleSerialize(ctx, in)
	}

	req, ok := in.Request.(*smithyhttp.Request)
	if !ok {
		return out, metadata, fmt.Errorf("unknown transport type %T", req)
	}

	endpointID := aws.ToString(value)

	if len(endpointID) == 0 {
		return out, metadata, &smithy.SerializationError{
			Err: fmt.Errorf("EndpointId must not be a zero-length string"),
		}
	}

	if u.endpointResolverOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled {
		return out, metadata, &smithy.SerializationError{
			Err: fmt.Errorf("EventBridge multi-region endpoints do not support FIPS endpoint configuration"),
		}
	}

	labels := strings.Split(endpointID, ".")

	for _, label := range labels {
		if !smithyhttp.ValidHostLabel(label) {
			return out, metadata, &smithy.SerializationError{
				Err: fmt.Errorf("EndpointId is not a valid host label, %s", endpointID),
			}
		}
	}

	region := awsmiddleware.GetRegion(ctx)

	endpoint, err := u.endpointResolver.ResolveEndpoint(region, u.endpointResolverOptions)
	if err != nil {
		return out, metadata, &smithy.SerializationError{
			Err: err,
		}
	}

	if len(endpoint.SigningRegion) > 0 {
		region = endpoint.SigningRegion
	}

	// set signing region and version for MRAP
	endpoint.SigningRegion = "*"
	ctx = awsmiddleware.SetSigningRegion(ctx, endpoint.SigningRegion)
	ctx = SetSignerVersion(ctx, v4a.Version)

	if len(endpoint.SigningName) != 0 {
		ctx = awsmiddleware.SetSigningName(ctx, endpoint.SigningName)
	}

	if endpoint.Source == aws.EndpointSourceCustom {
		return next.HandleSerialize(ctx, in)
	}

	dnsSuffix, err := endpoints.GetDNSSuffixFromRegion(region, u.endpointResolverOptions)
	if err != nil {
		return out, metadata, &smithy.SerializationError{
			Err: err,
		}
	}

	// modify endpoint host to use s3-global host prefix
	scheme := strings.SplitN(endpoint.URL, "://", 2)

	// set url as per partition
	endpoint.URL = scheme[0] + "://" + endpointID + ".endpoint.events." + dnsSuffix

	// assign resolved endpoint url to request url
	req.URL, err = url.Parse(endpoint.URL)
	if err != nil {
		return out, metadata, &smithy.SerializationError{
			Err: fmt.Errorf("failed to parse endpoint URL: %w", err),
		}
	}

	return next.HandleSerialize(ctx, in)
}