Skip to content

Commit b6bec42

Browse files
committed
fix: make ECS/IMDS credentials retry policies inherit from StandardRetryPolicy
1 parent 5dc0436 commit b6bec42

File tree

3 files changed

+15
-35
lines changed

3 files changed

+15
-35
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"id": "28e51fe7-a4d8-4c99-a257-886ad89b7d02",
3+
"type": "bugfix",
4+
"description": "improve retry policies for ECS and IMDS credentials to handle common network errors",
5+
"issues": [
6+
"awslabs/aws-sdk-kotlin#1626"
7+
]
8+
}

aws-runtime/aws-config/common/src/aws/sdk/kotlin/runtime/auth/credentials/EcsCredentialsProvider.kt

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ import aws.smithy.kotlin.runtime.io.closeIfCloseable
2525
import aws.smithy.kotlin.runtime.net.*
2626
import aws.smithy.kotlin.runtime.net.url.Url
2727
import aws.smithy.kotlin.runtime.operation.ExecutionContext
28-
import aws.smithy.kotlin.runtime.retries.policy.RetryDirective
29-
import aws.smithy.kotlin.runtime.retries.policy.RetryErrorType
30-
import aws.smithy.kotlin.runtime.retries.policy.RetryPolicy
3128
import aws.smithy.kotlin.runtime.serde.json.JsonDeserializer
3229
import aws.smithy.kotlin.runtime.telemetry.logging.logger
3330
import aws.smithy.kotlin.runtime.time.TimestampFormat
@@ -97,8 +94,6 @@ public class EcsCredentialsProvider(
9794
execution.endpointResolver = EndpointResolver { Endpoint(url) }
9895
}
9996

100-
op.execution.retryPolicy = EcsCredentialsRetryPolicy()
101-
10297
logger.debug { "retrieving container credentials" }
10398
val client = SdkHttpClient(httpClient)
10499
val creds = try {
@@ -260,22 +255,6 @@ private class EcsCredentialsSerializer(
260255
}
261256
}
262257

263-
internal class EcsCredentialsRetryPolicy : RetryPolicy<Any?> {
264-
override fun evaluate(result: Result<Any?>): RetryDirective = when {
265-
result.isSuccess -> RetryDirective.TerminateAndSucceed
266-
else -> evaluate(result.exceptionOrNull()!!)
267-
}
268-
269-
private fun evaluate(throwable: Throwable): RetryDirective = when (throwable) {
270-
is CredentialsProviderException -> when {
271-
throwable.sdkErrorMetadata.isThrottling -> RetryDirective.RetryError(RetryErrorType.Throttling)
272-
throwable.sdkErrorMetadata.isRetryable -> RetryDirective.RetryError(RetryErrorType.ServerSide)
273-
else -> RetryDirective.TerminateAndFail
274-
}
275-
else -> RetryDirective.TerminateAndFail
276-
}
277-
}
278-
279258
private val ecsV4Addr = IpV4Addr(169u, 254u, 170u, 2u)
280259

281260
private val eksV4Addr = IpV4Addr(169u, 254u, 170u, 23u)

aws-runtime/aws-config/common/src/aws/sdk/kotlin/runtime/config/imds/ImdsRetryPolicy.kt

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,25 @@ import aws.smithy.kotlin.runtime.http.HttpStatusCode
99
import aws.smithy.kotlin.runtime.http.category
1010
import aws.smithy.kotlin.runtime.retries.policy.RetryDirective
1111
import aws.smithy.kotlin.runtime.retries.policy.RetryErrorType
12-
import aws.smithy.kotlin.runtime.retries.policy.RetryPolicy
12+
import aws.smithy.kotlin.runtime.retries.policy.StandardRetryPolicy
1313
import aws.smithy.kotlin.runtime.telemetry.logging.logger
1414
import kotlin.coroutines.CoroutineContext
1515

16-
internal class ImdsRetryPolicy(
17-
private val callContext: CoroutineContext,
18-
) : RetryPolicy<Any?> {
19-
override fun evaluate(result: Result<Any?>): RetryDirective = when {
20-
result.isSuccess -> RetryDirective.TerminateAndSucceed
21-
else -> evaluate(result.exceptionOrNull()!!)
22-
}
23-
24-
private fun evaluate(throwable: Throwable): RetryDirective = when (throwable) {
16+
internal class ImdsRetryPolicy(private val callContext: CoroutineContext) : StandardRetryPolicy() {
17+
override fun evaluateSpecificExceptions(ex: Throwable) = when (ex) {
2518
is EC2MetadataError -> {
26-
val status = throwable.status
19+
val status = ex.status
2720
when {
2821
status.category() == HttpStatusCode.Category.SERVER_ERROR -> RetryDirective.RetryError(RetryErrorType.ServerSide)
2922
// 401 indicates the token has expired, this is retryable
3023
status == HttpStatusCode.Unauthorized -> RetryDirective.RetryError(RetryErrorType.ServerSide)
3124
else -> {
3225
val logger = callContext.logger<ImdsRetryPolicy>()
33-
logger.debug { "Non retryable IMDS error: statusCode=$status; ${throwable.message}" }
34-
RetryDirective.TerminateAndFail
26+
logger.debug { "IMDS error: statusCode=$status; ${ex.message}" }
27+
null
3528
}
3629
}
3730
}
38-
else -> RetryDirective.TerminateAndFail
31+
else -> null
3932
}
4033
}

0 commit comments

Comments
 (0)