feat: AWS SDK v2 Secrets Manager auto-instrumentation support (#14001)
Co-authored-by: Lauri Tulmin <ltulmin@splunk.com>
This commit is contained in:
parent
70588cd360
commit
4a2b49fbef
|
|
@ -121,9 +121,10 @@ dependencies {
|
|||
testLibrary("software.amazon.awssdk:lambda:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:rds:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:s3:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sqs:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sns:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:ses:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:secretsmanager:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sns:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sqs:2.2.0")
|
||||
}
|
||||
|
||||
val latestDepTest = findProperty("testLatestDeps") as Boolean
|
||||
|
|
|
|||
|
|
@ -18,8 +18,9 @@ dependencies {
|
|||
testLibrary("software.amazon.awssdk:lambda:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:rds:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:s3:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sqs:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:secretsmanager:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sns:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:sqs:2.2.0")
|
||||
}
|
||||
|
||||
tasks {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ dependencies {
|
|||
testLibrary("software.amazon.awssdk:kinesis:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:rds:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:s3:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:secretsmanager:2.2.0")
|
||||
testLibrary("software.amazon.awssdk:ses:2.2.0")
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkReques
|
|||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.DYNAMODB;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.KINESIS;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.S3;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SECRETSMANAGER;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SNS;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkRequestType.SQS;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.request;
|
||||
|
|
@ -35,6 +36,7 @@ enum AwsSdkRequest {
|
|||
SnsRequest(SNS, "SnsRequest"),
|
||||
SqsRequest(SQS, "SqsRequest"),
|
||||
KinesisRequest(KINESIS, "KinesisRequest"),
|
||||
SecretsManagerRequest(SECRETSMANAGER, "SecretsManagerRequest"),
|
||||
// specific requests
|
||||
BatchGetItem(
|
||||
DYNAMODB,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
package io.opentelemetry.instrumentation.awssdk.v2_2.internal;
|
||||
|
||||
import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.request;
|
||||
import static io.opentelemetry.instrumentation.awssdk.v2_2.internal.FieldMapping.response;
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import java.util.Collections;
|
||||
|
|
@ -18,6 +20,7 @@ enum AwsSdkRequestType {
|
|||
KINESIS(request("aws.stream.name", "StreamName")),
|
||||
DYNAMODB(request("aws.table.name", "TableName")),
|
||||
BEDROCK_RUNTIME(),
|
||||
SECRETSMANAGER(response(AttributeKeys.AWS_SECRETSMANAGER_SECRET_ARN.getKey(), "ARN")),
|
||||
SNS(
|
||||
/*
|
||||
* Only one of TopicArn and TargetArn are permitted on an SNS request.
|
||||
|
|
@ -38,6 +41,10 @@ enum AwsSdkRequestType {
|
|||
}
|
||||
|
||||
private static class AttributeKeys {
|
||||
// Copied from AwsIncubatingAttributes
|
||||
static final AttributeKey<String> AWS_SECRETSMANAGER_SECRET_ARN =
|
||||
stringKey("aws.secretsmanager.secret.arn");
|
||||
|
||||
// copied from MessagingIncubatingAttributes
|
||||
static final AttributeKey<String> MESSAGING_DESTINATION_NAME =
|
||||
AttributeKey.stringKey("messaging.destination.name");
|
||||
|
|
|
|||
|
|
@ -18,9 +18,10 @@ dependencies {
|
|||
compileOnly("software.amazon.awssdk:lambda:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:rds:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:s3:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:sqs:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:sns:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:secretsmanager:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:ses:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:sns:2.2.0")
|
||||
compileOnly("software.amazon.awssdk:sqs:2.2.0")
|
||||
|
||||
// needed for SQS - using emq directly as localstack references emq v0.15.7 ie WITHOUT AWS trace header propagation
|
||||
implementation("org.elasticmq:elasticmq-rest-sqs_2.13")
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import static io.opentelemetry.semconv.ServerAttributes.SERVER_ADDRESS;
|
|||
import static io.opentelemetry.semconv.ServerAttributes.SERVER_PORT;
|
||||
import static io.opentelemetry.semconv.UrlAttributes.URL_FULL;
|
||||
import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_REQUEST_ID;
|
||||
import static io.opentelemetry.semconv.incubating.AwsIncubatingAttributes.AWS_SECRETSMANAGER_SECRET_ARN;
|
||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_DESTINATION_NAME;
|
||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_MESSAGE_ID;
|
||||
import static io.opentelemetry.semconv.incubating.MessagingIncubatingAttributes.MESSAGING_OPERATION;
|
||||
|
|
@ -79,6 +80,12 @@ import software.amazon.awssdk.services.s3.S3Client;
|
|||
import software.amazon.awssdk.services.s3.S3ClientBuilder;
|
||||
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
|
||||
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
||||
import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClient;
|
||||
import software.amazon.awssdk.services.secretsmanager.SecretsManagerAsyncClientBuilder;
|
||||
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
|
||||
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClientBuilder;
|
||||
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueRequest;
|
||||
import software.amazon.awssdk.services.secretsmanager.model.GetSecretValueResponse;
|
||||
import software.amazon.awssdk.services.sns.SnsAsyncClient;
|
||||
import software.amazon.awssdk.services.sns.SnsAsyncClientBuilder;
|
||||
import software.amazon.awssdk.services.sns.SnsClient;
|
||||
|
|
@ -112,6 +119,18 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest
|
|||
+ " <ResponseMetadata><RequestId>0ac9cda2-bbf4-11d3-f92b-31fa5e8dbc99</RequestId></ResponseMetadata>"
|
||||
+ "</DeleteOptionGroupResponse>";
|
||||
|
||||
private static final String secretsManagerBodyContent =
|
||||
"{"
|
||||
+ " \"ARN\": \"arn:aws:secretsmanager:us-east-1:123456789012:secret:MySecretFromCLI-sNkBwD\","
|
||||
+ " \"Name\": \"MySecretFromCLI\","
|
||||
+ " \"VersionId\": \"9959b95b-1234-5678-a19b-a4b0315ca5aa\","
|
||||
+ " \"SecretString\": \"super-secret-value\","
|
||||
+ " \"VersionStages\": ["
|
||||
+ " \"AWSCURRENT\""
|
||||
+ " ],"
|
||||
+ " \"CreatedDate\": \"1.523477145713E9\""
|
||||
+ "}";
|
||||
|
||||
private static void assumeSupportedConfig(String operation) {
|
||||
Assumptions.assumeFalse(
|
||||
operation.equals("SendMessage") && isSqsAttributeInjectionEnabled(),
|
||||
|
|
@ -214,6 +233,13 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest
|
|||
equalTo(MESSAGING_SYSTEM, AWS_SQS))));
|
||||
}
|
||||
|
||||
if (service.equals("SecretsManager")) {
|
||||
attributes.add(
|
||||
equalTo(
|
||||
AWS_SECRETSMANAGER_SECRET_ARN,
|
||||
"arn:aws:secretsmanager:us-east-1:123456789012:secret:MySecretFromCLI-sNkBwD"));
|
||||
}
|
||||
|
||||
String evaluatedOperation;
|
||||
SpanKind operationKind;
|
||||
if (operation.equals("SendMessage")) {
|
||||
|
|
@ -722,4 +748,44 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest
|
|||
|
||||
assertThat(Context.current()).isEqualTo(Context.root());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSecretsManagerSendOperationRequestWithBuilder() {
|
||||
SecretsManagerClientBuilder builder = SecretsManagerClient.builder();
|
||||
configureSdkClient(builder);
|
||||
SecretsManagerClient client =
|
||||
builder
|
||||
.endpointOverride(clientUri)
|
||||
.region(Region.AP_NORTHEAST_1)
|
||||
.credentialsProvider(CREDENTIALS_PROVIDER)
|
||||
.build();
|
||||
|
||||
server.enqueue(
|
||||
HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, secretsManagerBodyContent));
|
||||
Object response =
|
||||
client.getSecretValue(GetSecretValueRequest.builder().secretId("MySecretFromCLI").build());
|
||||
assertThat(response.getClass().getSimpleName())
|
||||
.satisfies(
|
||||
v -> assertThat(v).isEqualTo("GetSecretValueResponse"),
|
||||
v -> assertThat(response).isInstanceOf(GetSecretValueResponse.class));
|
||||
clientAssertions("SecretsManager", "GetSecretValue", "POST", response, "UNKNOWN");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testSecretsManagerAsyncSendOperationRequestWithBuilder() {
|
||||
SecretsManagerAsyncClientBuilder builder = SecretsManagerAsyncClient.builder();
|
||||
configureSdkClient(builder);
|
||||
SecretsManagerAsyncClient client =
|
||||
builder
|
||||
.endpointOverride(clientUri)
|
||||
.region(Region.AP_NORTHEAST_1)
|
||||
.credentialsProvider(CREDENTIALS_PROVIDER)
|
||||
.build();
|
||||
|
||||
server.enqueue(
|
||||
HttpResponse.of(HttpStatus.OK, MediaType.PLAIN_TEXT_UTF_8, secretsManagerBodyContent));
|
||||
Object response =
|
||||
client.getSecretValue(GetSecretValueRequest.builder().secretId("MySecretFromCLI").build());
|
||||
clientAssertions("SecretsManager", "GetSecretValue", "POST", response, "UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue