generated from TrueCloudLab/basic
[#13] support tls over grpc for otlp_grpc exporter type
All checks were successful
DCO action / DCO (pull_request) Successful in 45s
Tests and linters / Tests (1.21) (pull_request) Successful in 1m38s
Tests and linters / Tests (1.22) (pull_request) Successful in 1m38s
Tests and linters / Tests with -race (pull_request) Successful in 1m42s
Tests and linters / Staticcheck (pull_request) Successful in 1m50s
Tests and linters / Lint (pull_request) Successful in 2m0s
All checks were successful
DCO action / DCO (pull_request) Successful in 45s
Tests and linters / Tests (1.21) (pull_request) Successful in 1m38s
Tests and linters / Tests (1.22) (pull_request) Successful in 1m38s
Tests and linters / Tests with -race (pull_request) Successful in 1m42s
Tests and linters / Staticcheck (pull_request) Successful in 1m50s
Tests and linters / Lint (pull_request) Successful in 2m0s
Signed-off-by: Aleksey Savaitan <a.savaitan@yadro.com>
This commit is contained in:
parent
6dd265d949
commit
db6cf1ea16
9 changed files with 217 additions and 1 deletions
25
testdata/testdata.go
vendored
Normal file
25
testdata/testdata.go
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
package testdata
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// basepath is the root directory of this package.
|
||||
var basepath string
|
||||
|
||||
func init() {
|
||||
_, currentFile, _, _ := runtime.Caller(0)
|
||||
basepath = filepath.Dir(currentFile)
|
||||
}
|
||||
|
||||
// Path returns the absolute path the given relative file or directory path,
|
||||
// relative to the google.golang.org/grpc/testdata directory in the user's GOPATH.
|
||||
// If rel is already absolute, it is returned unmodified.
|
||||
func Path(rel string) string {
|
||||
if filepath.IsAbs(rel) {
|
||||
return rel
|
||||
}
|
||||
|
||||
return filepath.Join(basepath, rel)
|
||||
}
|
0
testdata/tracing/setup/invalid_empty_root_ca.pem
vendored
Normal file
0
testdata/tracing/setup/invalid_empty_root_ca.pem
vendored
Normal file
1
testdata/tracing/setup/invalid_root_ca.pem
vendored
Normal file
1
testdata/tracing/setup/invalid_root_ca.pem
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
invalid content
|
12
testdata/tracing/setup/valid_google_globalsign_r4_rsa_root_ca.pem
vendored
Normal file
12
testdata/tracing/setup/valid_google_globalsign_r4_rsa_root_ca.pem
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYD
|
||||
VQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2Jh
|
||||
bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgw
|
||||
MTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9iYWxTaWduIEVDQyBSb290IENBIC0g
|
||||
UjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wWTAT
|
||||
BgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkWymOx
|
||||
uYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNV
|
||||
HQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/
|
||||
+wpu+74zyTyjhNUwCgYIKoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147
|
||||
bmF0774BxL4YSFlhgjICICadVGNA3jdgUM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm
|
||||
-----END CERTIFICATE-----
|
13
testdata/tracing/setup/valid_google_gts_r4_ecdsa_root_ca.pem
vendored
Normal file
13
testdata/tracing/setup/valid_google_gts_r4_ecdsa_root_ca.pem
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYD
|
||||
VQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIG
|
||||
A1UEAxMLR1RTIFJvb3QgUjQwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAw
|
||||
WjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2Vz
|
||||
IExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi
|
||||
AATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzuhXyi
|
||||
QHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvR
|
||||
HYqjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
|
||||
BBSATNbrdP9JNqPV2Py1PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D
|
||||
9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/Cr8deVl5c1RxYIigL9zC2L7F8AjEA8GE8
|
||||
p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh4rsUecrNIdSUtUlD
|
||||
-----END CERTIFICATE-----
|
|
@ -18,6 +18,8 @@ type Config struct {
|
|||
Exporter Exporter
|
||||
// Endpoint is collector endpoint for OTLP exporters.
|
||||
Endpoint string
|
||||
// ServerCaCertPath is path to remote server CA certificate. Use for TLS setup.
|
||||
ServerCaCertPath string
|
||||
|
||||
// Service is service name that will be used in tracing.
|
||||
// Mandatory.
|
||||
|
@ -64,6 +66,10 @@ func (c *Config) hasChange(other *Config) bool {
|
|||
return !c.serviceInfoEqual(other)
|
||||
}
|
||||
|
||||
if other.Exporter == OTLPgRPCExporter && c.ServerCaCertPath != other.ServerCaCertPath {
|
||||
return true
|
||||
}
|
||||
|
||||
return c.Exporter != other.Exporter ||
|
||||
c.Endpoint != other.Endpoint ||
|
||||
!c.serviceInfoEqual(other)
|
||||
|
|
|
@ -232,6 +232,27 @@ func TestConfig_hasChange(t *testing.T) {
|
|||
Version: "v1.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "use tls root ca certificate for grpc",
|
||||
want: true,
|
||||
config: Config{
|
||||
Enabled: true,
|
||||
Exporter: OTLPgRPCExporter,
|
||||
Endpoint: "localhost:4717",
|
||||
Service: "test",
|
||||
InstanceID: "s01",
|
||||
Version: "v1.0.0",
|
||||
},
|
||||
other: Config{
|
||||
Enabled: true,
|
||||
Exporter: OTLPgRPCExporter,
|
||||
Endpoint: "localhost:4717",
|
||||
Service: "test",
|
||||
InstanceID: "s01",
|
||||
Version: "v1.0.0",
|
||||
ServerCaCertPath: "/etc/ssl/test_ca.pem",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
@ -2,7 +2,9 @@ package tracing
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"os"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
|
@ -15,8 +17,11 @@ import (
|
|||
semconv "go.opentelemetry.io/otel/semconv/v1.17.0"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
"go.opentelemetry.io/otel/trace/noop"
|
||||
"google.golang.org/grpc/credentials"
|
||||
)
|
||||
|
||||
var ErrInvalidServerRootCaCertificate = fmt.Errorf("invalid server root ca certificate")
|
||||
|
||||
var (
|
||||
// tracingLock protects provider, done, config and tracer from concurrent update.
|
||||
// These fields change when the config is updated or the application is shutdown.
|
||||
|
@ -135,7 +140,19 @@ func getExporter(ctx context.Context, cfg *Config) (sdktrace.SpanExporter, error
|
|||
case NoOpExporter:
|
||||
return tracetest.NewNoopExporter(), nil
|
||||
case OTLPgRPCExporter:
|
||||
return otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint(cfg.Endpoint), otlptracegrpc.WithInsecure())
|
||||
securityOption := otlptracegrpc.WithInsecure()
|
||||
if cfg.ServerCaCertPath != "" {
|
||||
ca, err := os.ReadFile(cfg.ServerCaCertPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: cannot read server CA cert by path %s, %w", ErrInvalidServerRootCaCertificate, cfg.ServerCaCertPath, err)
|
||||
}
|
||||
roots := x509.NewCertPool()
|
||||
if !roots.AppendCertsFromPEM(ca) {
|
||||
return nil, fmt.Errorf("%w: failed to append certificates from server CA pem %s", ErrInvalidServerRootCaCertificate, cfg.ServerCaCertPath)
|
||||
}
|
||||
securityOption = otlptracegrpc.WithTLSCredentials(credentials.NewClientTLSFromCert(roots, ""))
|
||||
}
|
||||
return otlptracegrpc.New(ctx, otlptracegrpc.WithEndpoint(cfg.Endpoint), securityOption)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
121
tracing/setup_test.go
Normal file
121
tracing/setup_test.go
Normal file
|
@ -0,0 +1,121 @@
|
|||
package tracing_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/stretchr/testify/require"
|
||||
"testing"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/testdata"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
)
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config tracing.Config
|
||||
want bool
|
||||
expErr error
|
||||
}{
|
||||
{
|
||||
name: "setup stdout exporter",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.StdoutExporter,
|
||||
Service: "service-name",
|
||||
},
|
||||
want: true,
|
||||
expErr: nil,
|
||||
},
|
||||
{
|
||||
name: "setup noop exporter",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.NoOpExporter,
|
||||
Service: "service-name",
|
||||
},
|
||||
|
||||
want: true,
|
||||
expErr: nil,
|
||||
},
|
||||
{
|
||||
name: "setup otlp_grpc insecure exporter",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.OTLPgRPCExporter,
|
||||
Service: "service-name",
|
||||
Endpoint: "test-endpoint.com:4317",
|
||||
},
|
||||
want: true,
|
||||
expErr: nil,
|
||||
},
|
||||
{
|
||||
name: "setup otlp_grpc secure exporter with valid rsa root ca certificate",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.OTLPgRPCExporter,
|
||||
Service: "service-name",
|
||||
Endpoint: "test-endpoint.com:4317",
|
||||
ServerCaCertPath: testdata.Path("tracing/setup/valid_google_globalsign_r4_rsa_root_ca.pem"),
|
||||
},
|
||||
want: true,
|
||||
expErr: nil,
|
||||
},
|
||||
{
|
||||
name: "setup otlp_grpc secure exporter with valid ecdsa root ca certificate",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.OTLPgRPCExporter,
|
||||
Service: "service-name",
|
||||
Endpoint: "test-endpoint.com:4317",
|
||||
ServerCaCertPath: testdata.Path("tracing/setup/valid_google_gts_r4_ecdsa_root_ca.pem"),
|
||||
},
|
||||
want: true,
|
||||
expErr: nil,
|
||||
},
|
||||
{
|
||||
name: "setup otlp_grpc secure exporter with invalid empty root ca certificate",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.OTLPgRPCExporter,
|
||||
Service: "service-name",
|
||||
Endpoint: "test-endpoint.com:4317",
|
||||
ServerCaCertPath: testdata.Path("tracing/setup/invalid_empty_root_ca.pem"),
|
||||
},
|
||||
want: false,
|
||||
expErr: tracing.ErrInvalidServerRootCaCertificate,
|
||||
},
|
||||
{
|
||||
name: "setup otlp_grpc secure exporter with invalid root ca certificate",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.OTLPgRPCExporter,
|
||||
Service: "service-name",
|
||||
Endpoint: "test-endpoint.com:4317",
|
||||
ServerCaCertPath: testdata.Path("tracing/setup/invalid_root_ca.pem"),
|
||||
},
|
||||
want: false,
|
||||
expErr: tracing.ErrInvalidServerRootCaCertificate,
|
||||
},
|
||||
{
|
||||
name: "setup otlp_grpc secure exporter with invalid path root ca certificate",
|
||||
config: tracing.Config{
|
||||
Enabled: true,
|
||||
Exporter: tracing.OTLPgRPCExporter,
|
||||
Service: "service-name",
|
||||
Endpoint: "test-endpoint.com:4317",
|
||||
ServerCaCertPath: testdata.Path(""),
|
||||
},
|
||||
want: false,
|
||||
expErr: tracing.ErrInvalidServerRootCaCertificate,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := tracing.Setup(context.Background(), tt.config)
|
||||
require.ErrorIs(t, err, tt.expErr)
|
||||
if got != tt.want {
|
||||
t.Errorf("Setup config = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue