Skip to content
This repository was archived by the owner on Jul 31, 2025. It is now read-only.

Commit 39a0852

Browse files
authored
Presigned URL generation for Neptune and DocDB CopyDBClusterSnapshot & CreateDBCluster (#3782)
1 parent c30a7b2 commit 39a0852

File tree

9 files changed

+695
-4
lines changed

9 files changed

+695
-4
lines changed

CHANGELOG_PENDING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
### SDK Features
22

33
### SDK Enhancements
4+
* `service/neptune`: Support for PreSignedUrl generation for CopyDBClusterSnapshot and CreateDBCluster operations. ([#3782](https://github.com/aws/aws-sdk-go/pull/3782))
5+
* `service/docdb`: Support for PreSignedUrl generation for CopyDBClusterSnapshot and CreateDBCluster operations. ([#3782](https://github.com/aws/aws-sdk-go/pull/3782))
46

57
### SDK Bugs

private/model/api/customization_passes.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ func (a *API) customizationPasses() error {
4949
"s3control": s3ControlCustomizations,
5050
"cloudfront": cloudfrontCustomizations,
5151
"rds": rdsCustomizations,
52+
"neptune": neptuneCustomizations,
53+
"docdb": docdbCustomizations,
5254

5355
// Disable endpoint resolving for services that require customer
5456
// to provide endpoint them selves.
@@ -327,7 +329,34 @@ func rdsCustomizations(a *API) error {
327329
"CreateDBClusterInput",
328330
"StartDBInstanceAutomatedBackupsReplicationInput",
329331
}
330-
for _, input := range inputs {
332+
generatePresignedURL(a, inputs)
333+
return nil
334+
}
335+
336+
// neptuneCustomizations are customization for the service/neptune. This adds
337+
// non-modeled fields used for presigning.
338+
func neptuneCustomizations(a *API) error {
339+
inputs := []string{
340+
"CopyDBClusterSnapshotInput",
341+
"CreateDBClusterInput",
342+
}
343+
generatePresignedURL(a, inputs)
344+
return nil
345+
}
346+
347+
// neptuneCustomizations are customization for the service/neptune. This adds
348+
// non-modeled fields used for presigning.
349+
func docdbCustomizations(a *API) error {
350+
inputs := []string{
351+
"CopyDBClusterSnapshotInput",
352+
"CreateDBClusterInput",
353+
}
354+
generatePresignedURL(a, inputs)
355+
return nil
356+
}
357+
358+
func generatePresignedURL(a *API, inputShapes []string) {
359+
for _, input := range inputShapes {
331360
if ref, ok := a.Shapes[input]; ok {
332361
ref.MemberRefs["SourceRegion"] = &ShapeRef{
333362
Documentation: docstring(`SourceRegion is the source region where the resource exists. This is not sent over the wire and is only used for presigning. This value should always have the same region as the source ARN.`),
@@ -342,8 +371,6 @@ func rdsCustomizations(a *API) error {
342371
}
343372
}
344373
}
345-
346-
return nil
347374
}
348375

349376
func disableEndpointResolving(a *API) error {

service/docdb/api.go

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

service/docdb/customizations.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package docdb
2+
3+
import (
4+
"time"
5+
6+
"github.com/aws/aws-sdk-go/aws"
7+
"github.com/aws/aws-sdk-go/aws/awsutil"
8+
"github.com/aws/aws-sdk-go/aws/endpoints"
9+
"github.com/aws/aws-sdk-go/aws/request"
10+
)
11+
12+
func init() {
13+
ops := []string{
14+
opCopyDBClusterSnapshot,
15+
opCreateDBCluster,
16+
}
17+
initRequest = func(r *request.Request) {
18+
for _, operation := range ops {
19+
if r.Operation.Name == operation {
20+
r.Handlers.Build.PushFront(fillPresignedURL)
21+
}
22+
}
23+
}
24+
}
25+
26+
func fillPresignedURL(r *request.Request) {
27+
fns := map[string]func(r *request.Request){
28+
opCopyDBClusterSnapshot: copyDBClusterSnapshotPresign,
29+
opCreateDBCluster: createDBClusterPresign,
30+
}
31+
if !r.ParamsFilled() {
32+
return
33+
}
34+
if f, ok := fns[r.Operation.Name]; ok {
35+
f(r)
36+
}
37+
}
38+
39+
func copyDBClusterSnapshotPresign(r *request.Request) {
40+
originParams := r.Params.(*CopyDBClusterSnapshotInput)
41+
42+
if originParams.SourceRegion == nil || originParams.PreSignedUrl != nil || originParams.DestinationRegion != nil {
43+
return
44+
}
45+
46+
originParams.DestinationRegion = r.Config.Region
47+
// preSignedUrl is not required for instances in the same region.
48+
if *originParams.SourceRegion == *originParams.DestinationRegion {
49+
return
50+
}
51+
52+
newParams := awsutil.CopyOf(r.Params).(*CopyDBClusterSnapshotInput)
53+
originParams.PreSignedUrl = presignURL(r, originParams.SourceRegion, newParams)
54+
}
55+
56+
func createDBClusterPresign(r *request.Request) {
57+
originParams := r.Params.(*CreateDBClusterInput)
58+
59+
if originParams.SourceRegion == nil || originParams.PreSignedUrl != nil || originParams.DestinationRegion != nil {
60+
return
61+
}
62+
63+
originParams.DestinationRegion = r.Config.Region
64+
// preSignedUrl is not required for instances in the same region.
65+
if *originParams.SourceRegion == *originParams.DestinationRegion {
66+
return
67+
}
68+
69+
newParams := awsutil.CopyOf(r.Params).(*CreateDBClusterInput)
70+
originParams.PreSignedUrl = presignURL(r, originParams.SourceRegion, newParams)
71+
}
72+
73+
// presignURL will presign the request by using SoureRegion to sign with. SourceRegion is not
74+
// sent to the service, and is only used to not have the SDKs parsing ARNs.
75+
func presignURL(r *request.Request, sourceRegion *string, newParams interface{}) *string {
76+
cfg := r.Config.Copy(aws.NewConfig().
77+
WithEndpoint("").
78+
WithRegion(aws.StringValue(sourceRegion)))
79+
80+
clientInfo := r.ClientInfo
81+
resolved, err := r.Config.EndpointResolver.EndpointFor(
82+
EndpointsID, aws.StringValue(cfg.Region),
83+
func(opt *endpoints.Options) {
84+
opt.DisableSSL = aws.BoolValue(cfg.DisableSSL)
85+
opt.UseDualStack = aws.BoolValue(cfg.UseDualStack)
86+
},
87+
)
88+
if err != nil {
89+
r.Error = err
90+
return nil
91+
}
92+
93+
clientInfo.Endpoint = resolved.URL
94+
clientInfo.SigningRegion = resolved.SigningRegion
95+
96+
// Presign a request with modified params
97+
req := request.New(*cfg, clientInfo, r.Handlers, r.Retryer, r.Operation, newParams, r.Data)
98+
req.Operation.HTTPMethod = "GET"
99+
uri, err := req.Presign(5 * time.Minute) // 5 minutes should be enough.
100+
if err != nil { // bubble error back up to original request
101+
r.Error = err
102+
return nil
103+
}
104+
105+
// We have our URL, set it on params
106+
return &uri
107+
}

0 commit comments

Comments
 (0)