From 355def333c337df8db91a809e8b102696b58bbce Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Tue, 25 Apr 2023 13:55:57 -0400 Subject: [PATCH 1/8] Add support for client-side cert/key to gRPC exports. TODO: Add tests. I have not run or written any tests, other than verifying it worked once in my production system. --- api/CMakeLists.txt | 5 +++ .../otlp/otlp_grpc_exporter_options.h | 15 ++++++++ exporters/otlp/src/otlp_grpc_client.cc | 35 +++++++++++++------ 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index 31863b25e3..da5deced72 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -113,6 +113,11 @@ if(WITH_OTLP_HTTP_SSL_PREVIEW) endif() endif() +if (WITH_OTLP_GRPC_MTLS_PREVIEW) + target_compile_definitions(opentelemetry_api + INTERFACE ENABLE_OTLP_GRPC_MTLS_PREVIEW) +endif() + if(WITH_METRICS_EXEMPLAR_PREVIEW) target_compile_definitions(opentelemetry_api INTERFACE ENABLE_METRICS_EXEMPLAR_PREVIEW) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h index f5a2b9d295..930358c3be 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h @@ -3,6 +3,8 @@ #pragma once +#include "absl/types/optional.h" +#include "absl/types/variant.h" #include "opentelemetry/exporters/otlp/otlp_environment.h" #include @@ -28,6 +30,19 @@ struct OtlpGrpcExporterOptions // ssl_credentials_cacert_as_string in-memory string representation of .pem file to be used for // SSL encryption. std::string ssl_credentials_cacert_as_string = GetOtlpDefaultSslCertificateString(); + +#ifdef ENABLE_OTLP_GRPC_MTLS_PREVIEW + // At most one of ssl_client_key_* should be non-empty. If use_ssl_credentials, they will + // be read to allow for mTLS. + std::string ssl_client_key_path = GetOtlpDefaultTracesSslClientKeyPath(); + std::string ssl_client_key_string = GetOtlpDefaultTracesSslClientKeyString(); + + // At most one of ssl_client_cert_* should be non-empty. If use_ssl_credentials, they will + // be read to allow for mTLS. + std::string ssl_client_cert_path = GetOtlpDefaultTracesSslClientCertificatePath(); + std::string ssl_client_cert_string = GetOtlpDefaultTracesSslClientCertificateString(); +#endif + // Timeout for grpc deadline std::chrono::system_clock::duration timeout = GetOtlpDefaultTimeout(); // Additional HTTP headers diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index 9250f87cc4..a14f624d51 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -34,6 +34,16 @@ static std::string GetFileContents(const char *fpath) finstream.close(); return contents; } + +// If the file path is non-empty, returns the contents of the file. Otherwise returns contents. +static std::string GetFileContentsOrInMemoryContents( + const std::string& file_path, const std::string& contents) { + if (!file_path.empty()) { + return GetFileContents(file_path.c_str()); + } + return contents; +} + } // namespace std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporterOptions &options) @@ -58,17 +68,20 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte grpc::ChannelArguments grpc_arguments; grpc_arguments.SetUserAgentPrefix(options.user_agent); - if (options.use_ssl_credentials) - { - grpc::SslCredentialsOptions ssl_opts; - if (options.ssl_credentials_cacert_path.empty()) - { - ssl_opts.pem_root_certs = options.ssl_credentials_cacert_as_string; - } - else - { - ssl_opts.pem_root_certs = GetFileContents((options.ssl_credentials_cacert_path).c_str()); - } + if (options.use_ssl_credentials) { + grpc::SslCredentialsOptions ssl_opts = { + .pem_root_certs = GetFileContentsOrInMemoryContents( + options.ssl_credentials_cacert_path, + options.ssl_credentials_cacert_as_string), +#if ENABLE_OTLP_GRPC_MTLS_PREVIEW + .pem_private_key = GetFileContentsOrInMemoryContents( + options.ssl_client_key_path, + options.ssl_client_key_string), + .pem_cert_chain = GetFileContentsOrInMemoryContents( + options.ssl_client_cert_path, + options.ssl_client_cert_string) +#endif + }; channel = grpc::CreateCustomChannel(grpc_target, grpc::SslCredentials(ssl_opts), grpc_arguments); } From 933e6c0084c3239b8422af3f33e557f6cf40a08f Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Wed, 21 Jun 2023 18:25:31 -0400 Subject: [PATCH 2/8] Remove variant/optional includes, they are no longer used. --- .../opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h index 930358c3be..779a21aeab 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h @@ -3,8 +3,6 @@ #pragma once -#include "absl/types/optional.h" -#include "absl/types/variant.h" #include "opentelemetry/exporters/otlp/otlp_environment.h" #include From 6245fcd8a1a17acb29cc57243feac452d72196d1 Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Thu, 22 Jun 2023 10:39:44 -0400 Subject: [PATCH 3/8] Switch away from initializer lists because Windows complains. Also add "SSL" to the mTLS macros since evenetually there will be something named TLS on the gRPC side. --- api/CMakeLists.txt | 4 ++-- .../otlp/otlp_grpc_exporter_options.h | 2 +- exporters/otlp/src/otlp_grpc_client.cc | 22 +++++++++---------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index da5deced72..10cd86865f 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -113,9 +113,9 @@ if(WITH_OTLP_HTTP_SSL_PREVIEW) endif() endif() -if (WITH_OTLP_GRPC_MTLS_PREVIEW) +if (WITH_OTLP_GRPC_SSL_MTLS_PREVIEW) target_compile_definitions(opentelemetry_api - INTERFACE ENABLE_OTLP_GRPC_MTLS_PREVIEW) + INTERFACE ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW) endif() if(WITH_METRICS_EXEMPLAR_PREVIEW) diff --git a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h index 779a21aeab..01ac5b43f2 100644 --- a/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h +++ b/exporters/otlp/include/opentelemetry/exporters/otlp/otlp_grpc_exporter_options.h @@ -29,7 +29,7 @@ struct OtlpGrpcExporterOptions // SSL encryption. std::string ssl_credentials_cacert_as_string = GetOtlpDefaultSslCertificateString(); -#ifdef ENABLE_OTLP_GRPC_MTLS_PREVIEW +#ifdef ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW // At most one of ssl_client_key_* should be non-empty. If use_ssl_credentials, they will // be read to allow for mTLS. std::string ssl_client_key_path = GetOtlpDefaultTracesSslClientKeyPath(); diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index a14f624d51..6952ea0422 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -69,17 +69,17 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte grpc_arguments.SetUserAgentPrefix(options.user_agent); if (options.use_ssl_credentials) { - grpc::SslCredentialsOptions ssl_opts = { - .pem_root_certs = GetFileContentsOrInMemoryContents( - options.ssl_credentials_cacert_path, - options.ssl_credentials_cacert_as_string), -#if ENABLE_OTLP_GRPC_MTLS_PREVIEW - .pem_private_key = GetFileContentsOrInMemoryContents( - options.ssl_client_key_path, - options.ssl_client_key_string), - .pem_cert_chain = GetFileContentsOrInMemoryContents( - options.ssl_client_cert_path, - options.ssl_client_cert_string) + grpc::SslCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = GetFileContentsOrInMemoryContents( + options.ssl_credentials_cacert_path, + options.ssl_credentials_cacert_as_string); +#if ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW + ssl_opts.pem_private_key = GetFileContentsOrInMemoryContents( + options.ssl_client_key_path, + options.ssl_client_key_string); + ssl_opts.pem_cert_chain = GetFileContentsOrInMemoryContents( + options.ssl_client_cert_path, + options.ssl_client_cert_string); #endif }; channel = From 4a5e7708b43fede342f09d1239f8d4bb65ae20bc Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Fri, 23 Jun 2023 10:13:46 -0400 Subject: [PATCH 4/8] Fix compilation failure. --- exporters/otlp/src/otlp_grpc_client.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index 6952ea0422..35f5efb53e 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -81,7 +81,6 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte options.ssl_client_cert_path, options.ssl_client_cert_string); #endif - }; channel = grpc::CreateCustomChannel(grpc_target, grpc::SslCredentials(ssl_opts), grpc_arguments); } From 3df0faa2ad7bf1973d442caf63b886a1de9096d7 Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Fri, 23 Jun 2023 10:22:17 -0400 Subject: [PATCH 5/8] Update CI to try these options. --- ci/do_ci.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index d504b33ae8..388942376e 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -97,6 +97,8 @@ elif [[ "$1" == "cmake.maintainer.sync.test" ]]; then -DWITH_OTLP_HTTP=ON \ -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ + -DWITH_OTLP_GRPC=ON \ + -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -120,6 +122,8 @@ elif [[ "$1" == "cmake.maintainer.async.test" ]]; then -DWITH_OTLP_HTTP=ON \ -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ + -DWITH_OTLP_GRPC=ON \ + -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -144,6 +148,8 @@ elif [[ "$1" == "cmake.maintainer.cpp11.async.test" ]]; then -DWITH_OTLP_HTTP=ON \ -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ + -DWITH_OTLP_GRPC=ON \ + -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ From b76466881c3c84d877e49d871a3908b09e1e2c0e Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Fri, 23 Jun 2023 10:31:26 -0400 Subject: [PATCH 6/8] Apply clang-format. --- exporters/otlp/src/otlp_grpc_client.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index 35f5efb53e..2b2ae88685 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -36,9 +36,11 @@ static std::string GetFileContents(const char *fpath) } // If the file path is non-empty, returns the contents of the file. Otherwise returns contents. -static std::string GetFileContentsOrInMemoryContents( - const std::string& file_path, const std::string& contents) { - if (!file_path.empty()) { +static std::string GetFileContentsOrInMemoryContents(const std::string &file_path, + const std::string &contents) +{ + if (!file_path.empty()) + { return GetFileContents(file_path.c_str()); } return contents; @@ -68,18 +70,16 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte grpc::ChannelArguments grpc_arguments; grpc_arguments.SetUserAgentPrefix(options.user_agent); - if (options.use_ssl_credentials) { + if (options.use_ssl_credentials) + { grpc::SslCredentialsOptions ssl_opts; ssl_opts.pem_root_certs = GetFileContentsOrInMemoryContents( - options.ssl_credentials_cacert_path, - options.ssl_credentials_cacert_as_string); + options.ssl_credentials_cacert_path, options.ssl_credentials_cacert_as_string); #if ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW - ssl_opts.pem_private_key = GetFileContentsOrInMemoryContents( - options.ssl_client_key_path, - options.ssl_client_key_string); - ssl_opts.pem_cert_chain = GetFileContentsOrInMemoryContents( - options.ssl_client_cert_path, - options.ssl_client_cert_string); + ssl_opts.pem_private_key = GetFileContentsOrInMemoryContents(options.ssl_client_key_path, + options.ssl_client_key_string); + ssl_opts.pem_cert_chain = GetFileContentsOrInMemoryContents(options.ssl_client_cert_path, + options.ssl_client_cert_string); #endif channel = grpc::CreateCustomChannel(grpc_target, grpc::SslCredentials(ssl_opts), grpc_arguments); From 0dfacfcdbf99ca5ad1e8a0dcbe4882daf449d234 Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Fri, 23 Jun 2023 18:43:17 -0400 Subject: [PATCH 7/8] Fix lint errors. --- api/CMakeLists.txt | 2 +- exporters/otlp/src/otlp_grpc_client.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt index 10cd86865f..91d129e179 100644 --- a/api/CMakeLists.txt +++ b/api/CMakeLists.txt @@ -113,7 +113,7 @@ if(WITH_OTLP_HTTP_SSL_PREVIEW) endif() endif() -if (WITH_OTLP_GRPC_SSL_MTLS_PREVIEW) +if(WITH_OTLP_GRPC_SSL_MTLS_PREVIEW) target_compile_definitions(opentelemetry_api INTERFACE ENABLE_OTLP_GRPC_SSL_MTLS_PREVIEW) endif() diff --git a/exporters/otlp/src/otlp_grpc_client.cc b/exporters/otlp/src/otlp_grpc_client.cc index 2b2ae88685..5a94c66b59 100644 --- a/exporters/otlp/src/otlp_grpc_client.cc +++ b/exporters/otlp/src/otlp_grpc_client.cc @@ -79,7 +79,7 @@ std::shared_ptr OtlpGrpcClient::MakeChannel(const OtlpGrpcExporte ssl_opts.pem_private_key = GetFileContentsOrInMemoryContents(options.ssl_client_key_path, options.ssl_client_key_string); ssl_opts.pem_cert_chain = GetFileContentsOrInMemoryContents(options.ssl_client_cert_path, - options.ssl_client_cert_string); + options.ssl_client_cert_string); #endif channel = grpc::CreateCustomChannel(grpc_target, grpc::SslCredentials(ssl_opts), grpc_arguments); From 1eec89ba8f9f392b1ca3677f78f8b48b97c3868e Mon Sep 17 00:00:00 2001 From: Kyle Loveless Date: Mon, 26 Jun 2023 10:27:23 -0400 Subject: [PATCH 8/8] Switch to just using WITH_OTLP_GRPC_SSL_MTLS_PREVIEW on one test that arleady has GRPC enabled on it. --- ci/do_ci.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ci/do_ci.sh b/ci/do_ci.sh index 388942376e..6020d22a04 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -97,8 +97,6 @@ elif [[ "$1" == "cmake.maintainer.sync.test" ]]; then -DWITH_OTLP_HTTP=ON \ -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ - -DWITH_OTLP_GRPC=ON \ - -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -122,8 +120,6 @@ elif [[ "$1" == "cmake.maintainer.async.test" ]]; then -DWITH_OTLP_HTTP=ON \ -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ - -DWITH_OTLP_GRPC=ON \ - -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -148,8 +144,6 @@ elif [[ "$1" == "cmake.maintainer.cpp11.async.test" ]]; then -DWITH_OTLP_HTTP=ON \ -DWITH_OTLP_HTTP_SSL_PREVIEW=ON \ -DWITH_OTLP_HTTP_SSL_TLS_PREVIEW=ON \ - -DWITH_OTLP_GRPC=ON \ - -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ -DWITH_PROMETHEUS=ON \ -DWITH_EXAMPLES=ON \ -DWITH_EXAMPLES_HTTP=ON \ @@ -264,6 +258,7 @@ elif [[ "$1" == "cmake.exporter.otprotocol.test" ]]; then cmake -DCMAKE_BUILD_TYPE=Debug \ -DWITH_OTLP_GRPC=ON \ -DWITH_OTLP_HTTP=ON \ + -DWITH_OTLP_GRPC_SSL_MTLS_PREVIEW=ON \ "${SRC_DIR}" grpc_cpp_plugin=`which grpc_cpp_plugin` proto_make_file="CMakeFiles/opentelemetry_proto.dir/build.make"