如何将 aws-sdk-go-v2 与 localstack 一起使用?

How do I use aws-sdk-go-v2 with localstack?

我正在尝试从 aws-sdk-go to aws-sdk-go-v2 迁移。但是,我在本地使用 localstack 来模拟一些 aws 服务,例如 sqs 和 s3。我不确定如何配置新的 sdk 以使用 localstack 端点而不是真实的端点。

例如,在 v1 SDK 中,我可以通过在此处设置端点将其指向 localstack:

session.Must(session.NewSession(&aws.Config{
    Region:   aws.String("us-east-1"),
    Endpoint: aws.String("http://localstack:4566"), 
}))

但是,如何在 v2 SDK 中执行此操作?我想我需要在 config 中设置一些参数,但我没有看到任何指定端点的选项。

这取决于您使用的服务。

为了初始化 Glue 客户端:

cfg, err := config.LoadDefaultConfig(context.Background())
if err != nil {
    panic(err)
}
glueConnection := glue.New(glue.Options{Credentials: cfg.Credentials, Region: cfg.Region})

因此,如果您仔细阅读 python 代码,主要是这段代码,您会看到:

https://github.com/localstack/localstack/blob/25ba1de8a8841af27feab54b8d55c80ac46349e2/localstack/services/edge.py#L115

然后我需要在使用 v2 aws golang sdk 时覆盖授权 header 以添加正确的结构。

我从 运行 aws cli 工具中选取结构并跟踪记录本地堆栈 docker 容器:

'Authorization': 'AWS4-HMAC-SHA256 Credential=AKIAR2X5NRNSRTCOJHCI/20210827/eu-west-1/sns/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=c69672d38631752ede15d90e7047a5183ebf3707a228decf6ec26e97fdbd02aa',

接下来我需要覆盖 http 客户端以添加 header in:

type s struct {
    cl http.Client
}

func (s s) Do(r *http.Request) (*http.Response, error) {
    r.Header.Add("authorization", "AWS4-HMAC-SHA256 Credential=AKIAR2X5NRNSRTCOJHCI/20210827/eu-west-1/sns/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=33fa777a3bb1241f30742419b8fab81945aa219050da6e29b34db16053661000")
    return s.cl.Do(r)
}

func NewSNS(endpoint, topicARN string) (awsPubSub, error) {
    cfg := aws.Config{
        EndpointResolver: aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
            return aws.Endpoint{
                PartitionID:       "aws",
                URL:               "http://localhost:4566",
                SigningRegion:     "eu-west-1",
                HostnameImmutable: true,
                // Source:        aws.EndpointSourceCustom,
            }, nil
        }),
        HTTPClient: s{http.Client{}},
    }

....

这非常耗时和痛苦,我很想知道更好的方法,但这暂时有效...