From bca43ed846c1461c1233f33795d494262360652e Mon Sep 17 00:00:00 2001 From: Matthew Sainsbury Date: Wed, 27 Nov 2024 15:34:37 -0800 Subject: [PATCH] config: add client certificate and client key functionality --- config/config.go | 37 +++++++++++------ config/config_test.go | 57 +++++++++++++++++++++++++ config/log.go | 20 ++++----- config/log_test.go | 96 +++++++++++++++++++++++++++++-------------- config/metric.go | 20 ++++----- config/metric_test.go | 76 +++++++++++++++++++++++++--------- config/trace.go | 20 ++++----- config/trace_test.go | 96 +++++++++++++++++++++++++++++-------------- 8 files changed, 293 insertions(+), 129 deletions(-) diff --git a/config/config.go b/config/config.go index 3fb3b9abc5b..8a4201cf20e 100644 --- a/config/config.go +++ b/config/config.go @@ -8,6 +8,7 @@ import ( "crypto/tls" "crypto/x509" "errors" + "fmt" "os" "gopkg.in/yaml.v3" @@ -159,19 +160,29 @@ func toStringMap(pairs []NameStringValuePair) map[string]string { return output } -// createTLSConfig creates a tls.Config from a raw certificate bytes -// to verify a server certificate. -func createTLSConfig(certFile string) (*tls.Config, error) { - b, err := os.ReadFile(certFile) - if err != nil { - return nil, err +// createTLSConfig creates a tls.Config from certificate files. +func createTLSConfig(caCertFile *string, clientCertFile *string, clientKeyFile *string) (*tls.Config, error) { + tlsConfig := &tls.Config{} + if caCertFile != nil { + caText, err := os.ReadFile(*caCertFile) + if err != nil { + return nil, err + } + certPool := x509.NewCertPool() + if !certPool.AppendCertsFromPEM(caText) { + return nil, errors.New("could not create certificate authority chain from certificate") + } + tlsConfig.RootCAs = certPool } - cp := x509.NewCertPool() - if ok := cp.AppendCertsFromPEM(b); !ok { - return nil, errors.New("failed to append certificate to the cert pool") + if clientCertFile != nil { + if clientKeyFile == nil { + return nil, errors.New("client certificate was provided but no client key was provided") + } + clientCert, err := tls.LoadX509KeyPair(*clientCertFile, *clientKeyFile) + if err != nil { + return nil, fmt.Errorf("could not use client certificate: %w", err) + } + tlsConfig.Certificates = []tls.Certificate{clientCert} } - - return &tls.Config{ - RootCAs: cp, - }, nil + return tlsConfig, nil } diff --git a/config/config_test.go b/config/config_test.go index cdc3ddcd45b..fe3f654fe09 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -5,6 +5,7 @@ package config import ( "context" + "crypto/tls" "encoding/json" "errors" "os" @@ -489,6 +490,62 @@ func TestSerializeJSON(t *testing.T) { } } +func TestCreateTLSConfig(t *testing.T) { + tests := []struct { + name string + caCertFile *string + clientCertFile *string + clientKeyFile *string + wantErr error + want func(*tls.Config, *testing.T) + }{ + { + name: "no-input", + want: func(result *tls.Config, t *testing.T) { + require.Nil(t, result.Certificates) + require.Nil(t, result.RootCAs) + }, + }, + { + name: "only-cacert-provided", + caCertFile: ptr(filepath.Join("testdata", "ca.crt")), + want: func(result *tls.Config, t *testing.T) { + require.Nil(t, result.Certificates) + require.NotNil(t, result.RootCAs) + }, + }, + { + name: "nonexistent-cacert-file", + caCertFile: ptr("nowhere.crt"), + wantErr: errors.New("open nowhere.crt: no such file or directory"), + }, + { + name: "nonexistent-clientcert-file", + clientCertFile: ptr("nowhere.crt"), + clientKeyFile: ptr("nowhere.crt"), + wantErr: errors.New("could not use client certificate: open nowhere.crt: no such file or directory"), + }, + { + name: "bad-cacert-file", + caCertFile: ptr(filepath.Join("testdata", "bad_cert.crt")), + wantErr: errors.New("could not create certificate authority chain from certificate"), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := createTLSConfig(tt.caCertFile, tt.clientCertFile, tt.clientKeyFile) + + if tt.wantErr != nil { + require.Equal(t, tt.wantErr.Error(), err.Error()) + } else { + require.NoError(t, err) + tt.want(got, t) + } + }) + } +} + func ptr[T any](v T) *T { return &v } diff --git a/config/log.go b/config/log.go index ba729f8d792..bf38523e3cf 100644 --- a/config/log.go +++ b/config/log.go @@ -156,13 +156,11 @@ func otlpHTTPLogExporter(ctx context.Context, otlpConfig *OTLP) (sdklog.Exporter opts = append(opts, otlploghttp.WithHeaders(toStringMap(otlpConfig.Headers))) } - if otlpConfig.Certificate != nil { - creds, err := createTLSConfig(*otlpConfig.Certificate) - if err != nil { - return nil, fmt.Errorf("could not create client tls credentials: %w", err) - } - opts = append(opts, otlploghttp.WithTLSClientConfig(creds)) + tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey) + if err != nil { + return nil, err } + opts = append(opts, otlploghttp.WithTLSClientConfig(tlsConfig)) return otlploghttp.New(ctx, opts...) } @@ -206,13 +204,11 @@ func otlpGRPCLogExporter(ctx context.Context, otlpConfig *OTLP) (sdklog.Exporter opts = append(opts, otlploggrpc.WithHeaders(toStringMap(otlpConfig.Headers))) } - if otlpConfig.Certificate != nil { - creds, err := credentials.NewClientTLSFromFile(*otlpConfig.Certificate, "") - if err != nil { - return nil, fmt.Errorf("could not create client tls credentials: %w", err) - } - opts = append(opts, otlploggrpc.WithTLSCredentials(creds)) + tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey) + if err != nil { + return nil, err } + opts = append(opts, otlploggrpc.WithTLSCredentials(credentials.NewTLS(tlsConfig))) return otlploggrpc.New(ctx, opts...) } diff --git a/config/log_test.go b/config/log_test.go index 89092e13d03..982a82c2bdf 100644 --- a/config/log_test.go +++ b/config/log_test.go @@ -255,7 +255,25 @@ func TestLogProcessor(t *testing.T) { }, }, }, - wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("credentials: failed to append certificates")), + wantErr: fmt.Errorf("could not create certificate authority chain from certificate"), + }, + { + name: "batch/otlp-grpc-bad-client-certificate", + processor: LogRecordProcessor{ + Batch: &BatchLogRecordProcessor{ + Exporter: LogRecordExporter{ + OTLP: &OTLP{ + Protocol: ptr("grpc"), + Endpoint: ptr("localhost:4317"), + Compression: ptr("gzip"), + Timeout: ptr(1000), + ClientCertificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + ClientKey: ptr(filepath.Join("testdata", "bad_cert.crt")), + }, + }, + }, + }, + wantErr: fmt.Errorf("could not use client certificate: %w", errors.New("tls: failed to find any PEM data in certificate input")), }, { name: "batch/otlp-grpc-exporter-no-scheme", @@ -350,16 +368,22 @@ func TestLogProcessor(t *testing.T) { wantProcessor: sdklog.NewBatchProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-good-ca-certificate", + name: "batch/otlp-http-exporter-with-path", processor: LogRecordProcessor{ Batch: &BatchLogRecordProcessor{ + MaxExportBatchSize: ptr(0), + ExportTimeout: ptr(0), + MaxQueueSize: ptr(0), + ScheduleDelay: ptr(0), Exporter: LogRecordExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4317"), - Compression: ptr("gzip"), + Endpoint: ptr("http://localhost:4318/path/123"), + Compression: ptr("none"), Timeout: ptr(1000), - Certificate: ptr(filepath.Join("testdata", "ca.crt")), + Headers: []NameStringValuePair{ + {Name: "test", Value: ptr("test1")}, + }, }, }, }, @@ -367,24 +391,29 @@ func TestLogProcessor(t *testing.T) { wantProcessor: sdklog.NewBatchProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-bad-ca-certificate", + name: "batch/otlp-http-exporter-no-endpoint", processor: LogRecordProcessor{ Batch: &BatchLogRecordProcessor{ + MaxExportBatchSize: ptr(0), + ExportTimeout: ptr(0), + MaxQueueSize: ptr(0), + ScheduleDelay: ptr(0), Exporter: LogRecordExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Certificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + Headers: []NameStringValuePair{ + {Name: "test", Value: ptr("test1")}, + }, }, }, }, }, - wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("failed to append certificate to the cert pool")), + wantProcessor: sdklog.NewBatchProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-exporter-with-path", + name: "batch/otlp-http-exporter-no-scheme", processor: LogRecordProcessor{ Batch: &BatchLogRecordProcessor{ MaxExportBatchSize: ptr(0), @@ -394,8 +423,8 @@ func TestLogProcessor(t *testing.T) { Exporter: LogRecordExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("http://localhost:4318/path/123"), - Compression: ptr("none"), + Endpoint: ptr("localhost:4318"), + Compression: ptr("gzip"), Timeout: ptr(1000), Headers: []NameStringValuePair{ {Name: "test", Value: ptr("test1")}, @@ -407,21 +436,16 @@ func TestLogProcessor(t *testing.T) { wantProcessor: sdklog.NewBatchProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-exporter-no-endpoint", + name: "batch/otlp-http-good-ca-certificate", processor: LogRecordProcessor{ Batch: &BatchLogRecordProcessor{ - MaxExportBatchSize: ptr(0), - ExportTimeout: ptr(0), - MaxQueueSize: ptr(0), - ScheduleDelay: ptr(0), Exporter: LogRecordExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), + Endpoint: ptr("localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Headers: []NameStringValuePair{ - {Name: "test", Value: ptr("test1")}, - }, + Certificate: ptr(filepath.Join("testdata", "ca.crt")), }, }, }, @@ -429,27 +453,39 @@ func TestLogProcessor(t *testing.T) { wantProcessor: sdklog.NewBatchProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-exporter-no-scheme", + name: "batch/otlp-http-bad-ca-certificate", processor: LogRecordProcessor{ Batch: &BatchLogRecordProcessor{ - MaxExportBatchSize: ptr(0), - ExportTimeout: ptr(0), - MaxQueueSize: ptr(0), - ScheduleDelay: ptr(0), Exporter: LogRecordExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4318"), + Endpoint: ptr("localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Headers: []NameStringValuePair{ - {Name: "test", Value: ptr("test1")}, - }, + Certificate: ptr(filepath.Join("testdata", "bad_cert.crt")), }, }, }, }, - wantProcessor: sdklog.NewBatchProcessor(otlpHTTPExporter), + wantErr: fmt.Errorf("could not create certificate authority chain from certificate"), + }, + { + name: "batch/otlp-http-bad-client-certificate", + processor: LogRecordProcessor{ + Batch: &BatchLogRecordProcessor{ + Exporter: LogRecordExporter{ + OTLP: &OTLP{ + Protocol: ptr("http/protobuf"), + Endpoint: ptr("localhost:4317"), + Compression: ptr("gzip"), + Timeout: ptr(1000), + ClientCertificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + ClientKey: ptr(filepath.Join("testdata", "bad_cert.crt")), + }, + }, + }, + }, + wantErr: fmt.Errorf("could not use client certificate: %w", errors.New("tls: failed to find any PEM data in certificate input")), }, { name: "batch/otlp-http-invalid-protocol", diff --git a/config/metric.go b/config/metric.go index 5bd7bffe4f6..f0a4ea10699 100644 --- a/config/metric.go +++ b/config/metric.go @@ -182,13 +182,11 @@ func otlpHTTPMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet } } - if otlpConfig.Certificate != nil { - creds, err := createTLSConfig(*otlpConfig.Certificate) - if err != nil { - return nil, fmt.Errorf("could not create client tls credentials: %w", err) - } - opts = append(opts, otlpmetrichttp.WithTLSClientConfig(creds)) + tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey) + if err != nil { + return nil, err } + opts = append(opts, otlpmetrichttp.WithTLSClientConfig(tlsConfig)) return otlpmetrichttp.New(ctx, opts...) } @@ -245,13 +243,11 @@ func otlpGRPCMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet } } - if otlpConfig.Certificate != nil { - creds, err := credentials.NewClientTLSFromFile(*otlpConfig.Certificate, "") - if err != nil { - return nil, fmt.Errorf("could not create client tls credentials: %w", err) - } - opts = append(opts, otlpmetricgrpc.WithTLSCredentials(creds)) + tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey) + if err != nil { + return nil, err } + opts = append(opts, otlpmetricgrpc.WithTLSCredentials(credentials.NewTLS(tlsConfig))) return otlpmetricgrpc.New(ctx, opts...) } diff --git a/config/metric_test.go b/config/metric_test.go index 00b663a58ea..60685f77219 100644 --- a/config/metric_test.go +++ b/config/metric_test.go @@ -248,7 +248,25 @@ func TestReader(t *testing.T) { }, }, }, - wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("credentials: failed to append certificates")), + wantErr: errors.New("could not create certificate authority chain from certificate"), + }, + { + name: "periodic/otlp-grpc-bad-client-certificate", + reader: MetricReader{ + Periodic: &PeriodicMetricReader{ + Exporter: PushMetricExporter{ + OTLP: &OTLPMetric{ + Protocol: ptr("grpc"), + Endpoint: ptr("localhost:4317"), + Compression: ptr("gzip"), + Timeout: ptr(1000), + ClientCertificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + ClientKey: ptr(filepath.Join("testdata", "bad_cert.crt")), + }, + }, + }, + }, + wantErr: fmt.Errorf("could not use client certificate: %w", errors.New("tls: failed to find any PEM data in certificate input")), }, { name: "periodic/otlp-grpc-exporter-no-endpoint", @@ -444,16 +462,18 @@ func TestReader(t *testing.T) { wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), }, { - name: "periodic/otlp-http-good-ca-certificate", + name: "periodic/otlp-http-exporter-with-path", reader: MetricReader{ Periodic: &PeriodicMetricReader{ Exporter: PushMetricExporter{ OTLP: &OTLPMetric{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("https://localhost:4317"), + Endpoint: ptr("http://localhost:4318/path/123"), Compression: ptr("gzip"), Timeout: ptr(1000), - Certificate: ptr(filepath.Join("testdata", "ca.crt")), + Headers: []NameStringValuePair{ + {Name: "test", Value: ptr("test1")}, + }, }, }, }, @@ -461,30 +481,31 @@ func TestReader(t *testing.T) { wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), }, { - name: "periodic/otlp-http-bad-ca-certificate", + name: "periodic/otlp-http-exporter-no-endpoint", reader: MetricReader{ Periodic: &PeriodicMetricReader{ Exporter: PushMetricExporter{ OTLP: &OTLPMetric{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("https://localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Certificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + Headers: []NameStringValuePair{ + {Name: "test", Value: ptr("test1")}, + }, }, }, }, }, - wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("failed to append certificate to the cert pool")), + wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), }, { - name: "periodic/otlp-http-exporter-with-path", + name: "periodic/otlp-http-exporter-no-scheme", reader: MetricReader{ Periodic: &PeriodicMetricReader{ Exporter: PushMetricExporter{ OTLP: &OTLPMetric{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("http://localhost:4318/path/123"), + Endpoint: ptr("localhost:4318"), Compression: ptr("gzip"), Timeout: ptr(1000), Headers: []NameStringValuePair{ @@ -497,17 +518,16 @@ func TestReader(t *testing.T) { wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), }, { - name: "periodic/otlp-http-exporter-no-endpoint", + name: "periodic/otlp-http-good-ca-certificate", reader: MetricReader{ Periodic: &PeriodicMetricReader{ Exporter: PushMetricExporter{ OTLP: &OTLPMetric{ Protocol: ptr("http/protobuf"), + Endpoint: ptr("https://localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Headers: []NameStringValuePair{ - {Name: "test", Value: ptr("test1")}, - }, + Certificate: ptr(filepath.Join("testdata", "ca.crt")), }, }, }, @@ -515,23 +535,39 @@ func TestReader(t *testing.T) { wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), }, { - name: "periodic/otlp-http-exporter-no-scheme", + name: "periodic/otlp-http-bad-ca-certificate", reader: MetricReader{ Periodic: &PeriodicMetricReader{ Exporter: PushMetricExporter{ OTLP: &OTLPMetric{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4318"), + Endpoint: ptr("https://localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Headers: []NameStringValuePair{ - {Name: "test", Value: ptr("test1")}, - }, + Certificate: ptr(filepath.Join("testdata", "bad_cert.crt")), }, }, }, }, - wantReader: sdkmetric.NewPeriodicReader(otlpHTTPExporter), + wantErr: errors.New("could not create certificate authority chain from certificate"), + }, + { + name: "periodic/otlp-http-bad-client-certificate", + reader: MetricReader{ + Periodic: &PeriodicMetricReader{ + Exporter: PushMetricExporter{ + OTLP: &OTLPMetric{ + Protocol: ptr("http/protobuf"), + Endpoint: ptr("localhost:4317"), + Compression: ptr("gzip"), + Timeout: ptr(1000), + ClientCertificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + ClientKey: ptr(filepath.Join("testdata", "bad_cert.crt")), + }, + }, + }, + }, + wantErr: fmt.Errorf("could not use client certificate: %w", errors.New("tls: failed to find any PEM data in certificate input")), }, { name: "periodic/otlp-http-invalid-endpoint", diff --git a/config/trace.go b/config/trace.go index 158002051f5..d57fbe86de4 100644 --- a/config/trace.go +++ b/config/trace.go @@ -129,13 +129,11 @@ func otlpGRPCSpanExporter(ctx context.Context, otlpConfig *OTLP) (sdktrace.SpanE opts = append(opts, otlptracegrpc.WithHeaders(toStringMap(otlpConfig.Headers))) } - if otlpConfig.Certificate != nil { - creds, err := credentials.NewClientTLSFromFile(*otlpConfig.Certificate, "") - if err != nil { - return nil, fmt.Errorf("could not create client tls credentials: %w", err) - } - opts = append(opts, otlptracegrpc.WithTLSCredentials(creds)) + tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey) + if err != nil { + return nil, err } + opts = append(opts, otlptracegrpc.WithTLSCredentials(credentials.NewTLS(tlsConfig))) return otlptracegrpc.New(ctx, opts...) } @@ -174,13 +172,11 @@ func otlpHTTPSpanExporter(ctx context.Context, otlpConfig *OTLP) (sdktrace.SpanE opts = append(opts, otlptracehttp.WithHeaders(toStringMap(otlpConfig.Headers))) } - if otlpConfig.Certificate != nil { - creds, err := createTLSConfig(*otlpConfig.Certificate) - if err != nil { - return nil, fmt.Errorf("could not create client tls credentials: %w", err) - } - opts = append(opts, otlptracehttp.WithTLSClientConfig(creds)) + tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey) + if err != nil { + return nil, err } + opts = append(opts, otlptracehttp.WithTLSClientConfig(tlsConfig)) return otlptracehttp.New(ctx, opts...) } diff --git a/config/trace_test.go b/config/trace_test.go index 32f6b4c70b5..e63ef0fc105 100644 --- a/config/trace_test.go +++ b/config/trace_test.go @@ -295,7 +295,25 @@ func TestSpanProcessor(t *testing.T) { }, }, }, - wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("credentials: failed to append certificates")), + wantErr: errors.New("could not create certificate authority chain from certificate"), + }, + { + name: "batch/otlp-grpc-bad-client-certificate", + processor: SpanProcessor{ + Batch: &BatchSpanProcessor{ + Exporter: SpanExporter{ + OTLP: &OTLP{ + Protocol: ptr("grpc"), + Endpoint: ptr("localhost:4317"), + Compression: ptr("gzip"), + Timeout: ptr(1000), + ClientCertificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + ClientKey: ptr(filepath.Join("testdata", "bad_cert.crt")), + }, + }, + }, + }, + wantErr: fmt.Errorf("could not use client certificate: %w", errors.New("tls: failed to find any PEM data in certificate input")), }, { name: "batch/otlp-grpc-exporter-no-scheme", @@ -390,16 +408,22 @@ func TestSpanProcessor(t *testing.T) { wantProcessor: sdktrace.NewBatchSpanProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-good-ca-certificate", + name: "batch/otlp-http-exporter-with-path", processor: SpanProcessor{ Batch: &BatchSpanProcessor{ + MaxExportBatchSize: ptr(0), + ExportTimeout: ptr(0), + MaxQueueSize: ptr(0), + ScheduleDelay: ptr(0), Exporter: SpanExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4317"), - Compression: ptr("gzip"), + Endpoint: ptr("http://localhost:4318/path/123"), + Compression: ptr("none"), Timeout: ptr(1000), - Certificate: ptr(filepath.Join("testdata", "ca.crt")), + Headers: []NameStringValuePair{ + {Name: "test", Value: ptr("test1")}, + }, }, }, }, @@ -407,24 +431,29 @@ func TestSpanProcessor(t *testing.T) { wantProcessor: sdktrace.NewBatchSpanProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-bad-ca-certificate", + name: "batch/otlp-http-exporter-no-endpoint", processor: SpanProcessor{ Batch: &BatchSpanProcessor{ + MaxExportBatchSize: ptr(0), + ExportTimeout: ptr(0), + MaxQueueSize: ptr(0), + ScheduleDelay: ptr(0), Exporter: SpanExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Certificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + Headers: []NameStringValuePair{ + {Name: "test", Value: ptr("test1")}, + }, }, }, }, }, - wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("failed to append certificate to the cert pool")), + wantProcessor: sdktrace.NewBatchSpanProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-exporter-with-path", + name: "batch/otlp-http-exporter-no-scheme", processor: SpanProcessor{ Batch: &BatchSpanProcessor{ MaxExportBatchSize: ptr(0), @@ -434,8 +463,8 @@ func TestSpanProcessor(t *testing.T) { Exporter: SpanExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("http://localhost:4318/path/123"), - Compression: ptr("none"), + Endpoint: ptr("localhost:4318"), + Compression: ptr("gzip"), Timeout: ptr(1000), Headers: []NameStringValuePair{ {Name: "test", Value: ptr("test1")}, @@ -447,21 +476,16 @@ func TestSpanProcessor(t *testing.T) { wantProcessor: sdktrace.NewBatchSpanProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-exporter-no-endpoint", + name: "batch/otlp-http-good-ca-certificate", processor: SpanProcessor{ Batch: &BatchSpanProcessor{ - MaxExportBatchSize: ptr(0), - ExportTimeout: ptr(0), - MaxQueueSize: ptr(0), - ScheduleDelay: ptr(0), Exporter: SpanExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), + Endpoint: ptr("localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Headers: []NameStringValuePair{ - {Name: "test", Value: ptr("test1")}, - }, + Certificate: ptr(filepath.Join("testdata", "ca.crt")), }, }, }, @@ -469,27 +493,39 @@ func TestSpanProcessor(t *testing.T) { wantProcessor: sdktrace.NewBatchSpanProcessor(otlpHTTPExporter), }, { - name: "batch/otlp-http-exporter-no-scheme", + name: "batch/otlp-http-bad-ca-certificate", processor: SpanProcessor{ Batch: &BatchSpanProcessor{ - MaxExportBatchSize: ptr(0), - ExportTimeout: ptr(0), - MaxQueueSize: ptr(0), - ScheduleDelay: ptr(0), Exporter: SpanExporter{ OTLP: &OTLP{ Protocol: ptr("http/protobuf"), - Endpoint: ptr("localhost:4318"), + Endpoint: ptr("localhost:4317"), Compression: ptr("gzip"), Timeout: ptr(1000), - Headers: []NameStringValuePair{ - {Name: "test", Value: ptr("test1")}, - }, + Certificate: ptr(filepath.Join("testdata", "bad_cert.crt")), }, }, }, }, - wantProcessor: sdktrace.NewBatchSpanProcessor(otlpHTTPExporter), + wantErr: errors.New("could not create certificate authority chain from certificate"), + }, + { + name: "batch/otlp-http-bad-client-certificate", + processor: SpanProcessor{ + Batch: &BatchSpanProcessor{ + Exporter: SpanExporter{ + OTLP: &OTLP{ + Protocol: ptr("http/protobuf"), + Endpoint: ptr("localhost:4317"), + Compression: ptr("gzip"), + Timeout: ptr(1000), + ClientCertificate: ptr(filepath.Join("testdata", "bad_cert.crt")), + ClientKey: ptr(filepath.Join("testdata", "bad_cert.crt")), + }, + }, + }, + }, + wantErr: fmt.Errorf("could not use client certificate: %w", errors.New("tls: failed to find any PEM data in certificate input")), }, { name: "batch/otlp-http-invalid-endpoint",