From 39bc279a1858267e7ec041aab9f47805fc0623b8 Mon Sep 17 00:00:00 2001 From: Chittalkumar Patel Date: Thu, 14 Dec 2023 15:51:27 +0000 Subject: [PATCH 01/21] Implement client key file and client certificate file for all otlp exporters --- .../otlp/proto/grpc/_log_exporter/__init__.py | 7 +- .../exporter/otlp/proto/grpc/exporter.py | 48 ++++++++++--- .../proto/grpc/metric_exporter/__init__.py | 7 +- .../proto/grpc/trace_exporter/__init__.py | 7 +- .../tests/fixtures/test-client-cert.pem | 0 .../tests/fixtures/test-client-key.pem | 0 .../tests/logs/test_otlp_logs_exporter.py | 6 ++ .../tests/test_otlp_metrics_exporter.py | 6 ++ .../tests/test_otlp_trace_exporter.py | 20 ++---- .../otlp/proto/http/_log_exporter/__init__.py | 21 ++++++ .../proto/http/metric_exporter/__init__.py | 21 ++++++ .../proto/http/trace_exporter/__init__.py | 21 ++++++ .../metrics/test_otlp_metrics_exporter.py | 31 ++++++++ .../tests/test_proto_log_exporter.py | 28 ++++++++ .../tests/test_proto_span_exporter.py | 30 ++++++++ .../sdk/environment_variables.py | 70 +++++++++++++++++++ 16 files changed, 297 insertions(+), 26 deletions(-) create mode 100644 exporter/opentelemetry-exporter-otlp-proto-grpc/tests/fixtures/test-client-cert.pem create mode 100644 exporter/opentelemetry-exporter-otlp-proto-grpc/tests/fixtures/test-client-key.pem diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py index 3a87ef1223..d8f2ba2efb 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/_log_exporter/__init__.py @@ -34,6 +34,8 @@ from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_HEADERS, @@ -71,7 +73,10 @@ def __init__( and environ.get(OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE) is not None ): credentials = _get_credentials( - credentials, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE + credentials, + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, ) environ_timeout = environ.get(OTEL_EXPORTER_OTLP_LOGS_TIMEOUT) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index b422682828..6cf77512b8 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -61,6 +61,8 @@ ) from opentelemetry.proto.resource.v1.resource_pb2 import Resource # noqa: F401 from opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_ENDPOINT, @@ -118,22 +120,47 @@ def get_resource_data( return _get_resource_data(sdk_resource_scope_data, resource_class, name) -def _load_credential_from_file(filepath) -> ChannelCredentials: +def _get_file_content(file_path: str) -> bytes: + file = open(file_path, "rb") + content = file.read() + file.close() + return content + + +def _load_credentials( + certificate_file: str, + client_key_file: str, + client_certificate_file: str, +) -> ChannelCredentials: try: - with open(filepath, "rb") as creds_file: - credential = creds_file.read() - return ssl_channel_credentials(credential) + root_certificates = _get_file_content(certificate_file) + private_key = _get_file_content(client_key_file) + certificate_chain = _get_file_content(client_certificate_file) + return ssl_channel_credentials( + root_certificates=root_certificates, + private_key=private_key, + certificate_chain=certificate_chain, + ) except FileNotFoundError: logger.exception("Failed to read credential file") return None -def _get_credentials(creds, environ_key): +def _get_credentials( + creds: Optional[ChannelCredentials], + certificate_file_env_key: str, + client_key_file_env_key: str, + client_certificate_file_env_key: str, +) -> ChannelCredentials: if creds is not None: return creds - creds_env = environ.get(environ_key) - if creds_env: - return _load_credential_from_file(creds_env) + certificate_file = environ.get(certificate_file_env_key) + client_key_file = environ.get(client_key_file_env_key) + client_certificate_file = environ.get(client_certificate_file_env_key) + if certificate_file: + return _load_credentials( + certificate_file, client_key_file, client_certificate_file + ) return ssl_channel_credentials() @@ -214,7 +241,10 @@ def __init__( ) else: credentials = _get_credentials( - credentials, OTEL_EXPORTER_OTLP_CERTIFICATE + credentials, + OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, ) self._client = self._stub( secure_channel( diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py index 2560c5c305..9a9f37bcb7 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/metric_exporter/__init__.py @@ -42,6 +42,8 @@ from opentelemetry.proto.metrics.v1 import metrics_pb2 as pb2 # noqa: F401 from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_HEADERS, @@ -113,7 +115,10 @@ def __init__( and environ.get(OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE) is not None ): credentials = _get_credentials( - credentials, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE + credentials, + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, ) environ_timeout = environ.get(OTEL_EXPORTER_OTLP_METRICS_TIMEOUT) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py index bd120ac787..ce8dcaabdf 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/trace_exporter/__init__.py @@ -48,6 +48,8 @@ ) from opentelemetry.proto.trace.v1.trace_pb2 import Status # noqa: F401 from opentelemetry.sdk.environment_variables import ( + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, @@ -105,7 +107,10 @@ def __init__( and environ.get(OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE) is not None ): credentials = _get_credentials( - credentials, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE + credentials, + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, ) environ_timeout = environ.get(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/fixtures/test-client-cert.pem b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/fixtures/test-client-cert.pem new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/fixtures/test-client-key.pem b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/fixtures/test-client-key.pem new file mode 100644 index 0000000000..e69de29bb2 diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index a6479a1474..b7a9db5465 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -50,6 +50,8 @@ from opentelemetry.sdk._logs.export import LogExportResult from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_HEADERS, @@ -179,6 +181,10 @@ def test_exporting(self): OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + "/../fixtures/test.cert", + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE: THIS_DIR + + "/../fixtures/test-client-cert.pem", + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY: THIS_DIR + + "/../fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index 291e9457ef..590a88ec2a 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -43,6 +43,8 @@ from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, @@ -221,6 +223,10 @@ def test_preferred_temporality(self): OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317", OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: THIS_DIR + + "/fixtures/test-client-cert.pem", + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: THIS_DIR + + "/fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip", diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 5445ddf926..929f58bccc 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -56,6 +56,8 @@ from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_HEADERS, @@ -232,6 +234,10 @@ def test_exporting(self): OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317", OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: THIS_DIR + + "/fixtures/test-client-cert.pem", + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY: THIS_DIR + + "/fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10", OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip", @@ -879,20 +885,6 @@ def test_translate_key_values(self): self.assertTrue(isinstance(arr_value.values[1], AnyValue)) self.assertEqual(arr_value.values[1].string_value, "123") - # Tracing specs currently does not support Mapping type attributes - # map_value = _translate_key_values( - # "map_type", {"asd": "123", "def": "456"} - # ) - # self.assertTrue(isinstance(map_value, KeyValue)) - # self.assertEqual(map_value.key, "map_type") - # self.assertTrue(isinstance(map_value.value, AnyValue)) - # self.assertTrue(isinstance(map_value.value.kvlist_value, KeyValueList)) - - # kvlist_value = map_value.value.kvlist_value - # self.assertTrue(isinstance(kvlist_value.values[0], KeyValue)) - # self.assertEqual(kvlist_value.values[0].key, "asd") - # self.assertEqual(kvlist_value.values[0].value.string_value, "123") - def test_dropped_values(self): span = get_span_with_dropped_attributes_events_links() # pylint:disable=protected-access diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index caacdbdfca..7539cfbf5d 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -28,12 +28,16 @@ from opentelemetry.exporter.otlp.proto.common._log_encoder import encode_logs from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, OTEL_EXPORTER_OTLP_LOGS_HEADERS, OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, @@ -67,6 +71,8 @@ def __init__( self, endpoint: Optional[str] = None, certificate_file: Optional[str] = None, + client_key_file: Optional[str] = None, + client_certificate_file: Optional[str] = None, headers: Optional[Dict[str, str]] = None, timeout: Optional[int] = None, compression: Optional[Compression] = None, @@ -82,6 +88,20 @@ def __init__( OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE, True), ) + self._client_key_file = client_key_file or environ.get( + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, + environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY, None), + ) + self._client_certificate_file = client_certificate_file or environ.get( + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), + ) + self._client_cert = self._client_certificate_file + if self._client_certificate_file and self._client_key_file: + self._client_cert = ( + self._client_certificate_file, + self._client_key_file, + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_LOGS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), @@ -118,6 +138,7 @@ def _export(self, serialized_data: str): data=data, verify=self._certificate_file, timeout=self._timeout, + cert=self._client_cert, ) @staticmethod diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py index ed878dabe8..e9f8cc177e 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -51,11 +51,15 @@ from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_HEADERS, OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, @@ -96,6 +100,8 @@ def __init__( self, endpoint: Optional[str] = None, certificate_file: Optional[str] = None, + client_key_file: Optional[str] = None, + client_certificate_file: Optional[str] = None, headers: Optional[Dict[str, str]] = None, timeout: Optional[int] = None, compression: Optional[Compression] = None, @@ -113,6 +119,20 @@ def __init__( OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE, True), ) + self._client_key_file = client_key_file or environ.get( + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, + environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY, None), + ) + self._client_certificate_file = client_certificate_file or environ.get( + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), + ) + self._client_cert = self._client_certificate_file + if self._client_certificate_file and self._client_key_file: + self._client_cert = ( + self._client_certificate_file, + self._client_key_file, + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_METRICS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), @@ -152,6 +172,7 @@ def _export(self, serialized_data: str): data=data, verify=self._certificate_file, timeout=self._timeout, + cert=self._client_cert, ) @staticmethod diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py index 2ab7e97e02..57c481caa1 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py @@ -31,11 +31,15 @@ from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_HEADERS, OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, OTEL_EXPORTER_OTLP_CERTIFICATE, OTEL_EXPORTER_OTLP_COMPRESSION, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, @@ -65,6 +69,8 @@ def __init__( self, endpoint: Optional[str] = None, certificate_file: Optional[str] = None, + client_key_file: Optional[str] = None, + client_certificate_file: Optional[str] = None, headers: Optional[Dict[str, str]] = None, timeout: Optional[int] = None, compression: Optional[Compression] = None, @@ -80,6 +86,20 @@ def __init__( OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE, True), ) + self._client_key_file = client_key_file or environ.get( + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, + environ.get(OTEL_EXPORTER_OTLP_CLIENT_KEY, None), + ) + self._client_certificate_file = client_certificate_file or environ.get( + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), + ) + self._client_cert = self._client_certificate_file + if self._client_certificate_file and self._client_key_file: + self._client_cert = ( + self._client_certificate_file, + self._client_key_file, + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_TRACES_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), @@ -116,6 +136,7 @@ def _export(self, serialized_data: str): data=data, verify=self._certificate_file, timeout=self._timeout, + cert=self._client_cert, ) @staticmethod diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py index d9011322b9..7a09f76f73 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/metrics/test_otlp_metrics_exporter.py @@ -35,10 +35,14 @@ ) from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY, OTEL_EXPORTER_OTLP_METRICS_COMPRESSION, OTEL_EXPORTER_OTLP_METRICS_DEFAULT_HISTOGRAM_AGGREGATION, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, @@ -74,6 +78,8 @@ OS_ENV_ENDPOINT = "os.env.base" OS_ENV_CERTIFICATE = "os/env/base.crt" +OS_ENV_CLIENT_CERTIFICATE = "os/env/client-cert.pem" +OS_ENV_CLIENT_KEY = "os/env/client-key.pem" OS_ENV_HEADERS = "envHeader1=val1,envHeader2=val2" OS_ENV_TIMEOUT = "30" @@ -115,6 +121,8 @@ def test_constructor_default(self): exporter._endpoint, DEFAULT_ENDPOINT + DEFAULT_METRICS_EXPORT_PATH ) self.assertEqual(exporter._certificate_file, True) + self.assertEqual(exporter._client_certificate_file, None) + self.assertEqual(exporter._client_key_file, None) self.assertEqual(exporter._timeout, DEFAULT_TIMEOUT) self.assertIs(exporter._compression, DEFAULT_COMPRESSION) self.assertEqual(exporter._headers, {}) @@ -124,11 +132,15 @@ def test_constructor_default(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: OS_ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: OS_ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: OS_ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: OS_ENV_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS: OS_ENV_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT: OS_ENV_TIMEOUT, OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: "metrics/certificate.env", + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: "metrics/client-cert.pem", + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: "metrics/client-key.pem", OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: Compression.Deflate.value, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "https://metrics.endpoint.env", OTEL_EXPORTER_OTLP_METRICS_HEADERS: "metricsEnv1=val1,metricsEnv2=val2,metricEnv3===val3==", @@ -140,6 +152,10 @@ def test_exporter_metrics_env_take_priority(self): self.assertEqual(exporter._endpoint, "https://metrics.endpoint.env") self.assertEqual(exporter._certificate_file, "metrics/certificate.env") + self.assertEqual( + exporter._client_certificate_file, "metrics/client-cert.pem" + ) + self.assertEqual(exporter._client_key_file, "metrics/client-key.pem") self.assertEqual(exporter._timeout, 40) self.assertIs(exporter._compression, Compression.Deflate) self.assertEqual( @@ -156,6 +172,8 @@ def test_exporter_metrics_env_take_priority(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: OS_ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: OS_ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: OS_ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: OS_ENV_ENDPOINT, OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "https://metrics.endpoint.env", @@ -167,6 +185,8 @@ def test_exporter_constructor_take_priority(self): exporter = OTLPMetricExporter( endpoint="example.com/1234", certificate_file="path/to/service.crt", + client_key_file="path/to/client-key.pem", + client_certificate_file="path/to/client-cert.pem", headers={"testHeader1": "value1", "testHeader2": "value2"}, timeout=20, compression=Compression.NoCompression, @@ -175,6 +195,10 @@ def test_exporter_constructor_take_priority(self): self.assertEqual(exporter._endpoint, "example.com/1234") self.assertEqual(exporter._certificate_file, "path/to/service.crt") + self.assertEqual( + exporter._client_certificate_file, "path/to/client-cert.pem" + ) + self.assertEqual(exporter._client_key_file, "path/to/client-key.pem") self.assertEqual(exporter._timeout, 20) self.assertIs(exporter._compression, Compression.NoCompression) self.assertEqual( @@ -187,6 +211,8 @@ def test_exporter_constructor_take_priority(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: OS_ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: OS_ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: OS_ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_HEADERS: OS_ENV_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT: OS_ENV_TIMEOUT, @@ -197,6 +223,10 @@ def test_exporter_env(self): exporter = OTLPMetricExporter() self.assertEqual(exporter._certificate_file, OS_ENV_CERTIFICATE) + self.assertEqual( + exporter._client_certificate_file, OS_ENV_CLIENT_CERTIFICATE + ) + self.assertEqual(exporter._client_key_file, OS_ENV_CLIENT_KEY) self.assertEqual(exporter._timeout, int(OS_ENV_TIMEOUT)) self.assertIs(exporter._compression, Compression.Gzip) self.assertEqual( @@ -295,6 +325,7 @@ def test_serialization(self, mock_post): data=serialized_data.SerializeToString(), verify=exporter._certificate_file, timeout=exporter._timeout, + cert=exporter._client_cert, ) @activate diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py index 5300ce85de..c9579dcd1f 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_log_exporter.py @@ -36,10 +36,14 @@ from opentelemetry.sdk._logs import LogRecord as SDKLogRecord from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY, OTEL_EXPORTER_OTLP_LOGS_COMPRESSION, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, OTEL_EXPORTER_OTLP_LOGS_HEADERS, @@ -52,6 +56,8 @@ ENV_ENDPOINT = "http://localhost.env:8080/" ENV_CERTIFICATE = "/etc/base.crt" +ENV_CLIENT_CERTIFICATE = "/etc/client-cert.pem" +ENV_CLIENT_KEY = "/etc/client-key.pem" ENV_HEADERS = "envHeader1=val1,envHeader2=val2" ENV_TIMEOUT = "30" @@ -65,6 +71,8 @@ def test_constructor_default(self): exporter._endpoint, DEFAULT_ENDPOINT + DEFAULT_LOGS_EXPORT_PATH ) self.assertEqual(exporter._certificate_file, True) + self.assertEqual(exporter._client_certificate_file, None) + self.assertEqual(exporter._client_key_file, None) self.assertEqual(exporter._timeout, DEFAULT_TIMEOUT) self.assertIs(exporter._compression, DEFAULT_COMPRESSION) self.assertEqual(exporter._headers, {}) @@ -83,11 +91,15 @@ def test_constructor_default(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: ENV_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS: ENV_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT: ENV_TIMEOUT, OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: "logs/certificate.env", + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE: "logs/client-cert.pem", + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY: "logs/client-key.pem", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: Compression.Deflate.value, OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "https://logs.endpoint.env", OTEL_EXPORTER_OTLP_LOGS_HEADERS: "logsEnv1=val1,logsEnv2=val2,logsEnv3===val3==", @@ -99,6 +111,10 @@ def test_exporter_metrics_env_take_priority(self): self.assertEqual(exporter._endpoint, "https://logs.endpoint.env") self.assertEqual(exporter._certificate_file, "logs/certificate.env") + self.assertEqual( + exporter._client_certificate_file, "logs/client-cert.pem" + ) + self.assertEqual(exporter._client_key_file, "logs/client-key.pem") self.assertEqual(exporter._timeout, 40) self.assertIs(exporter._compression, Compression.Deflate) self.assertEqual( @@ -115,6 +131,8 @@ def test_exporter_metrics_env_take_priority(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: ENV_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS: ENV_HEADERS, @@ -126,6 +144,8 @@ def test_exporter_constructor_take_priority(self): exporter = OTLPLogExporter( endpoint="endpoint.local:69/logs", certificate_file="/hello.crt", + client_key_file="/client-key.pem", + client_certificate_file="/client-cert.pem", headers={"testHeader1": "value1", "testHeader2": "value2"}, timeout=70, compression=Compression.NoCompression, @@ -134,6 +154,8 @@ def test_exporter_constructor_take_priority(self): self.assertEqual(exporter._endpoint, "endpoint.local:69/logs") self.assertEqual(exporter._certificate_file, "/hello.crt") + self.assertEqual(exporter._client_certificate_file, "/client-cert.pem") + self.assertEqual(exporter._client_key_file, "/client-key.pem") self.assertEqual(exporter._timeout, 70) self.assertIs(exporter._compression, Compression.NoCompression) self.assertEqual( @@ -146,6 +168,8 @@ def test_exporter_constructor_take_priority(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: ENV_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS: ENV_HEADERS, @@ -160,6 +184,10 @@ def test_exporter_env(self): exporter._endpoint, ENV_ENDPOINT + DEFAULT_LOGS_EXPORT_PATH ) self.assertEqual(exporter._certificate_file, ENV_CERTIFICATE) + self.assertEqual( + exporter._client_certificate_file, ENV_CLIENT_CERTIFICATE + ) + self.assertEqual(exporter._client_key_file, ENV_CLIENT_KEY) self.assertEqual(exporter._timeout, int(ENV_TIMEOUT)) self.assertIs(exporter._compression, Compression.Gzip) self.assertEqual( diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py index 9a1d1604a2..98b4701582 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/tests/test_proto_span_exporter.py @@ -31,11 +31,15 @@ from opentelemetry.exporter.otlp.proto.http.version import __version__ from opentelemetry.sdk.environment_variables import ( OTEL_EXPORTER_OTLP_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION, OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY, OTEL_EXPORTER_OTLP_TRACES_COMPRESSION, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_HEADERS, @@ -45,6 +49,8 @@ OS_ENV_ENDPOINT = "os.env.base" OS_ENV_CERTIFICATE = "os/env/base.crt" +OS_ENV_CLIENT_CERTIFICATE = "os/env/client-cert.pem" +OS_ENV_CLIENT_KEY = "os/env/client-key.pem" OS_ENV_HEADERS = "envHeader1=val1,envHeader2=val2" OS_ENV_TIMEOUT = "30" @@ -59,6 +65,8 @@ def test_constructor_default(self): exporter._endpoint, DEFAULT_ENDPOINT + DEFAULT_TRACES_EXPORT_PATH ) self.assertEqual(exporter._certificate_file, True) + self.assertEqual(exporter._client_certificate_file, None) + self.assertEqual(exporter._client_key_file, None) self.assertEqual(exporter._timeout, DEFAULT_TIMEOUT) self.assertIs(exporter._compression, DEFAULT_COMPRESSION) self.assertEqual(exporter._headers, {}) @@ -77,11 +85,15 @@ def test_constructor_default(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: OS_ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: OS_ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: OS_ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: OS_ENV_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS: OS_ENV_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT: OS_ENV_TIMEOUT, OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: "traces/certificate.env", + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: "traces/client-cert.pem", + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY: "traces/client-key.pem", OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: Compression.Deflate.value, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "https://traces.endpoint.env", OTEL_EXPORTER_OTLP_TRACES_HEADERS: "tracesEnv1=val1,tracesEnv2=val2,traceEnv3===val3==", @@ -93,6 +105,10 @@ def test_exporter_traces_env_take_priority(self): self.assertEqual(exporter._endpoint, "https://traces.endpoint.env") self.assertEqual(exporter._certificate_file, "traces/certificate.env") + self.assertEqual( + exporter._client_certificate_file, "traces/client-cert.pem" + ) + self.assertEqual(exporter._client_key_file, "traces/client-key.pem") self.assertEqual(exporter._timeout, 40) self.assertIs(exporter._compression, Compression.Deflate) self.assertEqual( @@ -109,6 +125,8 @@ def test_exporter_traces_env_take_priority(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: OS_ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: OS_ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: OS_ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_ENDPOINT: OS_ENV_ENDPOINT, OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "https://traces.endpoint.env", @@ -120,6 +138,8 @@ def test_exporter_constructor_take_priority(self): exporter = OTLPSpanExporter( endpoint="example.com/1234", certificate_file="path/to/service.crt", + client_key_file="path/to/client-key.pem", + client_certificate_file="path/to/client-cert.pem", headers={"testHeader1": "value1", "testHeader2": "value2"}, timeout=20, compression=Compression.NoCompression, @@ -128,6 +148,10 @@ def test_exporter_constructor_take_priority(self): self.assertEqual(exporter._endpoint, "example.com/1234") self.assertEqual(exporter._certificate_file, "path/to/service.crt") + self.assertEqual( + exporter._client_certificate_file, "path/to/client-cert.pem" + ) + self.assertEqual(exporter._client_key_file, "path/to/client-key.pem") self.assertEqual(exporter._timeout, 20) self.assertIs(exporter._compression, Compression.NoCompression) self.assertEqual( @@ -140,6 +164,8 @@ def test_exporter_constructor_take_priority(self): "os.environ", { OTEL_EXPORTER_OTLP_CERTIFICATE: OS_ENV_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE: OS_ENV_CLIENT_CERTIFICATE, + OTEL_EXPORTER_OTLP_CLIENT_KEY: OS_ENV_CLIENT_KEY, OTEL_EXPORTER_OTLP_COMPRESSION: Compression.Gzip.value, OTEL_EXPORTER_OTLP_HEADERS: OS_ENV_HEADERS, OTEL_EXPORTER_OTLP_TIMEOUT: OS_ENV_TIMEOUT, @@ -150,6 +176,10 @@ def test_exporter_env(self): exporter = OTLPSpanExporter() self.assertEqual(exporter._certificate_file, OS_ENV_CERTIFICATE) + self.assertEqual( + exporter._client_certificate_file, OS_ENV_CLIENT_CERTIFICATE + ) + self.assertEqual(exporter._client_key_file, OS_ENV_CLIENT_KEY) self.assertEqual(exporter._timeout, int(OS_ENV_TIMEOUT)) self.assertIs(exporter._compression, Compression.Gzip) self.assertEqual( diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py index a69e451cbb..1c96264288 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/environment_variables.py @@ -403,6 +403,76 @@ TLS credentials of gRPC client for metrics. Should only be used for a secure connection for exporting metrics. """ +OTEL_EXPORTER_OTLP_CLIENT_KEY = "OTEL_EXPORTER_OTLP_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format. +""" + +OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY = "OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format for traces. +""" + +OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format for metrics. +""" + +OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY = "OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY" +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY` stores the path to the client private key to use +in mTLS communication in PEM format for logs. +""" + +OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE = "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE" +""" +.. envvar:: OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format. +""" + +OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE = ( + "OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE" +) +""" +.. envvar:: OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format for traces. +""" + +OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE = ( + "OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE" +) +""" +.. envvar:: OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format for metrics. +""" + +OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE = ( + "OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE" +) +""" +.. envvar:: OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE + +The :envvar:`OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE` stores the path to the client certificate/chain trust for +clients private key to use in mTLS communication in PEM format for logs. +""" + OTEL_EXPORTER_OTLP_TRACES_HEADERS = "OTEL_EXPORTER_OTLP_TRACES_HEADERS" """ .. envvar:: OTEL_EXPORTER_OTLP_TRACES_HEADERS From 6bef4e640cfb7027f874c2b017784d478ead46ef Mon Sep 17 00:00:00 2001 From: Chittalkumar Patel Date: Fri, 15 Dec 2023 21:08:50 +0000 Subject: [PATCH 02/21] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 894dccc990..6255d371c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3524](https://github.com/open-telemetry/opentelemetry-python/pull/3524)) - Handle `taskName` `logrecord` attribute ([#3557](https://github.com/open-telemetry/opentelemetry-python/pull/3557)) +- Implement client key file and client certificate file for all OTLP exporters + ([#3590](https://github.com/open-telemetry/opentelemetry-python/pull/3590)) ## Version 1.21.0/0.42b0 (2023-11-01) From e0b9ac7d491e41dba09c91a3d4ab142b7151920b Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 11 Aug 2024 23:49:30 +0900 Subject: [PATCH 03/21] Update changelog and add logging to _load_credentials. --- CHANGELOG.md | 4 ++-- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 241dbb7a7e..6910680b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#4103](https://github.com/open-telemetry/opentelemetry-python/pull/4103)) - Update semantic conventions to version 1.27.0 ([#4104](https://github.com/open-telemetry/opentelemetry-python/pull/4104)) +- Implement Client Key and Certificate File Support for All OTLP Exporters + ([#4115](https://github.com/open-telemetry/opentelemetry-python/pull/4115)) ## Version 1.26.0/0.47b0 (2024-07-25) @@ -199,8 +201,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#3524](https://github.com/open-telemetry/opentelemetry-python/pull/3524)) - Handle `taskName` `logrecord` attribute ([#3557](https://github.com/open-telemetry/opentelemetry-python/pull/3557)) -- Implement client key file and client certificate file for all OTLP exporters - ([#3590](https://github.com/open-telemetry/opentelemetry-python/pull/3590)) ## Version 1.21.0/0.42b0 (2023-11-01) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 63bc7e9e08..7eee9ed9d5 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -141,8 +141,10 @@ def _load_credentials( private_key=private_key, certificate_chain=certificate_chain, ) - except FileNotFoundError: - logger.exception("Failed to read credential file") + except FileNotFoundError as e: + logger.exception( + f"Failed to read credential file: {e.filename}. Please check if the file exists and is accessible." + ) return None From 10ba43d2ea3478d8c81296cd04333a54cf91050e Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 11 Aug 2024 23:52:36 +0900 Subject: [PATCH 04/21] Change CHANGELOG.md PR to #4116 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6910680b55..c636cfe57b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Update semantic conventions to version 1.27.0 ([#4104](https://github.com/open-telemetry/opentelemetry-python/pull/4104)) - Implement Client Key and Certificate File Support for All OTLP Exporters - ([#4115](https://github.com/open-telemetry/opentelemetry-python/pull/4115)) + ([#4116](https://github.com/open-telemetry/opentelemetry-python/pull/4116)) ## Version 1.26.0/0.47b0 (2024-07-25) From e59453d9b57dc1bf91353a13bfaf297eb4a63120 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Wed, 14 Aug 2024 17:25:36 +0900 Subject: [PATCH 05/21] refactor(otlp exporter): refactor client certificate and key handling - Moved `client_key_file` and `client_certificate_file` to local variables as suggested. - Added a comment explaining the retention of these as instance variables for testing purposes. - Addressed all review comments to improve code readability and maintainability. --- .../exporter/otlp/proto/grpc/exporter.py | 20 +++++++++---------- .../otlp/proto/http/_log_exporter/__init__.py | 1 + 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 7eee9ed9d5..912cb62cea 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -121,17 +121,14 @@ def get_resource_data( def _get_file_content(file_path: str) -> bytes: - file = open(file_path, "rb") - content = file.read() - file.close() - return content - + with open(file_path, "rb") as file: + return file.read() def _load_credentials( - certificate_file: str, - client_key_file: str, - client_certificate_file: str, -) -> ChannelCredentials: + certificate_file: Optional[str], + client_key_file: Optional[str], + client_certificate_file: Optional[str], +) -> Optional[ChannelCredentials]: try: root_certificates = _get_file_content(certificate_file) private_key = _get_file_content(client_key_file) @@ -156,10 +153,11 @@ def _get_credentials( ) -> ChannelCredentials: if creds is not None: return creds + certificate_file = environ.get(certificate_file_env_key) - client_key_file = environ.get(client_key_file_env_key) - client_certificate_file = environ.get(client_certificate_file_env_key) if certificate_file: + client_key_file = environ.get(client_key_file_env_key) + client_certificate_file = environ.get(client_certificate_file_env_key) return _load_credentials( certificate_file, client_key_file, client_certificate_file ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index 416753fb98..f4facf8804 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -84,6 +84,7 @@ def __init__( environ.get(OTEL_EXPORTER_OTLP_ENDPOINT, DEFAULT_ENDPOINT) ), ) + # Keeping these as instance variables because they are used in tests self._certificate_file = certificate_file or environ.get( OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CERTIFICATE, True), From d254a53454cd07bfe84ca415f816e87c0e64221f Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Wed, 14 Aug 2024 17:45:15 +0900 Subject: [PATCH 06/21] refactor(otlp exporter): refactor client certificate and key handling - Moved `client_key_file` and `client_certificate_file` to local variables as suggested. - Added a comment explaining the retention of these as instance variables for testing purposes. - Addressed all review comments to improve code readability and maintainability. --- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 912cb62cea..396931e8c5 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -124,10 +124,11 @@ def _get_file_content(file_path: str) -> bytes: with open(file_path, "rb") as file: return file.read() + def _load_credentials( - certificate_file: Optional[str], - client_key_file: Optional[str], - client_certificate_file: Optional[str], + certificate_file: str, + client_key_file: str, + client_certificate_file: str, ) -> Optional[ChannelCredentials]: try: root_certificates = _get_file_content(certificate_file) From c87f715efa5ad000eea2fb791384ebe13c69edf8 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Thu, 15 Aug 2024 10:19:55 +0900 Subject: [PATCH 07/21] test: Add coverage for OTLP exporters without client certificates --- .../exporter/otlp/proto/grpc/exporter.py | 8 +++--- .../tests/logs/test_otlp_logs_exporter.py | 25 +++++++++++++++++- .../tests/test_otlp_metrics_exporter.py | 26 ++++++++++++++++++- .../proto/http/metric_exporter/__init__.py | 11 ++++---- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 396931e8c5..c6c91f0f66 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -120,7 +120,7 @@ def get_resource_data( return _get_resource_data(sdk_resource_scope_data, resource_class, name) -def _get_file_content(file_path: str) -> bytes: +def _read_file(file_path: str) -> bytes: with open(file_path, "rb") as file: return file.read() @@ -131,9 +131,9 @@ def _load_credentials( client_certificate_file: str, ) -> Optional[ChannelCredentials]: try: - root_certificates = _get_file_content(certificate_file) - private_key = _get_file_content(client_key_file) - certificate_chain = _get_file_content(client_certificate_file) + root_certificates = _read_file(certificate_file) + private_key = _read_file(client_key_file) + certificate_chain = _read_file(client_certificate_file) return ssl_channel_credentials( root_certificates=root_certificates, private_key=private_key, diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 49af50eda3..135d15fe7b 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -226,7 +226,7 @@ def test_exporting(self): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables(self, mock_exporter_mixin): + def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPLogExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -238,6 +238,29 @@ def test_env_variables(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", + OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables_without_client_certificates(self, mock_exporter_mixin): + OTLPLogExporter() + + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + self.assertEqual(kwargs["endpoint"], "logs:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNone(kwargs["credentials"]) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index 9e733b992d..3c87f7ae57 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -237,7 +237,7 @@ def test_preferred_temporality(self): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables(self, mock_exporter_mixin): + def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPMetricExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -250,6 +250,30 @@ def test_env_variables(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317", + OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2", + OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables_without_client_certificates(self, mock_exporter_mixin): + OTLPMetricExporter() + + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + + self.assertEqual(kwargs["endpoint"], "collector:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNone(kwargs["credentials"]) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py index ce71989543..16ac042dd8 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -127,12 +127,11 @@ def __init__( OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), ) - self._client_cert = self._client_certificate_file - if self._client_certificate_file and self._client_key_file: - self._client_cert = ( - self._client_certificate_file, - self._client_key_file, - ) + self._client_cert = ( + (self._client_certificate_file, self._client_key_file) + if self._client_certificate_file and self._client_key_file + else self._client_certificate_file + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_METRICS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), From 4f4942fadb6284586711195319de73e7513e62e1 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Thu, 15 Aug 2024 10:20:15 +0900 Subject: [PATCH 08/21] test: Add coverage for OTLP exporters without client certificates --- .../tests/test_otlp_trace_exporter.py | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 60731893ab..417b1467d4 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -246,7 +246,7 @@ def test_exporting(self): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables(self, mock_exporter_mixin): + def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPSpanExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -259,6 +259,30 @@ def test_env_variables(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317", + OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2", + OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables_without_client_certificates(self, mock_exporter_mixin): + OTLPSpanExporter() + + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + + self.assertEqual(kwargs["endpoint"], "collector:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNone(kwargs["credentials"]) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) From b16967a0992aff71e1fb19bb3cbdb81578963a10 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Thu, 15 Aug 2024 22:03:44 +0900 Subject: [PATCH 09/21] test: Add coverage for OTLP exporters without client certificates --- .../tests/logs/test_otlp_logs_exporter.py | 4 +++- .../tests/test_otlp_metrics_exporter.py | 4 +++- .../tests/test_otlp_trace_exporter.py | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 135d15fe7b..8008d1b65c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -250,7 +250,9 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_without_client_certificates(self, mock_exporter_mixin): + def test_env_variables_without_client_certificates( + self, mock_exporter_mixin + ): OTLPLogExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index 3c87f7ae57..e25ca00f38 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -262,7 +262,9 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_without_client_certificates(self, mock_exporter_mixin): + def test_env_variables_without_client_certificates( + self, mock_exporter_mixin + ): OTLPMetricExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index d4702f9e6b..ddc3853b7c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -272,7 +272,9 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_without_client_certificates(self, mock_exporter_mixin): + def test_env_variables_without_client_certificates( + self, mock_exporter_mixin + ): OTLPSpanExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) From bfcea4e4d67904c60bd2471175fca5066fc12144 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Thu, 15 Aug 2024 22:13:41 +0900 Subject: [PATCH 10/21] fix: fix linting for test_otlp_trace_exporter --- .../tests/test_otlp_trace_exporter.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index ddc3853b7c..a89324d6de 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -249,10 +249,8 @@ def test_exporting(self): ) def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPSpanExporter() - self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] - self.assertEqual(kwargs["endpoint"], "collector:4317") self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") self.assertEqual(kwargs["timeout"], 10) @@ -276,10 +274,8 @@ def test_env_variables_without_client_certificates( self, mock_exporter_mixin ): OTLPSpanExporter() - self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] - self.assertEqual(kwargs["endpoint"], "collector:4317") self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") self.assertEqual(kwargs["timeout"], 10) From 3b62fd531dff3bfb24bcd0dfb31be7eaab172732 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Fri, 16 Aug 2024 02:40:36 +0900 Subject: [PATCH 11/21] fix: fix linting for test_otlp_trace_exporter --- .../tests/logs/test_otlp_logs_exporter.py | 25 +++++++++---------- .../tests/test_otlp_metrics_exporter.py | 24 ++++++++---------- .../tests/test_otlp_trace_exporter.py | 24 ++++++++---------- 3 files changed, 34 insertions(+), 39 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 8008d1b65c..5e881a4b2e 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -212,12 +212,6 @@ def test_exporting(self): "os.environ", { OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", - OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR - + "/../fixtures/test.cert", - OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE: THIS_DIR - + "/../fixtures/test-client-cert.pem", - OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY: THIS_DIR - + "/../fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", @@ -226,7 +220,7 @@ def test_exporting(self): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_with_client_certificates(self, mock_exporter_mixin): + def test_env_variables(self, mock_exporter_mixin): OTLPLogExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -235,13 +229,19 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2") self.assertEqual(kwargs["timeout"], 10) self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNotNone(kwargs["credentials"]) - self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + self.assertIsNone(kwargs["credentials"]) + # Create a new test method specifically for client certificates @patch.dict( "os.environ", { OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + + "/../fixtures/test.cert", + OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE: THIS_DIR + + "/../fixtures/test-client-cert.pem", + OTEL_EXPORTER_OTLP_LOGS_CLIENT_KEY: THIS_DIR + + "/../fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", @@ -250,9 +250,7 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_without_client_certificates( - self, mock_exporter_mixin - ): + def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPLogExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -261,7 +259,8 @@ def test_env_variables_without_client_certificates( self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2") self.assertEqual(kwargs["timeout"], 10) self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNone(kwargs["credentials"]) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index e25ca00f38..e8005b39d7 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -223,12 +223,6 @@ def test_preferred_temporality(self): "os.environ", { OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317", - OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR - + "/fixtures/test.cert", - OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: THIS_DIR - + "/fixtures/test-client-cert.pem", - OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: THIS_DIR - + "/fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip", @@ -237,7 +231,7 @@ def test_preferred_temporality(self): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_with_client_certificates(self, mock_exporter_mixin): + def test_env_variables(self, mock_exporter_mixin): OTLPMetricExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -247,13 +241,18 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") self.assertEqual(kwargs["timeout"], 10) self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNotNone(kwargs["credentials"]) - self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + self.assertIsNone(kwargs["credentials"]) @patch.dict( "os.environ", { OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317", + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR + + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE: THIS_DIR + + "/fixtures/test-client-cert.pem", + OTEL_EXPORTER_OTLP_METRICS_CLIENT_KEY: THIS_DIR + + "/fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip", @@ -262,9 +261,7 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_without_client_certificates( - self, mock_exporter_mixin - ): + def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPMetricExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -274,7 +271,8 @@ def test_env_variables_without_client_certificates( self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") self.assertEqual(kwargs["timeout"], 10) self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNone(kwargs["credentials"]) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index a89324d6de..bf6d407d22 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -233,12 +233,6 @@ def test_exporting(self): "os.environ", { OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317", - OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR - + "/fixtures/test.cert", - OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: THIS_DIR - + "/fixtures/test-client-cert.pem", - OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY: THIS_DIR - + "/fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10", OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip", @@ -247,7 +241,7 @@ def test_exporting(self): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_with_client_certificates(self, mock_exporter_mixin): + def test_env_variables(self, mock_exporter_mixin): OTLPSpanExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] @@ -255,13 +249,18 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") self.assertEqual(kwargs["timeout"], 10) self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNotNone(kwargs["credentials"]) - self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + self.assertIsNone(kwargs["credentials"]) @patch.dict( "os.environ", { OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317", + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR + + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE: THIS_DIR + + "/fixtures/test-client-cert.pem", + OTEL_EXPORTER_OTLP_TRACES_CLIENT_KEY: THIS_DIR + + "/fixtures/test-client-key.pem", OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10", OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip", @@ -270,9 +269,7 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_without_client_certificates( - self, mock_exporter_mixin - ): + def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPSpanExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] @@ -280,7 +277,8 @@ def test_env_variables_without_client_certificates( self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") self.assertEqual(kwargs["timeout"], 10) self.assertEqual(kwargs["compression"], Compression.Gzip) - self.assertIsNone(kwargs["credentials"]) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" From 13c8963a24d51e69c501243bdd989dcb7ade99dc Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sat, 17 Aug 2024 01:16:14 +0900 Subject: [PATCH 12/21] test: add test case for OTLP log exporter with only certificate set --- .../tests/logs/test_otlp_logs_exporter.py | 26 ++++++++++++++++++ .../tests/test_otlp_metrics_exporter.py | 27 +++++++++++++++++++ .../tests/test_otlp_trace_exporter.py | 26 ++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 5e881a4b2e..4811f5499c 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=too-many-lines + import time from concurrent.futures import ThreadPoolExecutor from os.path import dirname @@ -262,6 +264,30 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + "/../fixtures/test.cert", + OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", + OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables_with_only_certificate(self, mock_exporter_mixin): + OTLPLogExporter() + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + self.assertEqual(kwargs["endpoint"], "logs:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = VALUE=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index e8005b39d7..b9f96a9865 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=too-many-lines + import threading from concurrent.futures import ThreadPoolExecutor @@ -274,6 +276,31 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317", + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2", + OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables_with_only_certificate(self, mock_exporter_mixin): + OTLPMetricExporter() + + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + self.assertEqual(kwargs["endpoint"], "collector:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index bf6d407d22..a0e03a7003 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +# pylint: disable=too-many-lines + import os import threading from concurrent.futures import ThreadPoolExecutor @@ -280,6 +282,30 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch.dict( + "os.environ", + { + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317", + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2", + OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10", + OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip", + }, + ) + @patch( + "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" + ) + def test_env_variables_with_only_certificate(self, mock_exporter_mixin): + OTLPSpanExporter() + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) + _, kwargs = mock_exporter_mixin.call_args_list[0] + self.assertEqual(kwargs["endpoint"], "collector:4317") + self.assertEqual(kwargs["headers"], " key1=value1,KEY2 = value=2") + self.assertEqual(kwargs["timeout"], 10) + self.assertEqual(kwargs["compression"], Compression.Gzip) + self.assertIsNotNone(kwargs["credentials"]) + self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) From 2feed0d01dd96d2e620fc38e8ed6de9214a7bf6a Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sat, 17 Aug 2024 01:25:01 +0900 Subject: [PATCH 13/21] refactor: handle FileNotFoundError within _read_file function --- .../exporter/otlp/proto/grpc/exporter.py | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index c6c91f0f66..5e71e18270 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -120,31 +120,34 @@ def get_resource_data( return _get_resource_data(sdk_resource_scope_data, resource_class, name) -def _read_file(file_path: str) -> bytes: - with open(file_path, "rb") as file: - return file.read() - +def _read_file(file_path: str) -> Optional[bytes]: + try: + with open(file_path, "rb") as file: + return file.read() + except FileNotFoundError as e: + logger.exception( + f"Failed to read file: {e.filename}. Please check if the file exists and is accessible." + ) + return None def _load_credentials( certificate_file: str, client_key_file: str, client_certificate_file: str, ) -> Optional[ChannelCredentials]: - try: - root_certificates = _read_file(certificate_file) - private_key = _read_file(client_key_file) - certificate_chain = _read_file(client_certificate_file) - return ssl_channel_credentials( - root_certificates=root_certificates, - private_key=private_key, - certificate_chain=certificate_chain, - ) - except FileNotFoundError as e: - logger.exception( - f"Failed to read credential file: {e.filename}. Please check if the file exists and is accessible." - ) + root_certificates = _read_file(certificate_file) + private_key = _read_file(client_key_file) + certificate_chain = _read_file(client_certificate_file) + + if root_certificates is None or private_key is None or certificate_chain is None: return None + return ssl_channel_credentials( + root_certificates=root_certificates, + private_key=private_key, + certificate_chain=certificate_chain, + ) + def _get_credentials( creds: Optional[ChannelCredentials], From 9e1e80dd8528be065f6b1e410dc53d82224f1730 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sat, 17 Aug 2024 01:45:56 +0900 Subject: [PATCH 14/21] refactor: handle FileNotFoundError within _read_file function --- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 5e71e18270..625bde612a 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -120,7 +120,11 @@ def get_resource_data( return _get_resource_data(sdk_resource_scope_data, resource_class, name) -def _read_file(file_path: str) -> Optional[bytes]: +def _read_file(file_path: Optional[str]) -> Optional[bytes]: + if file_path is None: + logger.error("No file path provided for reading. Please check the environment variables.") + return None + try: with open(file_path, "rb") as file: return file.read() From 5eeb62a1765cd164315bf78b4f75f17bd0fc8441 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sat, 17 Aug 2024 01:51:35 +0900 Subject: [PATCH 15/21] refactor: handle FileNotFoundError within _read_file function --- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 625bde612a..1320f6228f 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -143,9 +143,6 @@ def _load_credentials( private_key = _read_file(client_key_file) certificate_chain = _read_file(client_certificate_file) - if root_certificates is None or private_key is None or certificate_chain is None: - return None - return ssl_channel_credentials( root_certificates=root_certificates, private_key=private_key, From d0f48d4e9c7d0a2f9f10cb50f9f46d0382a35df2 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sat, 17 Aug 2024 01:56:33 +0900 Subject: [PATCH 16/21] fix: fix linting for test_otlp_trace_exporter --- .../tests/logs/test_otlp_logs_exporter.py | 3 ++- .../tests/test_otlp_metrics_exporter.py | 3 ++- .../tests/test_otlp_trace_exporter.py | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 4811f5499c..044ff346c7 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -268,7 +268,8 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): "os.environ", { OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: "logs:4317", - OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + "/../fixtures/test.cert", + OTEL_EXPORTER_OTLP_LOGS_CERTIFICATE: THIS_DIR + + "/../fixtures/test.cert", OTEL_EXPORTER_OTLP_LOGS_HEADERS: " key1=value1,KEY2 = VALUE=2", OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: "gzip", diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index b9f96a9865..c0893347c0 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -280,7 +280,8 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): "os.environ", { OTEL_EXPORTER_OTLP_METRICS_ENDPOINT: "collector:4317", - OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_METRICS_CERTIFICATE: THIS_DIR + + "/fixtures/test.cert", OTEL_EXPORTER_OTLP_METRICS_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_METRICS_TIMEOUT: "10", OTEL_EXPORTER_OTLP_METRICS_COMPRESSION: "gzip", diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index a0e03a7003..8bd5099d00 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -286,7 +286,8 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): "os.environ", { OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "collector:4317", - OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR + "/fixtures/test.cert", + OTEL_EXPORTER_OTLP_TRACES_CERTIFICATE: THIS_DIR + + "/fixtures/test.cert", OTEL_EXPORTER_OTLP_TRACES_HEADERS: " key1=value1,KEY2 = value=2", OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: "10", OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: "gzip", From 89376ec0fb1e3c53cb8064df4d007e678bc0f70e Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sat, 17 Aug 2024 01:58:12 +0900 Subject: [PATCH 17/21] fix: fix linting for test_otlp_trace_exporter --- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 1320f6228f..0b6f596298 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -122,7 +122,9 @@ def get_resource_data( def _read_file(file_path: Optional[str]) -> Optional[bytes]: if file_path is None: - logger.error("No file path provided for reading. Please check the environment variables.") + logger.error( + "No file path provided for reading. Please check the environment variables." + ) return None try: @@ -134,6 +136,7 @@ def _read_file(file_path: Optional[str]) -> Optional[bytes]: ) return None + def _load_credentials( certificate_file: str, client_key_file: str, From c48d4ee414246e6c62b1715cc5a2807057fb99ba Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Sun, 18 Aug 2024 20:45:44 +0900 Subject: [PATCH 18/21] fix: fix linting for test_otlp_trace_exporter --- .../exporter/otlp/proto/grpc/exporter.py | 24 +++++++++---------- .../tests/logs/test_otlp_logs_exporter.py | 8 ++++++- .../tests/test_otlp_metrics_exporter.py | 7 +++++- .../tests/test_otlp_trace_exporter.py | 9 ++++++- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 0b6f596298..716d1db972 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -121,12 +121,6 @@ def get_resource_data( def _read_file(file_path: Optional[str]) -> Optional[bytes]: - if file_path is None: - logger.error( - "No file path provided for reading. Please check the environment variables." - ) - return None - try: with open(file_path, "rb") as file: return file.read() @@ -138,13 +132,19 @@ def _read_file(file_path: Optional[str]) -> Optional[bytes]: def _load_credentials( - certificate_file: str, - client_key_file: str, - client_certificate_file: str, + certificate_file: Optional[str], + client_key_file: Optional[str], + client_certificate_file: Optional[str], ) -> Optional[ChannelCredentials]: - root_certificates = _read_file(certificate_file) - private_key = _read_file(client_key_file) - certificate_chain = _read_file(client_certificate_file) + root_certificates = ( + _read_file(certificate_file) if certificate_file else None + ) + private_key = _read_file(client_key_file) if client_key_file else None + certificate_chain = ( + _read_file(client_certificate_file) + if client_certificate_file + else None + ) return ssl_channel_credentials( root_certificates=root_certificates, diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py index 044ff346c7..fc2211c5ae 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/logs/test_otlp_logs_exporter.py @@ -278,8 +278,12 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_with_only_certificate(self, mock_exporter_mixin): + @patch("logging.Logger.error") + def test_env_variables_with_only_certificate( + self, mock_logger_error, mock_exporter_mixin + ): OTLPLogExporter() + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] self.assertEqual(kwargs["endpoint"], "logs:4317") @@ -289,6 +293,8 @@ def test_env_variables_with_only_certificate(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + mock_logger_error.assert_not_called() + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py index c0893347c0..f9f9427b77 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_metrics_exporter.py @@ -290,7 +290,10 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_with_only_certificate(self, mock_exporter_mixin): + @patch("logging.Logger.error") + def test_env_variables_with_only_certificate( + self, mock_logger_error, mock_exporter_mixin + ): OTLPMetricExporter() self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) @@ -302,6 +305,8 @@ def test_env_variables_with_only_certificate(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + mock_logger_error.assert_not_called() + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py index 8bd5099d00..d618ffb13a 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/tests/test_otlp_trace_exporter.py @@ -273,6 +273,7 @@ def test_env_variables(self, mock_exporter_mixin): ) def test_env_variables_with_client_certificates(self, mock_exporter_mixin): OTLPSpanExporter() + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] self.assertEqual(kwargs["endpoint"], "collector:4317") @@ -296,8 +297,12 @@ def test_env_variables_with_client_certificates(self, mock_exporter_mixin): @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.OTLPExporterMixin.__init__" ) - def test_env_variables_with_only_certificate(self, mock_exporter_mixin): + @patch("logging.Logger.error") + def test_env_variables_with_only_certificate( + self, mock_logger_error, mock_exporter_mixin + ): OTLPSpanExporter() + self.assertTrue(len(mock_exporter_mixin.call_args_list) == 1) _, kwargs = mock_exporter_mixin.call_args_list[0] self.assertEqual(kwargs["endpoint"], "collector:4317") @@ -307,6 +312,8 @@ def test_env_variables_with_only_certificate(self, mock_exporter_mixin): self.assertIsNotNone(kwargs["credentials"]) self.assertIsInstance(kwargs["credentials"], ChannelCredentials) + mock_logger_error.assert_not_called() + @patch( "opentelemetry.exporter.otlp.proto.grpc.exporter.ssl_channel_credentials" ) From 5204b06bdc9977a6ebe81696d19c4d75965055d5 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Tue, 20 Aug 2024 02:20:13 +0900 Subject: [PATCH 19/21] refactor: update `_read_file` function to make `file_path` mandatory --- .../src/opentelemetry/exporter/otlp/proto/grpc/exporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py index 716d1db972..b07d24e0d0 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py +++ b/exporter/opentelemetry-exporter-otlp-proto-grpc/src/opentelemetry/exporter/otlp/proto/grpc/exporter.py @@ -120,7 +120,7 @@ def get_resource_data( return _get_resource_data(sdk_resource_scope_data, resource_class, name) -def _read_file(file_path: Optional[str]) -> Optional[bytes]: +def _read_file(file_path: str) -> Optional[bytes]: try: with open(file_path, "rb") as file: return file.read() From 651cc7d3ed163f1f95d2e27dd7b75b5c5baa29b7 Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Tue, 20 Aug 2024 21:19:46 +0900 Subject: [PATCH 20/21] refactor: standardize handling of client certificate and key file assignment --- .../otlp/proto/http/_log_exporter/__init__.py | 11 +++++------ .../otlp/proto/http/metric_exporter/__init__.py | 11 ++++++----- .../otlp/proto/http/trace_exporter/__init__.py | 11 +++++------ 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py index f4facf8804..597b012a49 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/_log_exporter/__init__.py @@ -97,12 +97,11 @@ def __init__( OTEL_EXPORTER_OTLP_LOGS_CLIENT_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), ) - self._client_cert = self._client_certificate_file - if self._client_certificate_file and self._client_key_file: - self._client_cert = ( - self._client_certificate_file, - self._client_key_file, - ) + self._client_cert = ( + (self._client_certificate_file, self._client_key_file) + if self._client_certificate_file and self._client_key_file + else self._client_certificate_file + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_LOGS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py index 16ac042dd8..ce71989543 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -127,11 +127,12 @@ def __init__( OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), ) - self._client_cert = ( - (self._client_certificate_file, self._client_key_file) - if self._client_certificate_file and self._client_key_file - else self._client_certificate_file - ) + self._client_cert = self._client_certificate_file + if self._client_certificate_file and self._client_key_file: + self._client_cert = ( + self._client_certificate_file, + self._client_key_file, + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_METRICS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py index 0a83bf838b..ac69b6acde 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/trace_exporter/__init__.py @@ -94,12 +94,11 @@ def __init__( OTEL_EXPORTER_OTLP_TRACES_CLIENT_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), ) - self._client_cert = self._client_certificate_file - if self._client_certificate_file and self._client_key_file: - self._client_cert = ( - self._client_certificate_file, - self._client_key_file, - ) + self._client_cert = ( + (self._client_certificate_file, self._client_key_file) + if self._client_certificate_file and self._client_key_file + else self._client_certificate_file + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_TRACES_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""), From 19f28361e0ff5fa3ed0e23e33e5599a735be9a6a Mon Sep 17 00:00:00 2001 From: Sandy Chen Date: Tue, 20 Aug 2024 21:21:05 +0900 Subject: [PATCH 21/21] refactor: standardize handling of client certificate and key file assignment --- .../otlp/proto/http/metric_exporter/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py index ce71989543..16ac042dd8 100644 --- a/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py +++ b/exporter/opentelemetry-exporter-otlp-proto-http/src/opentelemetry/exporter/otlp/proto/http/metric_exporter/__init__.py @@ -127,12 +127,11 @@ def __init__( OTEL_EXPORTER_OTLP_METRICS_CLIENT_CERTIFICATE, environ.get(OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE, None), ) - self._client_cert = self._client_certificate_file - if self._client_certificate_file and self._client_key_file: - self._client_cert = ( - self._client_certificate_file, - self._client_key_file, - ) + self._client_cert = ( + (self._client_certificate_file, self._client_key_file) + if self._client_certificate_file and self._client_key_file + else self._client_certificate_file + ) headers_string = environ.get( OTEL_EXPORTER_OTLP_METRICS_HEADERS, environ.get(OTEL_EXPORTER_OTLP_HEADERS, ""),