Introduce mTLS support for JaegerRemoteSamplerBuilder (#5209) (#5248)

This commit is contained in:
Francisco Bento 2023-03-09 13:11:36 -03:00 committed by GitHub
parent 4532648bbc
commit 2babc69924
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 0 deletions

View File

@ -65,3 +65,6 @@ Comparing source compatibility of against
---! REMOVED METHOD: PUBLIC(-) io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2.Sampling$SamplingStrategyResponse$Builder clone()
---! REMOVED METHOD: PUBLIC(-) io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2.Sampling$SamplingStrategyResponse$Builder setField(com.google.protobuf.Descriptors$FieldDescriptor, java.lang.Object)
---! REMOVED METHOD: PUBLIC(-) io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2.Sampling$SamplingStrategyResponse$Builder setRepeatedField(com.google.protobuf.Descriptors$FieldDescriptor, int, java.lang.Object)
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSamplerBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSamplerBuilder setClientTls(byte[], byte[])

View File

@ -65,6 +65,15 @@ public final class JaegerRemoteSamplerBuilder {
return this;
}
/**
* Sets the client key and the certificate chain to use for verifying client when TLS is enabled.
* The key must be PKCS8, and both must be in PEM format.
*/
public JaegerRemoteSamplerBuilder setClientTls(byte[] privateKeyPem, byte[] certificatePem) {
delegate.setClientTls(privateKeyPem, certificatePem);
return this;
}
/**
* Sets the polling interval for configuration updates. If unset, defaults to {@value
* DEFAULT_POLLING_INTERVAL_MILLIS}ms. Must be positive.

View File

@ -8,6 +8,8 @@ package io.opentelemetry.sdk.extension.trace.jaeger.sampler;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Named.named;
import static org.junit.jupiter.params.provider.Arguments.arguments;
import com.linecorp.armeria.common.grpc.protocol.ArmeriaStatusException;
import com.linecorp.armeria.server.ServerBuilder;
@ -16,6 +18,7 @@ import com.linecorp.armeria.server.grpc.protocol.AbstractUnaryGrpcService;
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.github.netmikey.logunit.api.LogCapturer;
import io.netty.handler.ssl.ClientAuth;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2.Sampling;
import io.opentelemetry.sdk.extension.trace.jaeger.proto.api_v2.Sampling.RateLimitingSamplingStrategy;
@ -29,12 +32,18 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.awaitility.core.ThrowingRunnable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.slf4j.event.Level;
import org.slf4j.event.LoggingEvent;
@ -61,7 +70,12 @@ class JaegerRemoteSamplerTest {
@RegisterExtension
static final SelfSignedCertificateExtension certificate = new SelfSignedCertificateExtension();
@RegisterExtension
@Order(2)
static final SelfSignedCertificateExtension clientCertificate =
new SelfSignedCertificateExtension();
@Order(3)
@RegisterExtension
static final ServerExtension server =
new ServerExtension() {
@ -98,6 +112,11 @@ class JaegerRemoteSamplerTest {
sb.http(0);
sb.https(0);
sb.tls(certificate.certificateFile(), certificate.privateKeyFile());
sb.tlsCustomizer(
ssl -> {
ssl.clientAuth(ClientAuth.OPTIONAL);
ssl.trustManager(clientCertificate.certificate());
});
}
};
@ -140,6 +159,36 @@ class JaegerRemoteSamplerTest {
}
}
@ParameterizedTest
@ArgumentsSource(ClientPrivateKeyProvider.class)
void clientTlsConnectionWorks(byte[] privateKey) throws IOException {
try (JaegerRemoteSampler sampler =
JaegerRemoteSampler.builder()
.setEndpoint(server.httpsUri().toString())
.setPollingInterval(1, TimeUnit.SECONDS)
.setTrustedCertificates(Files.readAllBytes(certificate.certificateFile().toPath()))
.setClientTls(
privateKey, Files.readAllBytes(clientCertificate.certificateFile().toPath()))
.setServiceName(SERVICE_NAME)
.build()) {
await().untilAsserted(samplerIsType(sampler, RateLimitingSampler.class));
// verify
assertThat(sampler.getDescription()).contains("RateLimitingSampler{999.00}");
}
}
private static class ClientPrivateKeyProvider implements ArgumentsProvider {
@Override
@SuppressWarnings("PrimitiveArrayPassedToVarargsMethod")
public Stream<? extends Arguments> provideArguments(ExtensionContext context) throws Exception {
return Stream.of(
arguments(named("PEM", Files.readAllBytes(clientCertificate.privateKeyFile().toPath()))),
arguments(named("DER", clientCertificate.privateKey().getEncoded())));
}
}
@Test
void description() {
try (JaegerRemoteSampler sampler =