-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Route 53 TrimHostedZone customization is incomplete (#1445)
- Loading branch information
Showing
9 changed files
with
160 additions
and
427 deletions.
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
IntegrationTests/Services/AWSRoute53IntegrationTests/AWSRoute53Tests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
import XCTest | ||
import AWSRoute53 | ||
|
||
class AWSRoute53Tests: XCTestCase { | ||
var client: Route53Client! | ||
var hostedZoneID: String? | ||
|
||
override func setUp() async throws { | ||
try await super.setUp() | ||
client = try Route53Client(region: "us-east-1") | ||
} | ||
|
||
override func tearDown() async throws { | ||
|
||
// Delete the hosted zone that was created in the test. | ||
// Note that the member with the hosted zone ID is just named 'id' | ||
// here while it is 'hostedZoneId' below; the customization has | ||
// been adapted to handle any member name. | ||
let input = DeleteHostedZoneInput(id: hostedZoneID) | ||
_ = try await client.deleteHostedZone(input: input) | ||
client = nil | ||
hostedZoneID = nil | ||
} | ||
|
||
// Tests the 'TrimHostedZone' customization by performing operations on | ||
// AWS Route 53 that will fail if the zone ID is not correctly trimmed. | ||
func test_route53_createsAndDeletesZoneAndRecords() async throws { | ||
|
||
// Create reference string that is used for idempotency, and | ||
// also use it to create a bogus web domain that is used in the test. | ||
let ref = UUID().uuidString | ||
let hostedZoneName = "\(ref).com." | ||
|
||
// Create a hosted zone for the zone name created above. | ||
// Store the hosted zone ID for future reference. | ||
// The ID will be in the form '/hostedzone/<alphanumeric ID>'. | ||
// The '/hostedzone/' portion of the ID at the beginning is what must be | ||
// trimmed by the customization, and only the alphanumeric portion | ||
// of the ID is used in the operation's request URL. | ||
let input0 = CreateHostedZoneInput(callerReference: ref, name: hostedZoneName) | ||
let output0 = try await client.createHostedZone(input: input0) | ||
hostedZoneID = output0.hostedZone?.id | ||
|
||
// Create an A record on the zone that was just made. | ||
// ChangeResourceRecordSetsInput includes the hosted zone ID in a URL | ||
// component. | ||
let createBatch = Route53ClientTypes.ChangeBatch(changes: | ||
[ | ||
Route53ClientTypes.Change( | ||
action: .create, | ||
resourceRecordSet: Route53ClientTypes.ResourceRecordSet( | ||
name: "abc.\(hostedZoneName)", resourceRecords: [Route53ClientTypes.ResourceRecord(value: "1.1.1.1")], ttl: 3600, type: .a | ||
) | ||
), | ||
] | ||
) | ||
let input1 = ChangeResourceRecordSetsInput(changeBatch: createBatch, hostedZoneId: hostedZoneID) | ||
let output1 = try await client.changeResourceRecordSets(input: input1) | ||
|
||
// Now delete the A record that was just created; this is necessary for the | ||
// hosted zone to be deleted in test teardown. | ||
let deleteBatch = Route53ClientTypes.ChangeBatch(changes: | ||
[ | ||
Route53ClientTypes.Change( | ||
action: .delete, | ||
resourceRecordSet: Route53ClientTypes.ResourceRecordSet( | ||
name: "abc.\(hostedZoneName)", resourceRecords: [Route53ClientTypes.ResourceRecord(value: "1.1.1.1")], ttl: 3600, type: .a | ||
) | ||
), | ||
] | ||
) | ||
let input2 = ChangeResourceRecordSetsInput(changeBatch: deleteBatch, hostedZoneId: hostedZoneID) | ||
let output2 = try await client.changeResourceRecordSets(input: input2) | ||
} | ||
} |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
Sources/Core/AWSClientRuntime/Middlewares/Route53TrimHostedZoneMiddleware.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
import ClientRuntime | ||
|
||
public struct Route53TrimHostedZoneMiddleware<Input, Output>: ClientRuntime.Middleware { | ||
public let id: Swift.String = "Route53TrimHostedZoneMiddleware" | ||
private let prefixes = ["/hostedzone/", "hostedzone/", "/hostedzone", "hostedzone"] | ||
|
||
private let hostedZoneIDKeyPath: WritableKeyPath<Input, String?> | ||
|
||
public init(_ hostedZoneIDKeyPath: WritableKeyPath<Input, String?>) { | ||
self.hostedZoneIDKeyPath = hostedZoneIDKeyPath | ||
} | ||
|
||
public func handle<H>(context: Context, | ||
input: Input, | ||
next: H) async throws -> ClientRuntime.OperationOutput<Output> | ||
where H: Handler, | ||
Self.MInput == H.Input, | ||
Self.MOutput == H.Output, | ||
Self.Context == H.Context { | ||
guard let hostedZoneId = input[keyPath: hostedZoneIDKeyPath] else { | ||
return try await next.handle(context: context, input: input) | ||
} | ||
var copiedInput = input | ||
let stripped = hostedZoneId.stripFirstMatching(prefixes: prefixes) | ||
copiedInput[keyPath: hostedZoneIDKeyPath] = stripped | ||
return try await next.handle(context: context, input: copiedInput) | ||
} | ||
|
||
public typealias MInput = Input | ||
public typealias MOutput = ClientRuntime.OperationOutput<Output> | ||
public typealias Context = ClientRuntime.HttpContext | ||
} |
Oops, something went wrong.