diff --git a/swift/example_code/iam/AttachRolePolicy/Sources/AttachRolePolicy/AttachRolePolicy.swift b/swift/example_code/iam/AttachRolePolicy/Sources/AttachRolePolicy/AttachRolePolicy.swift index dff561f8b76..0e9e58f36a5 100644 --- a/swift/example_code/iam/AttachRolePolicy/Sources/AttachRolePolicy/AttachRolePolicy.swift +++ b/swift/example_code/iam/AttachRolePolicy/Sources/AttachRolePolicy/AttachRolePolicy.swift @@ -34,11 +34,12 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.attachrolepolicy.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() + _ = try await serviceHandler.attachRolePolicy(role: rolename, policyArn: policyArn) } catch { + print("ERROR: runAsync:", dump(error)) throw error } } diff --git a/swift/example_code/iam/AttachRolePolicy/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/AttachRolePolicy/Sources/ServiceHandler/ServiceHandler.swift index 1b9990b8682..aa40c94b2d1 100644 --- a/swift/example_code/iam/AttachRolePolicy/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/AttachRolePolicy/Sources/ServiceHandler/ServiceHandler.swift @@ -26,18 +26,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.attachrolepolicy.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.attachrolepolicy.handler.init] @@ -48,7 +47,7 @@ public class ServiceHandler { /// - role: The name of the role to attach the policy to. /// - policyArn: The ARN of the policy to attach. /// - // snippet-start:[iam.swift.attachrolepolicy.handler.attachrolepolicy] + // snippet-start:[iam.swift.attachrolepolicy.handler.AttachRolePolicy] public func attachRolePolicy(role: String, policyArn: String) async throws { let input = AttachRolePolicyInput( policyArn: policyArn, @@ -57,9 +56,10 @@ public class ServiceHandler { do { _ = try await client.attachRolePolicy(input: input) } catch { + print("ERROR: Attaching a role policy:", dump(error)) throw error } } - // snippet-end:[iam.swift.attachrolepolicy.handler.attachrolepolicy] + // snippet-end:[iam.swift.attachrolepolicy.handler.AttachRolePolicy] } // snippet-end:[iam.swift.attachrolepolicy.handler] diff --git a/swift/example_code/iam/AttachRolePolicy/Tests/AttachRolePolicyTests/AttachRolePolicyTests.swift b/swift/example_code/iam/AttachRolePolicy/Tests/AttachRolePolicyTests/AttachRolePolicyTests.swift index aa3ab62c44c..4e4b7615e57 100644 --- a/swift/example_code/iam/AttachRolePolicy/Tests/AttachRolePolicyTests/AttachRolePolicyTests.swift +++ b/swift/example_code/iam/AttachRolePolicy/Tests/AttachRolePolicyTests/AttachRolePolicyTests.swift @@ -31,7 +31,7 @@ final class AttachRolePolicyTests: XCTestCase { super.setUp() Task() { - AttachRolePolicyTests.serviceHandler = await ServiceHandler() + AttachRolePolicyTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/CreateRole/Sources/CreateRole/CreateRole.swift b/swift/example_code/iam/CreateRole/Sources/CreateRole/CreateRole.swift index 90bdaa0eef3..69742fc0df7 100644 --- a/swift/example_code/iam/CreateRole/Sources/CreateRole/CreateRole.swift +++ b/swift/example_code/iam/CreateRole/Sources/CreateRole/CreateRole.swift @@ -31,9 +31,9 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.createrole.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() + // Get information about the user running this example. This user // will be granted the new role. let user = try await serviceHandler.getUser(name: nil) @@ -63,6 +63,7 @@ struct ExampleCommand: ParsableCommand { let roleID = try await serviceHandler.createRole(name: rolename, policyDocument: policyDocument) print("Created new role \(rolename) with ID \(roleID)") } catch { + print("ERROR: CreateRole runAsync:", dump(error)) throw error } } @@ -88,4 +89,4 @@ struct Main { } } // snippet-end:[iam.swift.createrole.main] -// snippet-end:[iam.swift.createrole.example] \ No newline at end of file +// snippet-end:[iam.swift.createrole.example] diff --git a/swift/example_code/iam/CreateRole/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/CreateRole/Sources/ServiceHandler/ServiceHandler.swift index e1ff91ea6c1..4b573947885 100644 --- a/swift/example_code/iam/CreateRole/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/CreateRole/Sources/ServiceHandler/ServiceHandler.swift @@ -27,18 +27,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.createrole.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.createrole.handler.init] @@ -48,7 +47,7 @@ public class ServiceHandler { /// - Parameter name: The name of the new IAM role. /// /// - Returns: The ID of the newly created role. - // snippet-start:[iam.swift.createrole.handler.createrole] + // snippet-start:[iam.swift.createrole.handler.CreateRole] public func createRole(name: String, policyDocument: String) async throws -> String { let input = CreateRoleInput( assumeRolePolicyDocument: policyDocument, @@ -64,10 +63,11 @@ public class ServiceHandler { } return id } catch { + print("ERROR: createRole:", dump(error)) throw error } } - // snippet-end:[iam.swift.createrole.handler.createrole] + // snippet-end:[iam.swift.createrole.handler.CreateRole] /// Get information about the specified user /// @@ -87,9 +87,10 @@ public class ServiceHandler { } return user } catch { + print("ERROR: getUser:", dump(error)) throw error } } // snippet-end:[iam.swift.createrole.handler.getuser] } -// snippet-end:[iam.swift.createrole.handler] \ No newline at end of file +// snippet-end:[iam.swift.createrole.handler] diff --git a/swift/example_code/iam/CreateRole/Tests/CreateRoleTests/CreateRoleTests.swift b/swift/example_code/iam/CreateRole/Tests/CreateRoleTests/CreateRoleTests.swift index 7ae16b7d3b4..ee820e87e35 100644 --- a/swift/example_code/iam/CreateRole/Tests/CreateRoleTests/CreateRoleTests.swift +++ b/swift/example_code/iam/CreateRole/Tests/CreateRoleTests/CreateRoleTests.swift @@ -29,9 +29,9 @@ final class CreateRoleTests: XCTestCase { override class func setUp() { let tdSem = TestWaiter(name: "Setup") super.setUp() - + Task() { - CreateRoleTests.serviceHandler = await ServiceHandler() + CreateRoleTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/CreateServiceLinkedRole/Sources/CreateServiceLinkedRole/CreateServiceLinkedRole.swift b/swift/example_code/iam/CreateServiceLinkedRole/Sources/CreateServiceLinkedRole/CreateServiceLinkedRole.swift index 4ea5885fac2..7259bf973ce 100644 --- a/swift/example_code/iam/CreateServiceLinkedRole/Sources/CreateServiceLinkedRole/CreateServiceLinkedRole.swift +++ b/swift/example_code/iam/CreateServiceLinkedRole/Sources/CreateServiceLinkedRole/CreateServiceLinkedRole.swift @@ -8,9 +8,10 @@ // snippet-start:[iam.swift.createservicelinkedrole.example] // snippet-start:[iam.swift.createservicelinkedrole.main.imports] +import ArgumentParser import Foundation import ServiceHandler -import ArgumentParser + // snippet-end:[iam.swift.createservicelinkedrole.main.imports] /// The command line arguments and options available for this @@ -37,13 +38,13 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.createservicelinkedrole.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() // Create the role and output information about it. let role = try await serviceHandler.createServiceLinkedRole( - service: servicename, suffix: suffix, description: description) - + service: servicename, suffix: suffix, description: description + ) + let roleID = role.roleId ?? "" let roleARN = role.arn ?? "" let roleDesc = role.description ?? "" @@ -62,11 +63,13 @@ struct ExampleCommand: ParsableCommand { print(" Created: \(dateFormatter.string(from: roleCreateDate))") print("Description: \(roleDesc)") } catch { + print("ERROR: CreateServiceLinkedRole runAsync:", dump(error)) throw error } } // snippet-end:[iam.swift.createservicelinkedrole.command.runasync] } + // snippet-end:[iam.swift.createservicelinkedrole.command] // @@ -84,7 +87,8 @@ struct Main { } catch { ExampleCommand.exit(withError: error) } - } + } } + // snippet-end:[iam.swift.createservicelinkedrole.main] // snippet-end:[iam.swift.createservicelinkedrole.example] \ No newline at end of file diff --git a/swift/example_code/iam/CreateServiceLinkedRole/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/CreateServiceLinkedRole/Sources/ServiceHandler/ServiceHandler.swift index 419c1910765..9fb6fe77651 100644 --- a/swift/example_code/iam/CreateServiceLinkedRole/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/CreateServiceLinkedRole/Sources/ServiceHandler/ServiceHandler.swift @@ -27,18 +27,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.createservicelinkedrole.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.createservicelinkedrole.handler.init] @@ -56,7 +55,7 @@ public class ServiceHandler { /// The `service` parameter should be a string derived that looks like a /// URL but has no `http://` at the beginning, such as /// `elasticbeanstalk.amazonaws.com`. - // snippet-start:[iam.swift.createservicelinkedrole.handler.createservicelinkedrole] + // snippet-start:[iam.swift.createservicelinkedrole.handler.CreateServiceLinkedRole] public func createServiceLinkedRole(service: String, suffix: String? = nil, description: String?) async throws -> IAMClientTypes.Role { let input = CreateServiceLinkedRoleInput( @@ -71,9 +70,10 @@ public class ServiceHandler { } return role } catch { + print("ERROR: createServiceLinkedRole:", dump(error)) throw error } } - // snippet-end:[iam.swift.createservicelinkedrole.handler.createservicelinkedrole] + // snippet-end:[iam.swift.createservicelinkedrole.handler.CreateServiceLinkedRole] } // snippet-end:[iam.swift.createservicelinkedrole.handler] diff --git a/swift/example_code/iam/CreateServiceLinkedRole/Tests/CreateServiceLinkedRoleTests/CreateServiceLinkedRoleTests.swift b/swift/example_code/iam/CreateServiceLinkedRole/Tests/CreateServiceLinkedRoleTests/CreateServiceLinkedRoleTests.swift index c43e51c2e37..8ff353ec911 100644 --- a/swift/example_code/iam/CreateServiceLinkedRole/Tests/CreateServiceLinkedRoleTests/CreateServiceLinkedRoleTests.swift +++ b/swift/example_code/iam/CreateServiceLinkedRole/Tests/CreateServiceLinkedRoleTests/CreateServiceLinkedRoleTests.swift @@ -29,9 +29,9 @@ final class CreateServiceLinkedRoleTests: XCTestCase { override class func setUp() { let tdSem = TestWaiter(name: "Setup") super.setUp() - + Task() { - CreateServiceLinkedRoleTests.serviceHandler = await ServiceHandler() + CreateServiceLinkedRoleTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/CreateUser/Sources/CreateUser/CreateUser.swift b/swift/example_code/iam/CreateUser/Sources/CreateUser/CreateUser.swift index 217acd164d2..2b4130a2419 100644 --- a/swift/example_code/iam/CreateUser/Sources/CreateUser/CreateUser.swift +++ b/swift/example_code/iam/CreateUser/Sources/CreateUser/CreateUser.swift @@ -31,12 +31,13 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.createuser.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - + do { + let serviceHandler = try await ServiceHandler() let userID = try await serviceHandler.createUser(name: username) print("Created new user \(username) with ID \(userID)") } catch { + print("ERROR: CreateUser runAsync:", dump(error)) throw error } } @@ -62,4 +63,4 @@ struct Main { } } // snippet-end:[iam.swift.createuser.main] -// snippet-end:[iam.swift.createuser.example] \ No newline at end of file +// snippet-end:[iam.swift.createuser.example] diff --git a/swift/example_code/iam/CreateUser/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/CreateUser/Sources/ServiceHandler/ServiceHandler.swift index d63a0dd648b..a278746f58c 100644 --- a/swift/example_code/iam/CreateUser/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/CreateUser/Sources/ServiceHandler/ServiceHandler.swift @@ -26,18 +26,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.createuser.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.createuser.handler.init] @@ -47,7 +46,7 @@ public class ServiceHandler { /// - Parameter name: The user's name. /// /// - Returns: The ID of the newly created user. - // snippet-start:[iam.swift.createuser.handler.createuser] + // snippet-start:[iam.swift.createuser.handler.CreateUser] public func createUser(name: String) async throws -> String { let input = CreateUserInput( userName: name @@ -62,9 +61,10 @@ public class ServiceHandler { } return id } catch { + print("ERROR: createUser:", dump(error)) throw error } } - // snippet-end:[iam.swift.createuser.handler.createuser] + // snippet-end:[iam.swift.createuser.handler.CreateUser] } // snippet-end:[iam.swift.createuser.handler] diff --git a/swift/example_code/iam/CreateUser/Tests/CreateUserTests/CreateUserTests.swift b/swift/example_code/iam/CreateUser/Tests/CreateUserTests/CreateUserTests.swift index 3ba5d258c42..a694c2f505e 100644 --- a/swift/example_code/iam/CreateUser/Tests/CreateUserTests/CreateUserTests.swift +++ b/swift/example_code/iam/CreateUser/Tests/CreateUserTests/CreateUserTests.swift @@ -31,7 +31,7 @@ final class CreateUserTests: XCTestCase { super.setUp() Task() { - CreateUserTests.serviceHandler = await ServiceHandler() + CreateUserTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/GetPolicy/Sources/GetPolicy/GetPolicy.swift b/swift/example_code/iam/GetPolicy/Sources/GetPolicy/GetPolicy.swift index f82ad9b413b..50a41b7e1c2 100644 --- a/swift/example_code/iam/GetPolicy/Sources/GetPolicy/GetPolicy.swift +++ b/swift/example_code/iam/GetPolicy/Sources/GetPolicy/GetPolicy.swift @@ -31,9 +31,8 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.getpolicy.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() let policy = try await serviceHandler.getPolicy(arn: arn) guard let policyName = policy.policyName, @@ -59,6 +58,7 @@ struct ExampleCommand: ParsableCommand { } } catch { + print("ERROR: CreateRole runAsync:", dump(error)) throw error } } @@ -84,4 +84,4 @@ struct Main { } } // snippet-end:[iam.swift.getpolicy.main] -// snippet-end:[iam.swift.getpolicy.example] \ No newline at end of file +// snippet-end:[iam.swift.getpolicy.example] diff --git a/swift/example_code/iam/GetPolicy/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/GetPolicy/Sources/ServiceHandler/ServiceHandler.swift index 8add7fb2bb0..ba10168cde1 100644 --- a/swift/example_code/iam/GetPolicy/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/GetPolicy/Sources/ServiceHandler/ServiceHandler.swift @@ -26,18 +26,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.getpolicy.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.getpolicy.handler.init] @@ -47,7 +46,7 @@ public class ServiceHandler { /// /// - Parameter arn: The ARN of the policy to return. /// - Returns: A `IAMClientTypes.Policy` with the policy information. - // snippet-start:[iam.swift.getpolicy.handler.getpolicy] + // snippet-start:[iam.swift.getpolicy.handler.GetPolicy] public func getPolicy(arn: String) async throws -> IAMClientTypes.Policy { let input = GetPolicyInput( policyArn: arn @@ -59,9 +58,10 @@ public class ServiceHandler { } return policy } catch { + print("ERROR: getPolicy:", dump(error)) throw error } } - // snippet-end:[iam.swift.getpolicy.handler.getpolicy] + // snippet-end:[iam.swift.getpolicy.handler.GetPolicy] } // snippet-end:[iam.swift.getpolicy.handler] diff --git a/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/GetPolicyTests.swift b/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/GetPolicyTests.swift index 2b0470e2016..4795a418a8a 100644 --- a/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/GetPolicyTests.swift +++ b/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/GetPolicyTests.swift @@ -29,9 +29,9 @@ final class GetPolicyTests: XCTestCase { override class func setUp() { let tdSem = TestWaiter(name: "Setup") super.setUp() - + Task() { - GetPolicyTests.serviceHandler = await ServiceHandler() + GetPolicyTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/ServiceHandler_Ext.swift b/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/ServiceHandler_Ext.swift index f713fb27d98..92cab1f778b 100644 --- a/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/ServiceHandler_Ext.swift +++ b/swift/example_code/iam/GetPolicy/Tests/GetPolicyTests/ServiceHandler_Ext.swift @@ -34,9 +34,9 @@ public extension ServiceHandler { guard let policy = output.policy else { throw ServiceHandlerError.noSuchPolicy } - guard let policyName = policy.policyName, - let policyID = policy.policyId, - let policyARN = policy.arn else { + guard let _ = policy.policyName, + let _ = policy.policyId, + let _ = policy.arn else { throw ServiceHandlerError.noSuchPolicy } return policy @@ -59,4 +59,4 @@ public extension ServiceHandler { throw error } } -} \ No newline at end of file +} diff --git a/swift/example_code/iam/GetRole/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/GetRole/Sources/ServiceHandler/ServiceHandler.swift index 302ed7b4165..166ecfb8f16 100644 --- a/swift/example_code/iam/GetRole/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/GetRole/Sources/ServiceHandler/ServiceHandler.swift @@ -48,7 +48,7 @@ public class ServiceHandler { /// - Parameter name: The name of the new IAM role. /// /// - Returns: The ID of the newly created role. - // snippet-start:[iam.swift.getrole.handler.getrole] + // snippet-start:[iam.swift.getrole.handler.GetRole] public func getRole(name: String) async throws -> IAMClientTypes.Role { let input = GetRoleInput( roleName: name @@ -63,6 +63,6 @@ public class ServiceHandler { throw error } } - // snippet-end:[iam.swift.getrole.handler.getrole] + // snippet-end:[iam.swift.getrole.handler.GetRole] } -// snippet-end:[iam.swift.getrole.handler] \ No newline at end of file +// snippet-end:[iam.swift.getrole.handler] diff --git a/swift/example_code/iam/ListAttachedRolePolicies/Sources/ListAttachedRolePolicies/ListAttachedRolePolicies.swift b/swift/example_code/iam/ListAttachedRolePolicies/Sources/ListAttachedRolePolicies/ListAttachedRolePolicies.swift index 49f8b574341..16dd14f7e2b 100644 --- a/swift/example_code/iam/ListAttachedRolePolicies/Sources/ListAttachedRolePolicies/ListAttachedRolePolicies.swift +++ b/swift/example_code/iam/ListAttachedRolePolicies/Sources/ListAttachedRolePolicies/ListAttachedRolePolicies.swift @@ -31,9 +31,10 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.listattachedrolepolicies.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() + do { + let serviceHandler = try await ServiceHandler() let attachedPolicies = try await serviceHandler.listAttachedRolePolicies(role: rolename) print("Found \(attachedPolicies.count) policies attached to role \(rolename)") @@ -41,6 +42,7 @@ struct ExampleCommand: ParsableCommand { print(" \(policy.policyName ?? "")") } } catch { + print("ERROR: ListAttachedRolePolicies runAsync:", dump(error)) throw error } } @@ -66,4 +68,4 @@ struct Main { } } // snippet-end:[iam.swift.listattachedrolepolicies.main] -// snippet-end:[iam.swift.listattachedrolepolicies.example] \ No newline at end of file +// snippet-end:[iam.swift.listattachedrolepolicies.example] diff --git a/swift/example_code/iam/ListAttachedRolePolicies/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/ListAttachedRolePolicies/Sources/ServiceHandler/ServiceHandler.swift index e692a457391..be86cb96de9 100644 --- a/swift/example_code/iam/ListAttachedRolePolicies/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/ListAttachedRolePolicies/Sources/ServiceHandler/ServiceHandler.swift @@ -2,15 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 /* - A class containing functions that interact with AWS services. -*/ + A class containing functions that interact with AWS services. + */ // snippet-start:[iam.swift.listattachedrolepolicies.handler] // snippet-start:[iam.swift.listattachedrolepolicies.handler.imports] -import Foundation +import AWSClientRuntime import AWSIAM import ClientRuntime -import AWSClientRuntime +import Foundation + // snippet-end:[iam.swift.listattachedrolepolicies.handler.imports] /// Errors returned by `ServiceHandler` functions. @@ -26,23 +27,23 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.listattachedrolepolicies.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } + // snippet-end:[iam.swift.listattachedrolepolicies.handler.init] - // snippet-start:[iam.swift.listattachedrolepolicies.handler.listattachedrolepolicies] + // snippet-start:[iam.swift.listattachedrolepolicies.handler.ListAttachedRolePolicies] /// Returns a list of AWS Identity and Access Management (IAM) policies /// that are attached to the role. @@ -53,29 +54,32 @@ public class ServiceHandler { /// describing each managed policy that's attached to the role. public func listAttachedRolePolicies(role: String) async throws -> [IAMClientTypes.AttachedPolicy] { var policyList: [IAMClientTypes.AttachedPolicy] = [] - var marker: String? = nil - var isTruncated: Bool - - repeat { - let input = ListAttachedRolePoliciesInput( - marker: marker, - roleName: role - ) - let output = try await client.listAttachedRolePolicies(input: input) - - guard let attachedPolicies = output.attachedPolicies else { - return policyList - } - for attachedPolicy in attachedPolicies { - policyList.append(attachedPolicy) + // Use "Paginated" to get all the objects. + // This lets the SDK handle the 'isTruncated' in "ListUsersOutput". + let input = ListAttachedRolePoliciesInput( + roleName: role + ) + let output = client.listAttachedRolePoliciesPaginated(input: input) + + do { + for try await page in output { + guard let attachedPolicies = page.attachedPolicies else { + print("Error: no attached policies returned.") + continue + } + for attachedPolicy in attachedPolicies { + policyList.append(attachedPolicy) + } } - marker = output.marker - isTruncated = output.isTruncated - } while isTruncated == true + } catch { + print("ERROR: listAttachedRolePolicies:", dump(error)) + throw error + } + return policyList } - // snippet-end:[iam.swift.listattachedrolepolicies.handler.listattachedrolepolicies] - + // snippet-end:[iam.swift.listattachedrolepolicies.handler.ListAttachedRolePolicies] } + // snippet-end:[iam.swift.listattachedrolepolicies.handler] diff --git a/swift/example_code/iam/ListAttachedRolePolicies/Tests/ListAttachedRolePoliciesTests/ListAttachedRolePoliciesTests.swift b/swift/example_code/iam/ListAttachedRolePolicies/Tests/ListAttachedRolePoliciesTests/ListAttachedRolePoliciesTests.swift index 0dda90fe634..92a31771697 100644 --- a/swift/example_code/iam/ListAttachedRolePolicies/Tests/ListAttachedRolePoliciesTests/ListAttachedRolePoliciesTests.swift +++ b/swift/example_code/iam/ListAttachedRolePolicies/Tests/ListAttachedRolePoliciesTests/ListAttachedRolePoliciesTests.swift @@ -31,7 +31,7 @@ final class ListAttachedRolePoliciesTests: XCTestCase { super.setUp() Task() { - ListAttachedRolePoliciesTests.serviceHandler = await ServiceHandler() + ListAttachedRolePoliciesTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/ListGroups/Sources/ListGroups/ListGroups.swift b/swift/example_code/iam/ListGroups/Sources/ListGroups/ListGroups.swift index 9b4d5075d21..2ffc0f12175 100644 --- a/swift/example_code/iam/ListGroups/Sources/ListGroups/ListGroups.swift +++ b/swift/example_code/iam/ListGroups/Sources/ListGroups/ListGroups.swift @@ -8,9 +8,10 @@ // snippet-start:[iam.swift.listgroups.example] // snippet-start:[iam.swift.listgroups.main.imports] +import ArgumentParser import Foundation import ServiceHandler -import ArgumentParser + // snippet-end:[iam.swift.listgroups.main.imports] /// The command line arguments and options available for this @@ -28,9 +29,9 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.listgroups.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() + let groups = try await serviceHandler.listGroups() print("Found \(groups.count) groups") for group in groups { @@ -42,6 +43,7 @@ struct ExampleCommand: ParsableCommand { } // snippet-end:[iam.swift.listgroups.command.runasync] } + // snippet-end:[iam.swift.listgroups.command] // @@ -59,7 +61,8 @@ struct Main { } catch { ExampleCommand.exit(withError: error) } - } + } } + // snippet-end:[iam.swift.listgroups.main] -// snippet-end:[iam.swift.listgroups.example] \ No newline at end of file +// snippet-end:[iam.swift.listgroups.example] diff --git a/swift/example_code/iam/ListGroups/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/ListGroups/Sources/ServiceHandler/ServiceHandler.swift index 8325c63f7f5..54db474f0be 100644 --- a/swift/example_code/iam/ListGroups/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/ListGroups/Sources/ServiceHandler/ServiceHandler.swift @@ -2,15 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 /* - A class containing functions that interact with AWS services. -*/ + A class containing functions that interact with AWS services. + */ // snippet-start:[iam.swift.listgroups.handler] // snippet-start:[iam.swift.listgroups.handler.imports] -import Foundation +import AWSClientRuntime import AWSIAM import ClientRuntime -import AWSClientRuntime +import Foundation + // snippet-end:[iam.swift.listgroups.handler.imports] /// A class containing all the code that interacts with the AWS SDK for Swift. @@ -18,50 +19,55 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.listgroups.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } + // snippet-end:[iam.swift.listgroups.handler.init] /// Returns a list of all AWS Identity and Access Management (IAM) group /// names. /// /// - Returns: An array of user records. - // snippet-start:[iam.swift.listgroups.handler.listgroups] + // snippet-start:[iam.swift.listgroups.handler.ListGroups] public func listGroups() async throws -> [String] { var groupList: [String] = [] - var marker: String? = nil - var isTruncated: Bool - - repeat { - let input = ListGroupsInput(marker: marker) - let output = try await client.listGroups(input: input) - - guard let groups = output.groups else { - return groupList - } - for group in groups { - if let name = group.groupName { - groupList.append(name) + // Use "Paginated" to get all the groups. + // This lets the SDK handle the 'isTruncated' property in "ListGroupsOutput". + let input = ListGroupsInput() + + let pages = client.listGroupsPaginated(input: input) + do { + for try await page in pages { + guard let groups = page.groups else { + print("Error: no groups returned.") + continue + } + + for group in groups { + if let name = group.groupName { + groupList.append(name) + } } } - marker = output.marker - isTruncated = output.isTruncated - } while isTruncated == true + } catch { + print("ERROR: listGroups:", dump(error)) + throw error + } return groupList } - // snippet-end:[iam.swift.listgroups.handler.listgroups] + // snippet-end:[iam.swift.listgroups.handler.ListGroups] } + // snippet-end:[iam.swift.listgroups.handler] diff --git a/swift/example_code/iam/ListGroups/Tests/ListGroupsTests/ListGroupsTests.swift b/swift/example_code/iam/ListGroups/Tests/ListGroupsTests/ListGroupsTests.swift index fb0497daca5..491152e5948 100644 --- a/swift/example_code/iam/ListGroups/Tests/ListGroupsTests/ListGroupsTests.swift +++ b/swift/example_code/iam/ListGroups/Tests/ListGroupsTests/ListGroupsTests.swift @@ -1,10 +1,7 @@ -// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -import XCTest -import Foundation -import AWSIAM import AWSClientRuntime +import AWSIAM import ClientRuntime +import Foundation import SwiftUtilities @testable import ServiceHandler @@ -21,6 +18,7 @@ final class ListGroupsTests: XCTestCase { /// /// This function sets up the following: /// + /// Configures the AWS SDK log system to only log errors. /// Initializes the service handler, which is used to call /// Amazon Identity and Access Management (IAM) functions. /// Initializes the demo cleanup handler, which is used to @@ -30,8 +28,8 @@ final class ListGroupsTests: XCTestCase { let tdSem = TestWaiter(name: "Setup") super.setUp() - Task() { - ListGroupsTests.serviceHandler = await ServiceHandler() + Task { + ListGroupsTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() @@ -42,7 +40,7 @@ final class ListGroupsTests: XCTestCase { override func tearDown() async throws { let tdSem = TestWaiter(name: "Teardown") - Task() { + Task { tdSem.signal() } tdSem.wait() @@ -55,7 +53,7 @@ final class ListGroupsTests: XCTestCase { let previousGroups = try await ListGroupsTests.serviceHandler!.listGroups() - for _ in 1...5 { + for _ in 1 ... 5 { let newName = String.uniqueName() _ = try await ListGroupsTests.serviceHandler!.createGroup(name: newName) createdGroups.append(newName) diff --git a/swift/example_code/iam/ListPolicies/Sources/ListPolicies/ListPolicies.swift b/swift/example_code/iam/ListPolicies/Sources/ListPolicies/ListPolicies.swift index d7c750d90ca..ae9bd33c9d0 100644 --- a/swift/example_code/iam/ListPolicies/Sources/ListPolicies/ListPolicies.swift +++ b/swift/example_code/iam/ListPolicies/Sources/ListPolicies/ListPolicies.swift @@ -29,9 +29,10 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.listpolicies.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - + do { + let serviceHandler = try await ServiceHandler() + let nameCol = TextTableColumn(header: "Policy Name") let idCol = TextTableColumn(header: "ID") let arnCol = TextTableColumn(header: "ARN") @@ -46,6 +47,7 @@ struct ExampleCommand: ParsableCommand { print(table.render()) } catch { + print("ERROR: ListPolicies::runAsync :", dump(error)) throw error } } @@ -71,4 +73,4 @@ struct Main { } } // snippet-end:[iam.swift.listpolicies.main] -// snippet-end:[iam.swift.listpolicies.example] \ No newline at end of file +// snippet-end:[iam.swift.listpolicies.example] diff --git a/swift/example_code/iam/ListPolicies/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/ListPolicies/Sources/ServiceHandler/ServiceHandler.swift index a121ab6378f..360b2448f0a 100644 --- a/swift/example_code/iam/ListPolicies/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/ListPolicies/Sources/ServiceHandler/ServiceHandler.swift @@ -2,15 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 /* - A class containing functions that interact with AWS services. -*/ + A class containing functions that interact with AWS services. + */ // snippet-start:[iam.swift.listpolicies.handler] // snippet-start:[iam.swift.listpolicies.handler.imports] -import Foundation +import AWSClientRuntime import AWSIAM import ClientRuntime -import AWSClientRuntime +import Foundation + // snippet-end:[iam.swift.listpolicies.handler.imports] /// Errors returned by `ServiceHandler` functions. @@ -26,18 +27,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.listpolicies.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.listpolicies.handler.init] @@ -46,33 +46,40 @@ public class ServiceHandler { /// (IAM) policy names. /// /// - Returns: An array of user records. - // snippet-start:[iam.swift.listpolicies.handler.listpolicies] + // snippet-start:[iam.swift.listpolicies.handler.ListPolicies] public func listPolicies() async throws -> [MyPolicyRecord] { var policyList: [MyPolicyRecord] = [] - var marker: String? = nil - var isTruncated: Bool - - repeat { - let input = ListPoliciesInput(marker: marker) - let output = try await client.listPolicies(input: input) - - guard let policies = output.policies else { - return policyList - } - for policy in policies { - guard let name = policy.policyName, - let id = policy.policyId, - let arn = policy.arn else { - throw ServiceHandlerError.noSuchPolicy + // Use "Paginated" to get all the objects. + // This lets the SDK handle the 'isTruncated' in "ListUsersOutput". + let input = ListPoliciesInput() + let output = client.listPoliciesPaginated(input: input) + + do { + for try await page in output { + guard let policies = page.policies else { + print("Error: no policies returned.") + continue + } + + for policy in policies { + guard let name = policy.policyName, + let id = policy.policyId, + let arn = policy.arn + else { + throw ServiceHandlerError.noSuchPolicy + } + policyList.append(MyPolicyRecord(name: name, id: id, arn: arn)) } - policyList.append(MyPolicyRecord(name: name, id: id, arn: arn)) } - marker = output.marker - isTruncated = output.isTruncated - } while isTruncated == true + } catch { + print("ERROR: listPolicies:", dump(error)) + throw error + } + return policyList } - // snippet-end:[iam.swift.listpolicies.handler.listpolicies] + // snippet-end:[iam.swift.listpolicies.handler.ListPolicies] } + // snippet-end:[iam.swift.listpolicies.handler] diff --git a/swift/example_code/iam/ListPolicies/Tests/ListPoliciesTests/ListPoliciesTests.swift b/swift/example_code/iam/ListPolicies/Tests/ListPoliciesTests/ListPoliciesTests.swift index 595bec12d29..a12b4051624 100644 --- a/swift/example_code/iam/ListPolicies/Tests/ListPoliciesTests/ListPoliciesTests.swift +++ b/swift/example_code/iam/ListPolicies/Tests/ListPoliciesTests/ListPoliciesTests.swift @@ -31,7 +31,7 @@ final class ListPoliciesTests: XCTestCase { super.setUp() Task() { - ListPoliciesTests.serviceHandler = await ServiceHandler() + ListPoliciesTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/ListRolePolicies/Sources/ListRolePolicies/ListRolePolicies.swift b/swift/example_code/iam/ListRolePolicies/Sources/ListRolePolicies/ListRolePolicies.swift index 884e4caa53c..3eee06c6409 100644 --- a/swift/example_code/iam/ListRolePolicies/Sources/ListRolePolicies/ListRolePolicies.swift +++ b/swift/example_code/iam/ListRolePolicies/Sources/ListRolePolicies/ListRolePolicies.swift @@ -8,9 +8,10 @@ // snippet-start:[iam.swift.listrolepolicies.example] // snippet-start:[iam.swift.listrolepolicies.main.imports] +import ArgumentParser import Foundation import ServiceHandler -import ArgumentParser + // snippet-end:[iam.swift.listrolepolicies.main.imports] /// The command line arguments and options available for this @@ -31,11 +32,11 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.listrolepolicies.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() + let policies = try await serviceHandler.listRolePolicies(role: rolename) - + print("Found \(policies.count) policies in role \(rolename)") for policy in policies { print(" \(policy)") @@ -46,6 +47,7 @@ struct ExampleCommand: ParsableCommand { } // snippet-end:[iam.swift.listrolepolicies.command.runasync] } + // snippet-end:[iam.swift.listrolepolicies.command] // @@ -63,7 +65,8 @@ struct Main { } catch { ExampleCommand.exit(withError: error) } - } + } } + // snippet-end:[iam.swift.listrolepolicies.main] -// snippet-end:[iam.swift.listrolepolicies.example] \ No newline at end of file +// snippet-end:[iam.swift.listrolepolicies.example] diff --git a/swift/example_code/iam/ListRolePolicies/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/ListRolePolicies/Sources/ServiceHandler/ServiceHandler.swift index 04af21a65cf..e56c5be7947 100644 --- a/swift/example_code/iam/ListRolePolicies/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/ListRolePolicies/Sources/ServiceHandler/ServiceHandler.swift @@ -2,15 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 /* - A class containing functions that interact with AWS services. -*/ + A class containing functions that interact with AWS services. + */ // snippet-start:[iam.swift.listrolepolicies.handler] // snippet-start:[iam.swift.listrolepolicies.handler.imports] -import Foundation +import AWSClientRuntime import AWSIAM import ClientRuntime -import AWSClientRuntime +import Foundation + // snippet-end:[iam.swift.listrolepolicies.handler.imports] /// Errors returned by `ServiceHandler` functions. @@ -26,51 +27,55 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.listrolepolicies.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } + // snippet-end:[iam.swift.listrolepolicies.handler.init] /// Returns a list of all AWS Identity and Access Management (IAM) policy /// names. /// /// - Returns: An array of the available policy names. - // snippet-start:[iam.swift.listrolepolicies.handler.listrolepolicies] + // snippet-start:[iam.swift.listrolepolicies.handler.ListRolePolicies] public func listRolePolicies(role: String) async throws -> [String] { var policyList: [String] = [] - var marker: String? = nil - var isTruncated: Bool - - repeat { - let input = ListRolePoliciesInput( - marker: marker, - roleName: role - ) - let output = try await client.listRolePolicies(input: input) - - guard let policies = output.policyNames else { - return policyList - } - for policy in policies { - policyList.append(policy) + // Use "Paginated" to get all the objects. + // This lets the SDK handle the 'isTruncated' in "ListUsersOutput". + let input = ListRolePoliciesInput( + roleName: role + ) + let pages = client.listRolePoliciesPaginated(input: input) + + do { + for try await page in pages { + guard let policies = page.policyNames else { + print("Error: no role policies returned.") + continue + } + + for policy in policies { + policyList.append(policy) + } } - marker = output.marker - isTruncated = output.isTruncated - } while isTruncated == true + } catch { + print("ERROR: listRolePolicies:", dump(error)) + throw error + } return policyList } - // snippet-end:[iam.swift.listrolepolicies.handler.listrolepolicies] + // snippet-end:[iam.swift.listrolepolicies.handler.ListRolePolicies] } + // snippet-end:[iam.swift.listrolepolicies.handler] diff --git a/swift/example_code/iam/ListRolePolicies/Tests/ListRolePoliciesTests/ListRolePoliciesTests.swift b/swift/example_code/iam/ListRolePolicies/Tests/ListRolePoliciesTests/ListRolePoliciesTests.swift index bb661bfd9ba..70bed3c1dd0 100644 --- a/swift/example_code/iam/ListRolePolicies/Tests/ListRolePoliciesTests/ListRolePoliciesTests.swift +++ b/swift/example_code/iam/ListRolePolicies/Tests/ListRolePoliciesTests/ListRolePoliciesTests.swift @@ -31,7 +31,7 @@ final class ListRolePoliciesTests: XCTestCase { super.setUp() Task() { - ListRolePoliciesTests.serviceHandler = await ServiceHandler() + ListRolePoliciesTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/ListRoles/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/ListRoles/Sources/ServiceHandler/ServiceHandler.swift index c5be3f1b541..121c7de935b 100644 --- a/swift/example_code/iam/ListRoles/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/ListRoles/Sources/ServiceHandler/ServiceHandler.swift @@ -45,7 +45,7 @@ public class ServiceHandler { /// names. /// /// - Returns: An array of user records. - // snippet-start:[iam.swift.listroles.handler.listroles] + // snippet-start:[iam.swift.listroles.handler.ListRoles] public func listRoles() async throws -> [String] { var roleList: [String] = [] var marker: String? = nil @@ -69,6 +69,6 @@ public class ServiceHandler { } while isTruncated == true return roleList } - // snippet-end:[iam.swift.listroles.handler.listroles] + // snippet-end:[iam.swift.listroles.handler.ListRoles] } // snippet-end:[iam.swift.listroles.handler] diff --git a/swift/example_code/iam/ListUsers/Sources/ListUsers/ListUsers.swift b/swift/example_code/iam/ListUsers/Sources/ListUsers/ListUsers.swift index 35c1d86029e..1c7727f2b26 100644 --- a/swift/example_code/iam/ListUsers/Sources/ListUsers/ListUsers.swift +++ b/swift/example_code/iam/ListUsers/Sources/ListUsers/ListUsers.swift @@ -28,9 +28,9 @@ struct ExampleCommand: ParsableCommand { /// example. // snippet-start:[iam.swift.listusers.command.runasync] func runAsync() async throws { - let serviceHandler = await ServiceHandler() - do { + let serviceHandler = try await ServiceHandler() + var users: [MyUserRecord] users = try await serviceHandler.listUsers() @@ -39,6 +39,7 @@ struct ExampleCommand: ParsableCommand { print(" \(user.name) (\(user.id))") } } catch { + print("ERROR: ListUsers runAsync:", dump(error)) throw error } } @@ -64,4 +65,4 @@ struct Main { } } // snippet-end:[iam.swift.listusers.main] -// snippet-end:[iam.swift.listusers.example] \ No newline at end of file +// snippet-end:[iam.swift.listusers.example] diff --git a/swift/example_code/iam/ListUsers/Sources/ServiceHandler/ServiceHandler.swift b/swift/example_code/iam/ListUsers/Sources/ServiceHandler/ServiceHandler.swift index 6c351c39b99..e28fed57d16 100644 --- a/swift/example_code/iam/ListUsers/Sources/ServiceHandler/ServiceHandler.swift +++ b/swift/example_code/iam/ListUsers/Sources/ServiceHandler/ServiceHandler.swift @@ -18,18 +18,17 @@ public class ServiceHandler { public let client: IAMClient /// Initialize and return a new ``ServiceHandler`` object, which is used - /// to drive the AWS calls used for the example. The Region string - /// `AWS_GLOBAL` is used because users are shared across all Regions. + /// to drive the AWS calls used for the example. /// /// - Returns: A new ``ServiceHandler`` object, ready to be called to /// execute AWS operations. // snippet-start:[iam.swift.listusers.handler.init] - public init() async { + public init() async throws { do { - client = try IAMClient(region: "AWS_GLOBAL") + client = try await IAMClient() } catch { print("ERROR: ", dump(error, name: "Initializing Amazon IAM client")) - exit(1) + throw error } } // snippet-end:[iam.swift.listusers.handler.init] @@ -38,30 +37,33 @@ public class ServiceHandler { /// ``MyUserRecord`` structures. /// /// - Returns: An array of user records. - // snippet-start:[iam.swift.listusers.handler.listusers] + // snippet-start:[iam.swift.listusers.handler.ListUsers] public func listUsers() async throws -> [MyUserRecord] { var userList: [MyUserRecord] = [] - var marker: String? = nil - var isTruncated: Bool - repeat { - let input = ListUsersInput(marker: marker) - let output = try await client.listUsers(input: input) - - guard let users = output.users else { - return userList - } + // Use "Paginated" to get all the objects. + // This lets the SDK handle the 'isTruncated' in "ListUsersOutput". + let input = ListUsersInput() + let output = client.listUsersPaginated(input: input) - for user in users { - if let id = user.userId, let name = user.userName { - userList.append(MyUserRecord(id: id, name: name)) + do { + for try await page in output { + guard let users = page.users else { + continue + } + for user in users { + if let id = user.userId, let name = user.userName { + userList.append(MyUserRecord(id: id, name: name)) + } } } - marker = output.marker - isTruncated = output.isTruncated - } while isTruncated == true - return userList + } + catch { + print("ERROR: listUsers:", dump(error)) + throw error + } + return userList } - // snippet-end:[iam.swift.listusers.handler.listusers] + // snippet-end:[iam.swift.listusers.handler.ListUsers] } // snippet-end:[iam.swift.listusers.handler] diff --git a/swift/example_code/iam/ListUsers/Tests/ListUsersTests/ListUsersTests.swift b/swift/example_code/iam/ListUsers/Tests/ListUsersTests/ListUsersTests.swift index 33e93cfde66..bafd3867f0a 100644 --- a/swift/example_code/iam/ListUsers/Tests/ListUsersTests/ListUsersTests.swift +++ b/swift/example_code/iam/ListUsers/Tests/ListUsersTests/ListUsersTests.swift @@ -31,7 +31,7 @@ final class ListUsersTests: XCTestCase { super.setUp() Task() { - ListUsersTests.serviceHandler = await ServiceHandler() + ListUsersTests.serviceHandler = try await ServiceHandler() tdSem.signal() } tdSem.wait() diff --git a/swift/example_code/iam/basics/Sources/Basics/Basics.swift b/swift/example_code/iam/basics/Sources/Basics/Basics.swift index 5a17cfd31fb..46126e0d03d 100644 --- a/swift/example_code/iam/basics/Sources/Basics/Basics.swift +++ b/swift/example_code/iam/basics/Sources/Basics/Basics.swift @@ -23,11 +23,16 @@ // snippet-start:[iam.swift.basics.example] // snippet-start:[iam.swift.basics.main.imports] -import Foundation import ArgumentParser import ClientRuntime +import Foundation +import Swift + // snippet-start:[iam.swift.import] import AWSIAM + +import AWSS3 + // snippet-end:[iam.swift.import] import AWSSTS import AWSS3 @@ -39,7 +44,7 @@ import AWSS3 // snippet-start:[iam.swift.basics.command] struct ExampleCommand: ParsableCommand { @Option(help: "The AWS Region to run AWS API calls in.") - var awsRegion = "us-east-2" + var awsRegion: String? = nil @Option( help: ArgumentHelp("The level of logging for the Swift SDK to perform."), @@ -71,9 +76,9 @@ struct ExampleCommand: ParsableCommand { func runAsync() async throws { // Create handlers for the AWS services to use. - let iamHandler = await ServiceHandlerIAM() - let stsHandler = await ServiceHandlerSTS(region: awsRegion) - let s3Handler = await ServiceHandlerS3(region: awsRegion) + let iamHandler = try await ServiceHandlerIAM() + let stsHandler = try await ServiceHandlerSTS(region: awsRegion) + let s3Handler = try await ServiceHandlerS3(region: awsRegion) // Create unique names for the user, role, and policy to create. let userName = String.uniqueName(withPrefix: "basics-user", maxDigits: 8) @@ -124,8 +129,9 @@ struct ExampleCommand: ParsableCommand { // Confirm that the returned access key is valid, then extract the access key // ID and secret access key. They will be needed later. - guard let accessKeyId: String = accessKey.accessKeyId, - let secretAccessKey = accessKey.secretAccessKey else { + guard let accessKeyId: String = accessKey.accessKeyId, + let secretAccessKey = accessKey.secretAccessKey + else { print("*** Invalid access key returned by createAccessKey().") return } @@ -134,7 +140,7 @@ struct ExampleCommand: ParsableCommand { // Pause a few seconds to give IAM time for the new user to propagate. await waitFor(seconds: 10, - message: "Pausing a few seconds so the new user can propagate.") + message: "Pausing a few seconds so the new user can propagate.") //===================================================================== // 3. Attempt to list the S3 buckets without first getting permission @@ -143,11 +149,11 @@ struct ExampleCommand: ParsableCommand { do { print("Attempting to list buckets without permission to do so.") - + // Use the user's access key to attempt to get the bucket list. try await s3Handler.setCredentials(accessKeyId: accessKeyId, - secretAccessKey: secretAccessKey) + secretAccessKey: secretAccessKey) _ = try await s3Handler.listBuckets() print("*** Successfully listed S3 buckets without permission. Bad program!") @@ -224,7 +230,7 @@ struct ExampleCommand: ParsableCommand { } await waitFor(seconds: 10, - message: "Pausing a few seconds to allow user and role changes to propagate.") + message: "Pausing a few seconds to allow user and role changes to propagate.") //===================================================================== // 6. Create a user policy letting the user change roles. @@ -259,12 +265,12 @@ struct ExampleCommand: ParsableCommand { // Make sure our calls to the AWS STS will use the user's // credentials. try await stsHandler.setCredentials(accessKeyId: accessKeyId, - secretAccessKey: secretAccessKey) + secretAccessKey: secretAccessKey) // Assume the role you created and get the credentials that grant the // permissions offered by the role. let credentials = try await stsHandler.assumeRole( - role: role, + role: role, sessionName: "listing-buckets" ) @@ -272,9 +278,10 @@ struct ExampleCommand: ParsableCommand { // three parts have values. guard let roleAccessKeyId = credentials.accessKeyId, let roleSecretAccessKey = credentials.secretAccessKey, - let roleSessionToken = credentials.sessionToken else { - print("*** Incomplete access keys returned by AssumeRole.") - return + let roleSessionToken = credentials.sessionToken + else { + print("*** Incomplete access keys returned by AssumeRole.") + return } await waitFor(seconds: 10, message: "Waiting to ensure user has assumed the role.") @@ -282,7 +289,7 @@ struct ExampleCommand: ParsableCommand { // Set our Amazon S3 handler to use the credentials returned by // assumeRole(). try await s3Handler.setCredentials(accessKeyId: roleAccessKeyId, - secretAccessKey: roleSecretAccessKey, sessionToken: roleSessionToken) + secretAccessKey: roleSecretAccessKey, sessionToken: roleSessionToken) } catch { print("*** Unable to assume the role and update Amazon S3 credentials.") throw error @@ -303,7 +310,7 @@ struct ExampleCommand: ParsableCommand { //===================================================================== // 8. Clean up by removing the policies, role, access key, and user you // created. - + do { print("Deleting resources created by this example.") try await iamHandler.detachRolePolicy(policy: managedPolicy, role: role) @@ -318,20 +325,27 @@ struct ExampleCommand: ParsableCommand { throw error } } + // snippet-end:[iam.swift.basics.command.runasync] /// Display a message and wait for a few seconds to pass. - /// + /// /// - Parameters: /// - seconds: The number of seconds to wait as a `Double`. /// - message: Optional `String` to display before the pause begins. func waitFor(seconds: Double, message: String? = nil) async { if message != nil { - print("*** \(message!) ***") + print("*** \(message!) ***") + } + do { + let duration = UInt64(seconds * 1_000_000_000) + try await Task.sleep(nanoseconds: duration) + } catch { + print("Sleep error:", dump(error)) } - Thread.sleep(forTimeInterval: seconds) } } + // snippet-end:[iam.swift.basics.command] // Main program entry point. @@ -348,7 +362,8 @@ struct Main { } catch { ExampleCommand.exit(withError: error) } - } + } } + // snippet-end:[iam.swift.basics.main] -// snippet-end:[iam.swift.basics.example] \ No newline at end of file +// snippet-end:[iam.swift.basics.example] diff --git a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM.swift b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM.swift index 89a67d76049..429323163fd 100644 --- a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM.swift +++ b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM.swift @@ -2,25 +2,24 @@ // SPDX-License-Identifier: Apache-2.0 /* - A class containing functions that interact with AWS Identity and Access - Management (IAM). -*/ + A class containing functions that interact with AWS Identity and Access + Management (IAM). + */ // snippet-start:[iam.swift.basics.iam] // snippet-start:[iam.swift.basics.iam.imports] -import Foundation import AWSIAM -import ClientRuntime import AWSSDKIdentity +import ClientRuntime +import Foundation import SwiftUtilities + // snippet-end:[iam.swift.basics.iam.imports] public class ServiceHandlerIAM { - /// IAM always uses the global value for the Region. - let region = "us-east-1" - /// The `IAMClient` used to interact with IAM. var iamClient: IAMClient + var region: String? /// Initialize the IAM client, optionally with credentials. /// @@ -30,21 +29,31 @@ public class ServiceHandlerIAM { /// - secretAccessKey: An optional `String` giving the credentials' /// secret access key. /// - sessionToken: An optional string specifying the session token. + /// region: An optional region to be used by the IAM client. // snippet-start:[iam.swift.basics.iam.init] - public init(accessKeyId: String? = nil, + public init(accessKeyId: String? = nil, secretAccessKey: String? = nil, - sessionToken: String? = nil) async { + sessionToken: String? = nil, + region: String? = nil) async throws + { + self.region = region + do { + let iamConfig = try await IAMClient.IAMClientConfiguration() + if let region = region { + iamConfig.region = region + } if accessKeyId == nil { - iamClient = try IAMClient(region: self.region) + iamClient = IAMClient(config: iamConfig) } else { // Use the given access key ID, secret access key, and session token // to generate a static credentials provider suitable for use when // initializing an IAM client. - guard let keyId = accessKeyId, - let secretKey = secretAccessKey else { - throw ServiceHandlerError.authError + guard let keyId = accessKeyId, + let secretKey = secretAccessKey + else { + throw ServiceHandlerError.authError } let credentials: AWSCredentialIdentity = AWSCredentialIdentity( @@ -54,21 +63,17 @@ public class ServiceHandlerIAM { ) let identityResolver = try StaticAWSCredentialIdentityResolver(credentials) - // Create an IAM configuration specifying the credentials - // provider. Then create a new `IAMClient` using those - // permissions. - - let iamConfig = try await IAMClient.IAMClientConfiguration( - awsCredentialIdentityResolver: identityResolver, - region: self.region - ) + // Update iamConfig to use the new credentials. + // Then create a new `IAMClient` using those permissions. + iamConfig.awsCredentialIdentityResolver = identityResolver iamClient = IAMClient(config: iamConfig) } } catch { print("Error initializing the AWS IAM client: ", dump(error)) - exit(1) + throw error } } + // snippet-end:[iam.swift.basics.iam.init] /// Update the IAM handler with a new `IAMClient` set up to use the @@ -80,7 +85,8 @@ public class ServiceHandlerIAM { /// - sessionToken: An optional string containing the AWS session token. // snippet-start:[iam.swift.basics.iam.setcredentials] public func setCredentials(accessKeyId: String, secretAccessKey: String, - sessionToken: String? = nil) async throws { + sessionToken: String? = nil) async throws + { do { // Use the given access key ID, secret access key, and session // token to generate a static credentials provider suitable for @@ -96,26 +102,36 @@ public class ServiceHandlerIAM { // Create a new `IAMClient` using the new identity resolver. let iamConfig = try await IAMClient.IAMClientConfiguration( - awsCredentialIdentityResolver: identityResolver, - region: self.region + awsCredentialIdentityResolver: identityResolver ) + if let region = self.region { + iamConfig.region = region + } iamClient = IAMClient(config: iamConfig) } catch { + print("Error setting credentials for the AWS IAM client: ", dump(error)) throw error } } + // snippet-end:[iam.swift.basics.iam.setcredentials] - + /// Reset IAM credentials by replacing the internal `iamClient` with a /// fresh one that uses the default configuration. // snippet-start:[iam.swift.basics.iam.resetcredentials] public func resetCredentials() async throws { do { - iamClient = try IAMClient(region: "AWS_GLOBAL") + let iamConfig = try await IAMClient.IAMClientConfiguration() + if let region = self.region { + iamConfig.region = region + } + iamClient = IAMClient(config: iamConfig) } catch { + print("Error resetting the AWS IAM client: ", dump(error)) throw error } } + // snippet-end:[iam.swift.basics.iam.resetcredentials] /// Create a new IAM user. @@ -137,9 +153,11 @@ public class ServiceHandlerIAM { return user } catch { + print("Error creating a user: ", dump(error)) throw error } } + // snippet-end:[iam.swift.basics.iam.createuser] /// Create a new IAM role. @@ -163,9 +181,11 @@ public class ServiceHandlerIAM { } return role } catch { + print("Error creating a role: ", dump(error)) throw error } } + // snippet-end:[iam.swift.basics.iam.createrole] /// Create an IAM access key for a user. @@ -174,7 +194,7 @@ public class ServiceHandlerIAM { /// /// - Returns: An `IAMClientTypes.AccessKey` object with the access key /// details. - // snippet-start:[iam.swift.basics.iam.createaccesskey] + // snippet-start:[iam.swift.basics.iam.CreateAccessKey] public func createAccessKey(userName: String) async throws -> IAMClientTypes.AccessKey { let input = CreateAccessKeyInput( userName: userName @@ -186,10 +206,12 @@ public class ServiceHandlerIAM { } return accessKey } catch { + print("Error creating an access key: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.createaccesskey] + + // snippet-end:[iam.swift.basics.iam.CreateAccessKey] /// Create a new AWS Identity and Access Management (IAM) policy. /// @@ -199,7 +221,7 @@ public class ServiceHandlerIAM { /// /// - Returns: An `IAMClientTypes.Policy` object describing the new policy. /// - // snippet-start:[iam.swift.basics.iam.createpolicy] + // snippet-start:[iam.swift.basics.iam.CreatePolicy] public func createPolicy(name: String, policyDocument: String) async throws -> IAMClientTypes.Policy { let input = CreatePolicyInput( policyDocument: policyDocument, @@ -212,10 +234,12 @@ public class ServiceHandlerIAM { } return policy } catch { + print("Error creating a policy: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.createpolicy] + + // snippet-end:[iam.swift.basics.iam.CreatePolicy] /// Add an inline policy to an AWS Identity and Access Management (IAM) /// user. @@ -226,7 +250,7 @@ public class ServiceHandlerIAM { /// - policyName: A string giving the policy's name. /// - user: The `IAMClientTypes.User` specifying the user. /// - // snippet-start:[iam.swift.basics.iam.putuserpolicy] + // snippet-start:[iam.swift.basics.iam.PutUserPolicy] func putUserPolicy(policyDocument: String, policyName: String, user: IAMClientTypes.User) async throws { let input = PutUserPolicyInput( policyDocument: policyDocument, @@ -236,10 +260,12 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.putUserPolicy(input: input) } catch { + print("Error putting the user policy: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.putuserpolicy] + + // snippet-end:[iam.swift.basics.iam.PutUserPolicy] /// Delete the specified inline user policy. /// @@ -248,7 +274,7 @@ public class ServiceHandlerIAM { /// delete the policy. /// - policyName: The name of the policy to delete. /// - // snippet-start:[iam.swift.basics.iam.deleteuserpolicy] + // snippet-start:[iam.swift.basics.iam.DeleteUserPolicy] func deleteUserPolicy(user: IAMClientTypes.User, policyName: String) async throws { let input = DeleteUserPolicyInput( policyName: policyName, @@ -257,10 +283,12 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.deleteUserPolicy(input: input) } catch { + print("Error deleting the user policy: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.deleteuserpolicy] + + // snippet-end:[iam.swift.basics.iam.DeleteUserPolicy] /// Attach a managed policy to a role. /// @@ -278,17 +306,19 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.attachRolePolicy(input: input) } catch { + print("Error attaching a role policy: ", dump(error)) throw error } } + // snippet-end:[iam.swift.basics.iam.attachrolepolicy] /// Detach a policy from a role. - /// + /// /// - Parameters: /// - policy: The policy to be detached from the role. /// - role: The role from which to detach a policy. - // snippet-start:[iam.swift.basics.iam.detachrolepolicy] + // snippet-start:[iam.swift.basics.iam.DetachRolePolicy] public func detachRolePolicy(policy: IAMClientTypes.Policy, role: IAMClientTypes.Role) async throws { let input = DetachRolePolicyInput( policyArn: policy.arn, @@ -298,16 +328,18 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.detachRolePolicy(input: input) } catch { + print("Error detaching a role policy: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.detachrolepolicy] + + // snippet-end:[iam.swift.basics.iam.DetachRolePolicy] /// Delete the specified policy. /// /// - Parameter policy: The `IAMClientTypes.Policy` object identifying the /// policy to delete. - // snippet-start:[iam.swift.basics.iam.deletepolicy] + // snippet-start:[iam.swift.basics.iam.DeletePolicy] public func deletePolicy(policy: IAMClientTypes.Policy) async throws { let input = DeletePolicyInput( policyArn: policy.arn @@ -318,14 +350,15 @@ public class ServiceHandlerIAM { throw error } } - // snippet-end:[iam.swift.basics.iam.deletepolicy] + + // snippet-end:[iam.swift.basics.iam.DeletePolicy] /// Delete an IAM user. /// /// - Parameter user: The `IAMClientTypes.User` object describing the IAM /// user to delete. /// - // snippet-start:[iam.swift.basics.iam.deleteuser] + // snippet-start:[iam.swift.basics.iam.DeleteUser] public func deleteUser(user: IAMClientTypes.User) async throws { let input = DeleteUserInput( userName: user.userName @@ -333,10 +366,12 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.deleteUser(input: input) } catch { + print("Error deleting a user: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.deleteuser] + + // snippet-end:[iam.swift.basics.iam.DeleteUser] /// Delete an access key. /// - Parameters: @@ -345,9 +380,10 @@ public class ServiceHandlerIAM { /// access key signing the request. /// - key: An `IAMClientTypes.AccessKey` object representing the key to /// delete. - // snippet-start:[iam.swift.basics.iam.deleteaccesskey] + // snippet-start:[iam.swift.basics.iam.DeleteAccessKey] public func deleteAccessKey(user: IAMClientTypes.User? = nil, - key: IAMClientTypes.AccessKey) async throws { + key: IAMClientTypes.AccessKey) async throws + { let userName: String? if user != nil { @@ -363,15 +399,17 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.deleteAccessKey(input: input) } catch { + print("Error deleting an access key: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.deleteaccesskey] + + // snippet-end:[iam.swift.basics.iam.DeleteAccessKey] /// Delete an IAM role. /// /// - Parameter name: The IAM role to delete. - // snippet-start:[iam.swift.basics.iam.deleterole] + // snippet-start:[iam.swift.basics.iam.DeleteRole] public func deleteRole(role: IAMClientTypes.Role) async throws { let input = DeleteRoleInput( roleName: role.roleName @@ -379,10 +417,12 @@ public class ServiceHandlerIAM { do { _ = try await iamClient.deleteRole(input: input) } catch { + print("Error deleting a role: ", dump(error)) throw error } } - // snippet-end:[iam.swift.basics.iam.deleterole] + + // snippet-end:[iam.swift.basics.iam.DeleteRole] /// Get information about the specified user. /// @@ -402,9 +442,11 @@ public class ServiceHandlerIAM { } return user } catch { + print("Error getting a user: ", dump(error)) throw error } } // snippet-end:[iam.swift.basics.iam.getuser] } + // snippet-end:[iam.swift.basics.iam] diff --git a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM_Ext.swift b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM_Ext.swift index f0aae7b0736..a9baa3879f7 100644 --- a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM_Ext.swift +++ b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerIAM_Ext.swift @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 /* - Extensions to the `ServiceHandlerIAM` class to handle tasks needed - for testing that aren't the purpose of this example. -*/ + Extensions to the `ServiceHandlerIAM` class to handle tasks needed + for testing that aren't the purpose of this example. + */ -import Foundation import AWSIAM import ClientRuntime +import Foundation import SwiftUtilities public extension ServiceHandlerIAM { @@ -25,6 +25,7 @@ public extension ServiceHandlerIAM { } return id } catch { + print("Error getting the user ID: ", dump(error)) throw error } } @@ -44,6 +45,7 @@ public extension ServiceHandlerIAM { } return role } catch { + print("Error getting the role: ", dump(error)) throw error } } diff --git a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerS3.swift b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerS3.swift index a3f699388bb..9090f3cfbee 100644 --- a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerS3.swift +++ b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerS3.swift @@ -17,7 +17,7 @@ import AWSSDKIdentity public class ServiceHandlerS3 { /// The AWS Region to use for Amazon S3 operations. - let region: String + let region: String? /// The S3Client used to interact with Amazon S3. var s3Client: S3Client @@ -25,7 +25,7 @@ public class ServiceHandlerS3 { /// Initialize the Amazon S3 client, optionally with credentials. /// /// - Parameters: - /// - region: A `String` providing the AWS Region to use for Amazon S3. + /// - region: An optional`String` providing the AWS Region to use for Amazon S3. /// operations. If not provided, us-east-2 is assumed. /// - accessKeyId: An optional `String` giving the access key ID of the /// credentials to use. @@ -33,18 +33,22 @@ public class ServiceHandlerS3 { /// secret access key. /// - sessionToken: An optional string specifying the session token. // snippet-start:[iam.swift.basics.s3.init] - public init(region: String = "us-east-2", + public init(region: String? = nil, accessKeyId: String? = nil, secretAccessKey: String? = nil, - sessionToken: String? = nil) async { + sessionToken: String? = nil) async throws { do { self.region = region + let s3Config = try await S3Client.S3ClientConfiguration() + + if let region = self.region { + s3Config.region = region + } // If the access key ID isn't provided, initialize the Amazon // S3 client with the Region. Otherwise, use the credentials. - if accessKeyId == nil { - s3Client = try S3Client(region: self.region) + s3Client = S3Client(config: s3Config) } else { // Use the given access key ID, secret access key, and session token // to generate a static credentials provider suitable for use when @@ -62,18 +66,15 @@ public class ServiceHandlerS3 { ) let identityResolver = try StaticAWSCredentialIdentityResolver(credentials) - // Create an Amazon S3 configuration specifying the credentials - // provider. Then create a new `S3Client` using those permissions. + // Update s3Config to use the new credentials. + // Then create a new `S3Client` using those permissions. + s3Config.awsCredentialIdentityResolver = identityResolver - let s3Config = try await S3Client.S3ClientConfiguration( - awsCredentialIdentityResolver: identityResolver, - region: self.region - ) s3Client = S3Client(config: s3Config) } } catch { print("Error initializing the AWS S3 client: ", dump(error)) - exit(1) + throw error } } // snippet-end:[iam.swift.basics.s3.init] @@ -110,6 +111,7 @@ public class ServiceHandlerS3 { ) s3Client = S3Client(config: s3Config) } catch { + print("Error setting credentials for the AWS S3 client: ", dump(error)) throw error } } @@ -121,8 +123,15 @@ public class ServiceHandlerS3 { // snippet-start:[iam.swift.basics.s3.resetcredentials] public func resetCredentials() async throws { do { - s3Client = try S3Client(region: self.region) + let s3Config = try await S3Client.S3ClientConfiguration() + + if let region = self.region { + s3Config.region = region + } + + s3Client = S3Client(config: s3Config) } catch { + print("Error resetting credential for the AWS S3 client: ", dump(error)) throw error } } @@ -135,16 +144,25 @@ public class ServiceHandlerS3 { /// buckets in the Amazon S3 account. // snippet-start:[iam.swift.basics.s3.listbuckets] public func listBuckets() async throws -> [S3ClientTypes.Bucket] { - let input = ListBucketsInput() + let input = ListBucketsInput(maxBuckets: 10) do { - let output = try await s3Client.listBuckets(input: input) - - guard let buckets = output.buckets else { - throw ServiceHandlerError.bucketError + // Use "Paginated" to get all the buckets. + // This lets the SDK handle the 'continuationToken' in "ListBucketsOutput". + let output = s3Client.listBucketsPaginated(input: input) + var allBuckets : [S3ClientTypes.Bucket] = [] + for try await page in output { + guard let buckets = page.buckets else { + print("ERROR: listBucketsPaginated returned nil contents.") + continue + } + + allBuckets += buckets } - return buckets + + return allBuckets } catch { + print("Error listing the buckets: ", dump(error)) throw error } } diff --git a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS.swift b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS.swift index 4d961f2fddf..a7b732cfc3a 100644 --- a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS.swift +++ b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS.swift @@ -22,7 +22,7 @@ import AWSSDKIdentity /// Service (AWS STS). public class ServiceHandlerSTS { /// The AWS Region to use for AWS STS operations. - let region: String + let region: String? /// The STSClient used to interact with AWS STS. var stsClient: STSClient @@ -30,7 +30,7 @@ public class ServiceHandlerSTS { /// Initialize the AWS STS client, optionally with credentials. /// /// - Parameters: - /// - region: A string specifying the AWS Region in which to perform + /// - region: An optional string specifying the AWS Region in which to perform /// AWS STS operations. If not specified, us-east-2 is used. /// - accessKeyId: An optional string giving the access key ID to /// use for AWS STS operations. @@ -40,15 +40,20 @@ public class ServiceHandlerSTS { /// credentials. /// // snippet-start:[iam.swift.basics.sts.init] - public init(region: String = "us-east-2", + public init(region: String? = nil, accessKeyId: String? = nil, secretAccessKey: String? = nil, - sessionToken: String? = nil) async { + sessionToken: String? = nil) async throws { do { self.region = region + + let stsConfig = try await STSClient.STSClientConfiguration() + if let region = self.region { + stsConfig.region = region + } if accessKeyId == nil { - stsClient = try STSClient(region: self.region) + stsClient = STSClient(config: stsConfig) } else { // Use the given access key ID, secret access key, and session token // to generate a static credentials provider suitable for use when @@ -66,18 +71,14 @@ public class ServiceHandlerSTS { ) let identityResolver = try StaticAWSCredentialIdentityResolver(credentials) - // Create an AWS STS configuration specifying the credentials - // provider. Then create a new `STSClient` using those permissions. - - let s3Config = try await STSClient.STSClientConfiguration( - awsCredentialIdentityResolver: identityResolver, - region: self.region - ) - stsClient = STSClient(config: s3Config) + // Update s3Config to use the new credentials. + // Then create a new `STSClient` using those permissions. + stsConfig.awsCredentialIdentityResolver = identityResolver + stsClient = STSClient(config: stsConfig) } } catch { print("Error initializing the AWS S3 client: ", dump(error)) - exit(1) + throw error } } // snippet-end:[iam.swift.basics.sts.init] @@ -108,11 +109,15 @@ public class ServiceHandlerSTS { // Create a new AWS STS client with the specified access credentials. let stsConfig = try await STSClient.STSClientConfiguration( - awsCredentialIdentityResolver: identityResolver, - region: self.region + awsCredentialIdentityResolver: identityResolver ) + + if let region = self.region { + stsConfig.region = region + } stsClient = STSClient(config: stsConfig) } catch { + print("Error setting credentials: ", dump(error)) throw error } } @@ -124,8 +129,13 @@ public class ServiceHandlerSTS { // snippet-start:[iam.swift.basics.sts.resetcredentials] public func resetCredentials() async throws { do { - stsClient = try STSClient(region: self.region) + let stsConfig = try await STSClient.STSClientConfiguration() + if let region = self.region { + stsConfig.region = region + } + stsClient = STSClient(config: stsConfig) } catch { + print("Error resetting credentials: ", dump(error)) throw error } } @@ -157,6 +167,7 @@ public class ServiceHandlerSTS { return credentials } catch { + print("Error assuming role: ", dump(error)) throw error } } diff --git a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS_Ext.swift b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS_Ext.swift index af9494addbb..746213cc905 100644 --- a/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS_Ext.swift +++ b/swift/example_code/iam/basics/Sources/ServiceHandler/ServiceHandlerSTS_Ext.swift @@ -31,5 +31,9 @@ public extension ServiceHandlerSTS { } return account } - } -} \ No newline at end of file + catch { + print("Error getting access key account number: ", dump(error)) + throw error + } + } +} diff --git a/swift/example_code/iam/basics/Tests/BasicsTests/BasicsTests.swift b/swift/example_code/iam/basics/Tests/BasicsTests/BasicsTests.swift index 6fea3c3260e..5ff38846ad0 100644 --- a/swift/example_code/iam/basics/Tests/BasicsTests/BasicsTests.swift +++ b/swift/example_code/iam/basics/Tests/BasicsTests/BasicsTests.swift @@ -338,7 +338,13 @@ final class BasicsTests: XCTestCase { if message != nil { print("\n*** \(message!) ***") } - Thread.sleep(forTimeInterval: seconds) + do { + let duration = UInt64(seconds * 1_000_000_000) + try await Task.sleep(nanoseconds: duration) + } + catch { + print("Sleep error:", dump(error)) + } print("\n") } }