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

feat: S3 Express support #1906

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft

feat: S3 Express support #1906

wants to merge 6 commits into from

Conversation

jbelkins
Copy link
Contributor

Description of changes

Provides customizations needed to utilize the S3 Express feature.

New/existing dependencies impact assessment, if applicable

No new dependencies were added to this change.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

continuation.resume(returning: fileBasedConfig)
} catch {
continuation.resume(throwing: error)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just fixes a concurrency issue; the nonconcurrent code called here should be called using withCheckedThrowingContinuation.

@@ -49,7 +50,7 @@ public class AWSSigV4Signer: SmithyHTTPAuthAPI.Signer {
)
}

guard let identity = identity as? AWSCredentialIdentity else {
guard let identity = (identity as? AWSCredentialIdentity) ?? (identity as? S3ExpressIdentity)?.awsCredentialIdentity else {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the CRT signer signs in S3 Express mode, it intakes the S3 Express credentials using the same Credentials type as with any other signing operation. So, when an S3ExpressIdentity is supplied, convert it to an AWS credential identity to pass into CRT (see private helper method below.)

import protocol SmithyHTTPAuthAPI.Signer
import struct Smithy.Attributes

public struct SigV4S3ExpressAuthScheme: AuthScheme {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This AuthScheme for S3 Express is basically the sigv4 auth scheme, but with a different scheme ID & signing algorithm.


import struct Smithy.AttributeKey

public enum AWSIdentityPropertyKeys {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These keys are used to pass data & components into identity resolvers in a type-safe manner.

clientConfig: DefaultClientConfiguration,
bucket: String
) async throws -> S3ExpressIdentity
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This protocol provides an interface for the S3 Express identity resolver to call S3 CreateSession to get credentials, without depending on the code-generated S3 client.

A SwiftIntegration on the S3 service provides conformance with this protocol.


import protocol SmithyIdentityAPI.Identity
import struct Foundation.Date

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A type to hold a S3 Express identity.

import struct Smithy.Attributes
import protocol SmithyIdentityAPI.IdentityResolver

public protocol S3ExpressIdentityResolver: IdentityResolver where IdentityT == S3ExpressIdentity {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A convenience declaration for the type of an S3 Express-specialized identity resolver.

authOption.signingProperties.set(key: SmithyHTTPAuthAPI.SigningPropertyKeys.signingRegion, value: param.signingRegion)
authOption.identityProperties.set(key: AWSSDKIdentity.AWSIdentityPropertyKeys.bucket, value: serviceParams.bucket)
authOption.identityProperties.set(key: AWSSDKIdentity.AWSIdentityPropertyKeys.s3ExpressClient, value: S3ExpressCreateSessionClient())
validAuthOptions.append(authOption)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note: this is generated code]

An auth option is added for S3 Express. The bucket name and a S3ExpressCreateSessionClient are added to identity properties for use by the S3 Express identity resolver.

@@ -22522,6 +22523,7 @@ extension GetObjectInput {
.withExpiration(value: expiration)
.withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4")
.withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: "aws.auth#sigv4a")
.withIdentityResolver(value: config.s3ExpressIdentityResolver, schemeID: "aws.auth#sigv4-s3express")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note: this is generated code]

For this & several other presigned URLs:

  • The client config is added to context so it can be used for the S3 CreateSession operation to get credentials later on.
  • The S3 Express identity resolver is added to the operation.

@@ -44,7 +45,7 @@ public class DefaultAWSAuthSchemePlugin: ClientRuntime.Plugin {
public func configureClient(clientConfiguration: ClientRuntime.ClientConfiguration) throws {
if let config = clientConfiguration as? S3Client.S3ClientConfiguration {
config.authSchemeResolver = DefaultS3AuthSchemeResolver()
config.authSchemes = [AWSSDKHTTPAuth.SigV4AuthScheme(), AWSSDKHTTPAuth.SigV4AAuthScheme()]
config.authSchemes = [AWSSDKHTTPAuth.SigV4AuthScheme(), AWSSDKHTTPAuth.SigV4AAuthScheme(), AWSSDKHTTPAuth.SigV4S3ExpressAuthScheme()]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Note: this is generated code]

SigV4S3ExpressAuthScheme is added to the service's auth schemes


if (ctx.service.isS3) {
updatedAuthSchemeList += writer.format("\$N()", AWSSDKHTTPAuthTypes.SigV4S3ExpressAuthScheme)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SigV4S3ExpressAuthScheme is added, but only to the S3 service client.

@@ -36,6 +37,9 @@ abstract class AWSHTTPProtocolCustomizations : DefaultHTTPProtocolCustomizations
}
writer.write(" .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: \$S)", "aws.auth#sigv4")
writer.write(" .withIdentityResolver(value: config.awsCredentialIdentityResolver, schemeID: \$S)", "aws.auth#sigv4a")
if (ctx.service.isS3) {
writer.write(" .withIdentityResolver(value: config.s3ExpressIdentityResolver, schemeID: \$S)", "aws.auth#sigv4-s3express")
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S3 Express identity resolver is added to the context for an operation, but only to the S3 service client.

)
write("validAuthOptions.append(authOption)")
dedent()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the S3 rules-based auth scheme resolver only, the S3 Express auth option is added.

(See the generated code above for more discussion of the content here.)

ctx: SwiftCodegenContext,
protocolGenerationContext: ProtocolGenerator.GenerationContext,
delegator: SwiftDelegator
) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method generates a file that creates a concrete implementation of the S3ExpressCreateSessionClient protocol.

An instance of this class is passed into the S3 credential provider, and allows that credential provider to call S3 without actually depending on S3.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant