Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions otelconf/internal/tls/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

// Package tls provides functionality to translate configuration options into tls.Config.
package tls // import "go.opentelemetry.io/contrib/otelconf/internal/tls"

import (
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"os"
)

// CreateConfig creates a tls.Config from certificate files.
func CreateConfig(caCertFile, clientCertFile, 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
}
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 tlsConfig, nil
}
72 changes: 72 additions & 0 deletions otelconf/internal/tls/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package tls

import (
"crypto/tls"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func TestCreateConfig(t *testing.T) {
tests := []struct {
name string
caCertFile *string
clientCertFile *string
clientKeyFile *string
wantErrContains string
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"),
wantErrContains: "open nowhere.crt:",
},
{
name: "nonexistent-clientcert-file",
clientCertFile: ptr("nowhere.crt"),
clientKeyFile: ptr("nowhere.crt"),
wantErrContains: "could not use client certificate: open nowhere.crt:",
},
{
name: "bad-cacert-file",
caCertFile: ptr(filepath.Join("..", "..", "testdata", "bad_cert.crt")),
wantErrContains: "could not create certificate authority chain from certificate",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := CreateConfig(tt.caCertFile, tt.clientCertFile, tt.clientKeyFile)

if tt.wantErrContains != "" {
require.Contains(t, err.Error(), tt.wantErrContains)
} else {
require.NoError(t, err)
tt.want(got, t)
}
})
}
}

func ptr[T any](v T) *T {
return &v
}
30 changes: 0 additions & 30 deletions otelconf/v0.3.0/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ package otelconf // import "go.opentelemetry.io/contrib/otelconf/v0.3.0"

import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"fmt"
"os"

"go.opentelemetry.io/otel/baggage"
"go.opentelemetry.io/otel/log"
Expand Down Expand Up @@ -195,33 +192,6 @@ func ParseYAML(file []byte) (*OpenTelemetryConfiguration, error) {
return &cfg, nil
}

// createTLSConfig creates a tls.Config from certificate files.
func createTLSConfig(caCertFile, clientCertFile, 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
}
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 tlsConfig, nil
}

// createHeadersConfig combines the two header config fields. Headers take precedence over headersList.
func createHeadersConfig(headers []NameStringValuePair, headersList *string) (map[string]string, error) {
result := make(map[string]string)
Expand Down
57 changes: 0 additions & 57 deletions otelconf/v0.3.0/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package otelconf

import (
"crypto/tls"
"encoding/json"
"errors"
"os"
Expand Down Expand Up @@ -610,62 +609,6 @@ func TestSerializeJSON(t *testing.T) {
}
}

func TestCreateTLSConfig(t *testing.T) {
tests := []struct {
name string
caCertFile *string
clientCertFile *string
clientKeyFile *string
wantErrContains string
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"),
wantErrContains: "open nowhere.crt:",
},
{
name: "nonexistent-clientcert-file",
clientCertFile: ptr("nowhere.crt"),
clientKeyFile: ptr("nowhere.crt"),
wantErrContains: "could not use client certificate: open nowhere.crt:",
},
{
name: "bad-cacert-file",
caCertFile: ptr(filepath.Join("..", "testdata", "bad_cert.crt")),
wantErrContains: "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.wantErrContains != "" {
require.Contains(t, err.Error(), tt.wantErrContains)
} else {
require.NoError(t, err)
tt.want(got, t)
}
})
}
}

func TestCreateHeadersConfig(t *testing.T) {
tests := []struct {
name string
Expand Down
6 changes: 4 additions & 2 deletions otelconf/v0.3.0/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
sdklog "go.opentelemetry.io/otel/sdk/log"
"go.opentelemetry.io/otel/sdk/resource"
"google.golang.org/grpc/credentials"

"go.opentelemetry.io/contrib/otelconf/internal/tls"
)

func loggerProvider(cfg configOptions, res *resource.Resource) (log.LoggerProvider, shutdownFunc, error) {
Expand Down Expand Up @@ -158,7 +160,7 @@ func otlpHTTPLogExporter(ctx context.Context, otlpConfig *OTLP) (sdklog.Exporter
opts = append(opts, otlploghttp.WithHeaders(headersConfig))
}

tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
tlsConfig, err := tls.CreateConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -211,7 +213,7 @@ func otlpGRPCLogExporter(ctx context.Context, otlpConfig *OTLP) (sdklog.Exporter
}

if otlpConfig.Certificate != nil || otlpConfig.ClientCertificate != nil || otlpConfig.ClientKey != nil {
tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
tlsConfig, err := tls.CreateConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
if err != nil {
return nil, err
}
Expand Down
6 changes: 4 additions & 2 deletions otelconf/v0.3.0/metric.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import (
"go.opentelemetry.io/otel/sdk/metric/metricdata"
"go.opentelemetry.io/otel/sdk/resource"
"google.golang.org/grpc/credentials"

"go.opentelemetry.io/contrib/otelconf/internal/tls"
)

var zeroScope instrumentation.Scope
Expand Down Expand Up @@ -184,7 +186,7 @@ func otlpHTTPMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
}
}

tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
tlsConfig, err := tls.CreateConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -250,7 +252,7 @@ func otlpGRPCMetricExporter(ctx context.Context, otlpConfig *OTLPMetric) (sdkmet
}

if otlpConfig.Certificate != nil || otlpConfig.ClientCertificate != nil || otlpConfig.ClientKey != nil {
tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
tlsConfig, err := tls.CreateConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
if err != nil {
return nil, err
}
Expand Down
6 changes: 4 additions & 2 deletions otelconf/v0.3.0/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"go.opentelemetry.io/otel/trace"
"go.opentelemetry.io/otel/trace/noop"
"google.golang.org/grpc/credentials"

"go.opentelemetry.io/contrib/otelconf/internal/tls"
)

var errInvalidSamplerConfiguration = errors.New("invalid sampler configuration")
Expand Down Expand Up @@ -214,7 +216,7 @@ func otlpGRPCSpanExporter(ctx context.Context, otlpConfig *OTLP) (sdktrace.SpanE
}

if otlpConfig.Certificate != nil || otlpConfig.ClientCertificate != nil || otlpConfig.ClientKey != nil {
tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
tlsConfig, err := tls.CreateConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -262,7 +264,7 @@ func otlpHTTPSpanExporter(ctx context.Context, otlpConfig *OTLP) (sdktrace.SpanE
opts = append(opts, otlptracehttp.WithHeaders(headersConfig))
}

tlsConfig, err := createTLSConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
tlsConfig, err := tls.CreateConfig(otlpConfig.Certificate, otlpConfig.ClientCertificate, otlpConfig.ClientKey)
if err != nil {
return nil, err
}
Expand Down