Skip to content

Commit

Permalink
Adds support for S3 Multi-region Access Point ARNs (#1402)
Browse files Browse the repository at this point in the history
* SigV4a Signer Implementation

* v4A Credential Wrapper

* Add Config Resolver for v4a Wrapping

* Regenerated Clients

* Presign Middleware Support

* Add configuration settings for disable mrap

* java codegen changes

* add customizations to support s3 mrap

* regenerate s3 client

* update mrap customization to use DNS helper utils, change behavior for custom endpoints, export a constant for v4a

* feedback and code cleanup

* delete v4a signer stale commit from aws package

* adds changelog entry for MRAP

Co-authored-by: Sean McGrail <[email protected]>
  • Loading branch information
skotambkar and skmcgrail authored Sep 2, 2021
1 parent 1412e59 commit 1898f5b
Show file tree
Hide file tree
Showing 134 changed files with 4,905 additions and 803 deletions.
10 changes: 10 additions & 0 deletions .changelog/0c026d00c5d04cf3a1a100108e4634da.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "0c026d00-c5d0-4cf3-a1a1-00108e4634da",
"type": "feature",
"description": "Add support for S3 Multi-Region Access Point ARNs.",
"modules": [
"config",
"service/internal/s3shared",
"service/s3"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ public class AwsHttpPresignURLClientGenerator implements GoIntegration {
private static final Symbol presignerInterfaceSymbol = SymbolUtils.createPointableSymbolBuilder(
"HTTPPresignerV4"
).build();

private static final Symbol presignerV4aInterfaceSymbol = SymbolUtils.createPointableSymbolBuilder(
"httpPresignerV4a"
).build();


private static final Symbol v4NewPresignerSymbol = SymbolUtils.createPointableSymbolBuilder(
"NewSigner", AwsGoDependency.AWS_SIGNER_V4
).build();
Expand Down Expand Up @@ -176,6 +182,9 @@ public void writeAdditionalFiles(
// generate presigner interface
writePresignInterface(writer, model, symbolProvider, serviceShape);

// generate s3 sigv4a presigner interface
writePresignV4aInterface(writer, model, symbolProvider, serviceShape);

// generate presign options and helpers per service
writePresignOptionType(writer, model, symbolProvider, serviceShape);

Expand Down Expand Up @@ -371,6 +380,37 @@ private void writeConvertToPresignMiddleware(

// s3 service needs expires and sets unsignedPayload if input is stream
if (isS3ServiceShape(model, serviceShape)) {

writer.write("");
writer.write("// add multi-region access point presigner");

// ==== multi-region access point support
Symbol PresignConstructor = SymbolUtils.createValueSymbolBuilder(
"NewPresignHTTPRequestMiddleware", AwsCustomGoDependency.S3_CUSTOMIZATION
).build();

Symbol PresignOptions = SymbolUtils.createValueSymbolBuilder(
"PresignHTTPRequestMiddlewareOptions", AwsCustomGoDependency.S3_CUSTOMIZATION
).build();

Symbol RegisterPresigningMiddleware = SymbolUtils.createValueSymbolBuilder(
"RegisterPreSigningMiddleware", AwsCustomGoDependency.S3_CUSTOMIZATION
).build();

writer.openBlock("signermv := $T($T{", "})",
PresignConstructor,PresignOptions, () -> {
writer.write("CredentialsProvider : options.Credentials,");
writer.write("V4Presigner : c.Presigner,");
writer.write("V4aPresigner : c.presignerV4a,");
writer.write("LogSigning : options.ClientLogMode.IsSigning(),");
});

writer.write("err = $T(stack, signermv)", RegisterPresigningMiddleware);
writer.write("if err != nil { return err }");
writer.write("");

// =======

writer.openBlock("if c.Expires < 0 {", "}", () -> {
writer.addUseImports(SmithyGoDependency.FMT);
writer.write(
Expand Down Expand Up @@ -437,6 +477,13 @@ private void writePresignClientType(
});
writer.write("");

if (isS3ServiceShape(model, serviceShape)) {
writer.openBlock("if options.presignerV4a == nil {", "}", () -> {
writer.write("options.presignerV4a = $L(c.options)", AwsSignatureVersion4.NEW_SIGNER_V4A_FUNC_NAME);
});
writer.write("");
}

writer.openBlock("return &$L{", "}", presignClientSymbol, () -> {
writer.write("client: c,");
writer.write("options: options,");
Expand Down Expand Up @@ -494,6 +541,38 @@ public void writePresignInterface(
writer.write("");
}


/**
* Writes the presigner sigv4a interface used by the presign url client
*/
public void writePresignV4aInterface(
GoWriter writer,
Model model,
SymbolProvider symbolProvider,
ServiceShape serviceShape
) {
if (!isS3ServiceShape(model, serviceShape)) {
return;
}

Symbol signerOptionsSymbol = SymbolUtils.createPointableSymbolBuilder(
"SignerOptions", AwsCustomGoDependency.S3_SIGV4A_CUSTOMIZATION).build();

writer.writeDocs(
String.format("%s represents sigv4a presigner interface used by presign url client",
presignerV4aInterfaceSymbol.getName())
);
writer.openBlock("type $T interface {", "}", presignerV4aInterfaceSymbol, () -> {
writer.write("PresignHTTP(");
writer.write("ctx context.Context, credentials v4a.Credentials, r *http.Request,");
writer.write("payloadHash string, service string, regionSet []string, signingTime time.Time,");
writer.write("optFns ...func($P),", signerOptionsSymbol);
writer.write(") (url string, signedHeader http.Header, err error)");
});

writer.write("");
}

/**
* Writes the Presign client's type and methods.
*
Expand Down Expand Up @@ -530,8 +609,13 @@ public void writePresignOptionType(
)
);
writer.write("Expires time.Duration");
writer.write("");

writer.writeDocs("presignerV4a is the presigner used by the presign url client");
writer.write("presignerV4a $T", presignerV4aInterfaceSymbol);
}
});

writer.openBlock("func (o $T) copy() $T {", "}", presignOptionsSymbol, presignOptionsSymbol, () -> {
writer.write("clientOptions := make([]func(*Options), len(o.ClientOptions))");
writer.write("copy(clientOptions, o.ClientOptions)");
Expand All @@ -548,15 +632,15 @@ public void writePresignOptionType(
writer.openBlock("func $L(optFns ...func(*Options)) func($P) {", "}",
PRESIGN_OPTIONS_FROM_CLIENT_OPTIONS, presignOptionsSymbol, () -> {
writer.write("return $L(optFns).options", presignOptionsFromClientOptionsInternal.getName());
});
});

writer.insertTrailingNewline();

writer.write("type $L []func(*Options)", presignOptionsFromClientOptionsInternal.getName());
writer.openBlock("func (w $L) options (o $P) {", "}",
presignOptionsFromClientOptionsInternal.getName(), presignOptionsSymbol, () -> {
writer.write("o.ClientOptions = append(o.ClientOptions, w...)");
}).insertTrailingNewline();
}).insertTrailingNewline();


// s3 specific helpers
Expand All @@ -569,15 +653,15 @@ public void writePresignOptionType(
writer.openBlock("func $L(dur time.Duration) func($P) {", "}",
PRESIGN_OPTIONS_FROM_EXPIRES, presignOptionsSymbol, () -> {
writer.write("return $L(dur).options", presignOptionsFromExpiresInternal.getName());
});
});

writer.insertTrailingNewline();

writer.write("type $L time.Duration", presignOptionsFromExpiresInternal.getName());
writer.openBlock("func (w $L) options (o $P) {", "}",
presignOptionsFromExpiresInternal.getName(), presignOptionsSymbol, () -> {
writer.write("o.Expires = time.Duration(w)");
}).insertTrailingNewline();
}).insertTrailingNewline();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public final class AwsSignatureVersion4 implements GoIntegration {
public static final String SIGNER_INTERFACE_NAME = "HTTPSignerV4";
public static final String SIGNER_CONFIG_FIELD_NAME = SIGNER_INTERFACE_NAME;
public static final String NEW_SIGNER_FUNC_NAME = "newDefaultV4Signer";
public static final String NEW_SIGNER_V4A_FUNC_NAME = "newDefaultV4aSigner";
public static final String SIGNER_RESOLVER = "resolve" + SIGNER_CONFIG_FIELD_NAME;

private static final List<String> DISABLE_URI_PATH_ESCAPE = ListUtils.of("com.amazonaws.s3#AmazonS3");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public final class AwsCustomGoDependency extends AwsGoDependency {
"service/dynamodb/internal/customizations", "ddbcust");
public static final GoDependency S3_CUSTOMIZATION = aws("service/s3/internal/customizations", "s3cust");
public static final GoDependency S3CONTROL_CUSTOMIZATION = aws("service/s3control/internal/customizations", "s3controlcust");
public static final GoDependency S3_SIGV4A_CUSTOMIZATION = aws("service/s3/internal/v4a");
public static final GoDependency APIGATEWAY_CUSTOMIZATION = aws(
"service/apigateway/internal/customizations", "agcust");
public static final GoDependency GLACIER_CUSTOMIZATION = aws(
Expand Down
Loading

0 comments on commit 1898f5b

Please sign in to comment.