Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds support for S3 Multi-region Access Point ARNs #1402

Merged
merged 13 commits into from
Sep 2, 2021
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