From 998157685bfb82dca8de8d9a370289ab765bbd51 Mon Sep 17 00:00:00 2001 From: Eric Shepherd Date: Mon, 14 Oct 2024 17:49:21 +0000 Subject: [PATCH 1/3] First commit --- .../example_code/sts/AssumeRole/Package.swift | 40 +++ .../sts/AssumeRole/Sources/entry.swift | 244 ++++++++++++++++++ 2 files changed, 284 insertions(+) create mode 100644 swift/example_code/sts/AssumeRole/Package.swift create mode 100644 swift/example_code/sts/AssumeRole/Sources/entry.swift diff --git a/swift/example_code/sts/AssumeRole/Package.swift b/swift/example_code/sts/AssumeRole/Package.swift new file mode 100644 index 00000000000..2669cd7015f --- /dev/null +++ b/swift/example_code/sts/AssumeRole/Package.swift @@ -0,0 +1,40 @@ +// swift-tools-version:5.9 +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// The swift-tools-version declares the minimum version of Swift required to +// build this package. + +import PackageDescription + +let package = Package( + name: "AssumeRole", + // Let Xcode know the minimum Apple platforms supported. + platforms: [ + .macOS(.v11), + .iOS(.v13) + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + .package( + url: "https://github.com/awslabs/aws-sdk-swift", + from: "1.0.0" + ), + .package( + url: "https://github.com/apple/swift-argument-parser.git", + branch: "main" + ), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .executableTarget( + name: "AssumeRole", + dependencies: [ + .product(name: "AWSSTS", package: "aws-sdk-swift"), + .product(name: "AWSS3", package: "aws-sdk-swift"), + .product(name: "ArgumentParser", package: "swift-argument-parser"), + ], + path: "Sources"), + ] +) diff --git a/swift/example_code/sts/AssumeRole/Sources/entry.swift b/swift/example_code/sts/AssumeRole/Sources/entry.swift new file mode 100644 index 00000000000..361bd81f818 --- /dev/null +++ b/swift/example_code/sts/AssumeRole/Sources/entry.swift @@ -0,0 +1,244 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: Apache-2.0 +// +/// A simple example that shows how to use the AWS SDK for Swift to +/// authenticate using an AWS IAM role ARN. + +// snippet-start:[swift.static-resolver.imports] +import ArgumentParser +import AWSClientRuntime +import AWSS3 +import AWSSDKIdentity +import AWSSTS +import Foundation +import SmithyIdentity +// snippet-end:[swift.static-resolver.imports] + +struct ExampleCommand: ParsableCommand { + @Option(help: "AWS access key ID") + var accessKey: String + @Option(help: "AWS secret access key") + var secretKey: String + @Option(help: "Session token") + var sessionToken: String? = nil + @Argument(help: "ARN of the role to assume") + var roleArn: String + + static var configuration = CommandConfiguration( + commandName: "static-resolver", + abstract: """ + Authenticate using the access key, secret access key, and role provided. + Then list the available buckets. + """, + discussion: """ + This program uses the specified credentials when assuming the specified + role, then uses the credentials returned by the role to list the user's + buckets. This shows a couple of ways to use a + StaticAWSCredentialIdentityResolver object. + """ + ) + + /// Called by ``main()`` to do the actual running of the AWS + /// example. + // snippet-start:[swift.static-resolver.command.runasync] + func runAsync() async throws { + // Authenticate using the command line inputs. + var identityResolver: StaticAWSCredentialIdentityResolver? = nil + /* + do { + identityResolver = try getIdentityResolver(accessKey: accessKey, + secretKey: secretKey, sessionToken: sessionToken) + } catch { + print("ERROR: Unable to get identity resolver in runAsync:", + dump(error)) + throw error + } + */ + + // Assume the role. + + do { + // snippet-start: [swift.static-resolver.use-role-credentials] + let credentials = try await assumeRole(identityResolver: identityResolver, + roleArn: roleArn) + do { + identityResolver = try getIdentityResolver( + accessKey: credentials.accessKey, + secretKey: credentials.secret, + sessionToken: credentials.sessionToken + ) + } catch { + print("ERROR: Unable to authenticate using provided options:", + dump(error)) + throw error + } + // snippet-end: [swift.static-resolver.use-role-credentials] + } catch { + print("ERROR: Error assuming role in runAsync:", dump(error)) + throw AssumeRoleExampleError.assumeRoleFailed + } + + // Use the credential identity resolver to access AWS S3. + + do { + let names = try await getBucketNames(identityResolver: identityResolver) + + print("Found \(names.count) buckets:") + for name in names { + print(" \(name)") + } + } catch { + print("ERROR: Error getting bucket names in runAsync:", dump(error)) + throw error + } + } + // snippet-end:[swift.static-resolver.command.runasync] +} + +enum AssumeRoleExampleError: Error { + case assumeRoleFailed + case incompleteCredentials + case missingCredentials + + var errorDescription: String? { + switch self { + case .assumeRoleFailed: + return "Unable to assume the specified role." + case .incompleteCredentials: + return "AWS STS returned incomplete credentials." + case .missingCredentials: + return "AWS STS did not return any credentials for the specified role." + } + } +} + +// snippet-start:[swift.static-resolver.assumeRole-function] +func assumeRole(identityResolver: (any AWSCredentialIdentityResolver)?, + roleArn: String) async throws -> AWSCredentialIdentity { + let stsConfiguration = try await STSClient.STSClientConfiguration( + awsCredentialIdentityResolver: identityResolver + ) + let stsClient = STSClient(config: stsConfiguration) + + let input = AssumeRoleInput( + roleArn: roleArn, + roleSessionName: "Static-Resolver-Example" + ) + + // Assume the role and return the assigned credentials. + + do { + let output = try await stsClient.assumeRole(input: input) + + guard let credentials = output.credentials else { + throw AssumeRoleExampleError.missingCredentials + } + + guard let accessKey = credentials.accessKeyId, + let secretKey = credentials.secretAccessKey, + let sessionToken = credentials.sessionToken else { + throw AssumeRoleExampleError.incompleteCredentials + } + + // Return an `AWSCredentialIdentity` object with the temporary + // credentials. + + let awsCredentials = AWSCredentialIdentity( + accessKey: accessKey, + secret: secretKey, + sessionToken: sessionToken + ) + return awsCredentials + } +} +// snippet-end:[swift.static-resolver.assumeRole-function] + +// snippet-start:[s3.swift.intro.getbucketnames] +// Return an array containing the names of all available buckets. +// +// - Returns: An array of strings listing the buckets. +func getBucketNames(identityResolver: (any AWSCredentialIdentityResolver)?) + async throws -> [String] { + do { + // Get an S3Client with which to access Amazon S3. + // snippet-start:[s3.swift.intro.client-init] + let configuration = try await S3Client.S3ClientConfiguration( + awsCredentialIdentityResolver: identityResolver + ) + // configuration.region = "us-east-2" // Uncomment this to set the region programmatically. + let client = S3Client(config: configuration) + // snippet-end:[s3.swift.intro.client-init] + + // snippet-start:[s3.swift.intro.listbuckets] + // Use "Paginated" to get all the buckets. + // This lets the SDK handle the 'continuationToken' in "ListBucketsOutput". + let pages = client.listBucketsPaginated( + input: ListBucketsInput( maxBuckets: 10) + ) + // snippet-end:[s3.swift.intro.listbuckets] + + // Get the bucket names. + var bucketNames: [String] = [] + + do { + for try await page in pages { + guard let buckets = page.buckets else { + print("Error: no buckets returned.") + continue + } + + for bucket in buckets { + bucketNames.append(bucket.name ?? "") + } + } + + return bucketNames + } catch { + print("ERROR: listBuckets:", dump(error)) + throw error + } + } +} + +/// Create a credential identity resolver using access key and secret access +/// key. +/// +/// - Parameters: +/// - accessKey: A string containing the AWS access key ID. +/// - secretKey: A string containing the AWS secret access key. +/// - sessionToken: An optional string containing the session token. +/// - Throws: Re-throws errors from AWSSDKIdentity. +/// - Returns: A `StaticAWSCredentialIdentityResolver` that can be used when +/// configuring service clients. +func getIdentityResolver(accessKey: String, secretKey: String, + sessionToken: String?) + throws -> StaticAWSCredentialIdentityResolver { + let credentials = AWSCredentialIdentity( + accessKey: accessKey, + secret: secretKey, + //expiration: cognitoCredentials.expiration, + sessionToken: sessionToken + ) + + return try StaticAWSCredentialIdentityResolver(credentials) +} + +// snippet-end:[s3.swift.intro.getbucketnames] + +// snippet-start:[s3.swift.intro.main] +/// The program's asynchronous entry point. +@main +struct Main { + static func main() async { + let args = Array(CommandLine.arguments.dropFirst()) + + do { + let command = try ExampleCommand.parse(args) + try await command.runAsync() + } catch { + ExampleCommand.exit(withError: error) + } + } +} + +// snippet-end:[s3.swift.intro.main] From c9ff3b16c0086017e658f171a8029cccadb93772 Mon Sep 17 00:00:00 2001 From: Eric Shepherd Date: Wed, 16 Oct 2024 15:00:04 +0000 Subject: [PATCH 2/3] Add README for STS; cleanup Added the README.md file for the STS examples. Also, added and updated comments and snippet tags. --- .../sts/AssumeRole/Sources/entry.swift | 173 +++++++++++------- swift/example_code/sts/README.md | 89 +++++++++ 2 files changed, 192 insertions(+), 70 deletions(-) create mode 100644 swift/example_code/sts/README.md diff --git a/swift/example_code/sts/AssumeRole/Sources/entry.swift b/swift/example_code/sts/AssumeRole/Sources/entry.swift index 361bd81f818..b99d6de4c8b 100644 --- a/swift/example_code/sts/AssumeRole/Sources/entry.swift +++ b/swift/example_code/sts/AssumeRole/Sources/entry.swift @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 // /// A simple example that shows how to use the AWS SDK for Swift to -/// authenticate using an AWS IAM role ARN. +/// authenticate using optional static credentials and an AWS IAM role ARN. -// snippet-start:[swift.static-resolver.imports] +// snippet-start:[swift.AssumeRole.imports] import ArgumentParser import AWSClientRuntime import AWSS3 @@ -12,53 +12,59 @@ import AWSSDKIdentity import AWSSTS import Foundation import SmithyIdentity -// snippet-end:[swift.static-resolver.imports] +// snippet-end:[swift.AssumeRole.imports] struct ExampleCommand: ParsableCommand { @Option(help: "AWS access key ID") - var accessKey: String + var accessKey: String? = nil @Option(help: "AWS secret access key") - var secretKey: String + var secretKey: String? = nil @Option(help: "Session token") var sessionToken: String? = nil @Argument(help: "ARN of the role to assume") var roleArn: String static var configuration = CommandConfiguration( - commandName: "static-resolver", + commandName: "AssumeRole", abstract: """ - Authenticate using the access key, secret access key, and role provided. - Then list the available buckets. + Authenticate using the specified role, optionally using specified + access key, secret access key, and session token first. """, discussion: """ - This program uses the specified credentials when assuming the specified - role, then uses the credentials returned by the role to list the user's - buckets. This shows a couple of ways to use a + This program uses the specified access key, secret access key, and + optional session token, to request temporary credentials for the + specified role Then it uses the credentials to list the user's + Amazon S3 buckets. This shows a couple of ways to use a StaticAWSCredentialIdentityResolver object. """ ) /// Called by ``main()`` to do the actual running of the AWS /// example. - // snippet-start:[swift.static-resolver.command.runasync] + // snippet-start:[swift.AssumeRole.command.runasync] func runAsync() async throws { - // Authenticate using the command line inputs. + // If credentials are specified, create a credential identity + // resolver that uses them to authenticate. This identity will be used + // to ask for permission to use the specified role. + var identityResolver: StaticAWSCredentialIdentityResolver? = nil - /* - do { - identityResolver = try getIdentityResolver(accessKey: accessKey, - secretKey: secretKey, sessionToken: sessionToken) - } catch { - print("ERROR: Unable to get identity resolver in runAsync:", - dump(error)) - throw error + + if accessKey != nil && secretKey != nil { + do { + identityResolver = try getIdentityResolver(accessKey: accessKey, + secretKey: secretKey, sessionToken: sessionToken) + } catch { + print("ERROR: Unable to get identity resolver in runAsync:", + dump(error)) + throw error + } } - */ - // Assume the role. + // Assume the role using the credentials provided on the command line, + // or using the default credentials if none were specified. do { - // snippet-start: [swift.static-resolver.use-role-credentials] + // snippet-start: [swift.AssumeRole.use-role-credentials] let credentials = try await assumeRole(identityResolver: identityResolver, roleArn: roleArn) do { @@ -72,7 +78,7 @@ struct ExampleCommand: ParsableCommand { dump(error)) throw error } - // snippet-end: [swift.static-resolver.use-role-credentials] + // snippet-end: [swift.AssumeRole.use-role-credentials] } catch { print("ERROR: Error assuming role in runAsync:", dump(error)) throw AssumeRoleExampleError.assumeRoleFailed @@ -92,14 +98,21 @@ struct ExampleCommand: ParsableCommand { throw error } } - // snippet-end:[swift.static-resolver.command.runasync] + // snippet-end:[swift.AssumeRole.command.runasync] } +/// An `Error` type used to return errors from the +/// `assumeRole(identityResolver: roleArn:)` function. enum AssumeRoleExampleError: Error { + /// An error indicating that the STS `AssumeRole` request failed. case assumeRoleFailed + /// An error indicating that the returned credentials were missing + /// required information. case incompleteCredentials + /// An error indicating that no credentials were returned by `AssumeRole`. case missingCredentials + /// Return a human-readable explanation of the error. var errorDescription: String? { switch self { case .assumeRoleFailed: @@ -112,7 +125,20 @@ enum AssumeRoleExampleError: Error { } } -// snippet-start:[swift.static-resolver.assumeRole-function] +// snippet-start:[swift.AssumeRole.assumeRole-function] +/// Assume the specified role. If any kind of credential identity resolver is +/// specified, that identity is adopted before assuming the role. +/// +/// - Parameters: +/// - identityResolver: Any kind of `AWSCredentialIdentityResolver`. If +/// provided, this identity is adopted before attempting to assume the +/// specified role. +/// - roleArn: The ARN of the AWS role to assume. +/// +/// - Throws: Re-throws STS errors. Also can throw any +/// `AssumeRoleExampleError`. +/// - Returns: An `AWSCredentialIdentity` containing the temporary credentials +/// assigned. func assumeRole(identityResolver: (any AWSCredentialIdentityResolver)?, roleArn: String) async throws -> AWSCredentialIdentity { let stsConfiguration = try await STSClient.STSClientConfiguration( @@ -120,62 +146,65 @@ func assumeRole(identityResolver: (any AWSCredentialIdentityResolver)?, ) let stsClient = STSClient(config: stsConfiguration) + // Assume the role and return the assigned credentials. + + // snippet-start: [swift.sts.AssumeRole] let input = AssumeRoleInput( roleArn: roleArn, - roleSessionName: "Static-Resolver-Example" + roleSessionName: "AssumeRole-Example" ) - // Assume the role and return the assigned credentials. + let output = try await stsClient.assumeRole(input: input) - do { - let output = try await stsClient.assumeRole(input: input) - - guard let credentials = output.credentials else { - throw AssumeRoleExampleError.missingCredentials - } + guard let credentials = output.credentials else { + throw AssumeRoleExampleError.missingCredentials + } - guard let accessKey = credentials.accessKeyId, - let secretKey = credentials.secretAccessKey, - let sessionToken = credentials.sessionToken else { - throw AssumeRoleExampleError.incompleteCredentials - } + guard let accessKey = credentials.accessKeyId, + let secretKey = credentials.secretAccessKey, + let sessionToken = credentials.sessionToken else { + throw AssumeRoleExampleError.incompleteCredentials + } + // snippet-end: [swift.sts.AssumeRole] - // Return an `AWSCredentialIdentity` object with the temporary - // credentials. + // Return an `AWSCredentialIdentity` object with the temporary + // credentials. - let awsCredentials = AWSCredentialIdentity( - accessKey: accessKey, - secret: secretKey, - sessionToken: sessionToken - ) - return awsCredentials - } + let awsCredentials = AWSCredentialIdentity( + accessKey: accessKey, + secret: secretKey, + sessionToken: sessionToken + ) + return awsCredentials } -// snippet-end:[swift.static-resolver.assumeRole-function] +// snippet-end:[swift.AssumeRole.assumeRole-function] -// snippet-start:[s3.swift.intro.getbucketnames] -// Return an array containing the names of all available buckets. -// -// - Returns: An array of strings listing the buckets. +/// Return an array containing the names of all available buckets using +/// the specified credential identity resolver to authenticate. +/// +/// - Parameter identityResolver: Any type of `AWSCredentialIdentityResolver`, +/// used to authenticate and authorize the user for access to the bucket +/// names. +/// +/// - Throws: Re-throws errors from `ListBucketsPaginated`. +/// +/// - Returns: An array of strings listing the buckets. func getBucketNames(identityResolver: (any AWSCredentialIdentityResolver)?) async throws -> [String] { do { // Get an S3Client with which to access Amazon S3. - // snippet-start:[s3.swift.intro.client-init] + // snippet-start:[swift.AssumeRole.use-resolver] let configuration = try await S3Client.S3ClientConfiguration( awsCredentialIdentityResolver: identityResolver ) - // configuration.region = "us-east-2" // Uncomment this to set the region programmatically. let client = S3Client(config: configuration) - // snippet-end:[s3.swift.intro.client-init] - // snippet-start:[s3.swift.intro.listbuckets] - // Use "Paginated" to get all the buckets. - // This lets the SDK handle the 'continuationToken' in "ListBucketsOutput". + // Use "Paginated" to get all the buckets. This lets the SDK handle + // the 'continuationToken' in "ListBucketsOutput". let pages = client.listBucketsPaginated( input: ListBucketsInput( maxBuckets: 10) ) - // snippet-end:[s3.swift.intro.listbuckets] + // snippet-end:[swift.AssumeRole.use-resolver] // Get the bucket names. var bucketNames: [String] = [] @@ -183,7 +212,7 @@ func getBucketNames(identityResolver: (any AWSCredentialIdentityResolver)?) do { for try await page in pages { guard let buckets = page.buckets else { - print("Error: no buckets returned.") + print("Error: page is empty.") continue } @@ -210,22 +239,28 @@ func getBucketNames(identityResolver: (any AWSCredentialIdentityResolver)?) /// - Throws: Re-throws errors from AWSSDKIdentity. /// - Returns: A `StaticAWSCredentialIdentityResolver` that can be used when /// configuring service clients. -func getIdentityResolver(accessKey: String, secretKey: String, +func getIdentityResolver(accessKey: String?, secretKey: String?, sessionToken: String?) - throws -> StaticAWSCredentialIdentityResolver { + throws -> StaticAWSCredentialIdentityResolver? { + + if accessKey == nil || secretKey == nil { + return nil + } + + guard let accessKey = accessKey, + let secretKey = secretKey else { + return nil + } + let credentials = AWSCredentialIdentity( accessKey: accessKey, secret: secretKey, - //expiration: cognitoCredentials.expiration, sessionToken: sessionToken ) return try StaticAWSCredentialIdentityResolver(credentials) } -// snippet-end:[s3.swift.intro.getbucketnames] - -// snippet-start:[s3.swift.intro.main] /// The program's asynchronous entry point. @main struct Main { @@ -240,5 +275,3 @@ struct Main { } } } - -// snippet-end:[s3.swift.intro.main] diff --git a/swift/example_code/sts/README.md b/swift/example_code/sts/README.md new file mode 100644 index 00000000000..0547ddec2ff --- /dev/null +++ b/swift/example_code/sts/README.md @@ -0,0 +1,89 @@ +# AWS STS code examples for the SDK for Swift + +## Overview + +Shows how to use the AWS SDK for Swift to work with AWS Security Token Service (AWS STS). + + + + +_AWS STS creates and provides trusted users with temporary security credentials that can control access to your AWS resources._ + +## ⚠ Important + +* Running this code might result in charges to your AWS account. For more details, see [AWS Pricing](https://aws.amazon.com/pricing/) and [Free Tier](https://aws.amazon.com/free/). +* Running the tests might result in charges to your AWS account. +* We recommend that you grant your code least privilege. At most, grant only the minimum permissions required to perform the task. For more information, see [Grant least privilege](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege). +* This code is not tested in every AWS Region. For more information, see [AWS Regional Services](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services). + + + + +## Code examples + +### Prerequisites + +For prerequisites, see the [README](../../README.md#Prerequisites) in the `swift` folder. + + + + + +### Single actions + +Code excerpts that show you how to call individual service functions. + +- [AssumeRole](../iam/basics/Sources/ServiceHandler/ServiceHandlerSTS.swift#L160) + + + + + +## Run the examples + +### Instructions + +To build any of these examples from a terminal window, navigate into its +directory, then use the following command: + +``` +$ swift build +``` + +To build one of these examples in Xcode, navigate to the example's directory +(such as the `ListUsers` directory, to build that example). Then type `xed.` +to open the example directory in Xcode. You can then use standard Xcode build +and run commands. + + + + + + +### Tests + +⚠ Running tests might result in charges to your AWS account. + + +To find instructions for running these tests, see the [README](../../README.md#Tests) +in the `swift` folder. + + + + + + +## Additional resources + +- [AWS STS User Guide](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp.html) +- [AWS STS API Reference](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) +- [SDK for Swift AWS STS reference](https://sdk.amazonaws.com/swift/api/awssts/latest/documentation/awssts) + + + + +--- + +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + +SPDX-License-Identifier: Apache-2.0 \ No newline at end of file From 2f18bff5018f7e386dd22f207ad2ff997ddcba2d Mon Sep 17 00:00:00 2001 From: Eric Shepherd Date: Wed, 16 Oct 2024 15:05:28 +0000 Subject: [PATCH 3/3] Use better snippet tag names --- .../sts/AssumeRole/Sources/entry.swift | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/swift/example_code/sts/AssumeRole/Sources/entry.swift b/swift/example_code/sts/AssumeRole/Sources/entry.swift index b99d6de4c8b..9f8dabb1d39 100644 --- a/swift/example_code/sts/AssumeRole/Sources/entry.swift +++ b/swift/example_code/sts/AssumeRole/Sources/entry.swift @@ -4,7 +4,7 @@ /// A simple example that shows how to use the AWS SDK for Swift to /// authenticate using optional static credentials and an AWS IAM role ARN. -// snippet-start:[swift.AssumeRole.imports] +// snippet-start:[swift.sts.AssumeRole.imports] import ArgumentParser import AWSClientRuntime import AWSS3 @@ -12,7 +12,7 @@ import AWSSDKIdentity import AWSSTS import Foundation import SmithyIdentity -// snippet-end:[swift.AssumeRole.imports] +// snippet-end:[swift.sts.AssumeRole.imports] struct ExampleCommand: ParsableCommand { @Option(help: "AWS access key ID") @@ -41,7 +41,7 @@ struct ExampleCommand: ParsableCommand { /// Called by ``main()`` to do the actual running of the AWS /// example. - // snippet-start:[swift.AssumeRole.command.runasync] + // snippet-start:[swift.sts.AssumeRole.command.runasync] func runAsync() async throws { // If credentials are specified, create a credential identity // resolver that uses them to authenticate. This identity will be used @@ -64,7 +64,7 @@ struct ExampleCommand: ParsableCommand { // or using the default credentials if none were specified. do { - // snippet-start: [swift.AssumeRole.use-role-credentials] + // snippet-start: [swift.sts.AssumeRole] let credentials = try await assumeRole(identityResolver: identityResolver, roleArn: roleArn) do { @@ -78,7 +78,7 @@ struct ExampleCommand: ParsableCommand { dump(error)) throw error } - // snippet-end: [swift.AssumeRole.use-role-credentials] + // snippet-end: [swift.sts.AssumeRole] } catch { print("ERROR: Error assuming role in runAsync:", dump(error)) throw AssumeRoleExampleError.assumeRoleFailed @@ -98,7 +98,7 @@ struct ExampleCommand: ParsableCommand { throw error } } - // snippet-end:[swift.AssumeRole.command.runasync] + // snippet-end:[swift.sts.AssumeRole.command.runasync] } /// An `Error` type used to return errors from the @@ -125,7 +125,7 @@ enum AssumeRoleExampleError: Error { } } -// snippet-start:[swift.AssumeRole.assumeRole-function] +// snippet-start:[swift.sts.AssumeRole.assumeRole-function] /// Assume the specified role. If any kind of credential identity resolver is /// specified, that identity is adopted before assuming the role. /// @@ -148,7 +148,7 @@ func assumeRole(identityResolver: (any AWSCredentialIdentityResolver)?, // Assume the role and return the assigned credentials. - // snippet-start: [swift.sts.AssumeRole] + // snippet-start: [swift.sts.sts.AssumeRole] let input = AssumeRoleInput( roleArn: roleArn, roleSessionName: "AssumeRole-Example" @@ -165,7 +165,7 @@ func assumeRole(identityResolver: (any AWSCredentialIdentityResolver)?, let sessionToken = credentials.sessionToken else { throw AssumeRoleExampleError.incompleteCredentials } - // snippet-end: [swift.sts.AssumeRole] + // snippet-end: [swift.sts.sts.AssumeRole] // Return an `AWSCredentialIdentity` object with the temporary // credentials. @@ -177,7 +177,7 @@ func assumeRole(identityResolver: (any AWSCredentialIdentityResolver)?, ) return awsCredentials } -// snippet-end:[swift.AssumeRole.assumeRole-function] +// snippet-end:[swift.sts.AssumeRole.assumeRole-function] /// Return an array containing the names of all available buckets using /// the specified credential identity resolver to authenticate. @@ -193,7 +193,7 @@ func getBucketNames(identityResolver: (any AWSCredentialIdentityResolver)?) async throws -> [String] { do { // Get an S3Client with which to access Amazon S3. - // snippet-start:[swift.AssumeRole.use-resolver] + // snippet-start:[swift.sts.AssumeRole.use-resolver] let configuration = try await S3Client.S3ClientConfiguration( awsCredentialIdentityResolver: identityResolver ) @@ -204,7 +204,7 @@ func getBucketNames(identityResolver: (any AWSCredentialIdentityResolver)?) let pages = client.listBucketsPaginated( input: ListBucketsInput( maxBuckets: 10) ) - // snippet-end:[swift.AssumeRole.use-resolver] + // snippet-end:[swift.sts.AssumeRole.use-resolver] // Get the bucket names. var bucketNames: [String] = []