Skip to content

Commit f25fd8d

Browse files
authored
system/telemetry metrics OTLP GRPC Exporter: add CA certificate support (#11633)
#### Description Adds support for CA certificates to the OTLP gRPC exporter for metrics in system/telemetry. Currently if a "Certificate" is specified in the config, it is silently ignored. #### Testing Both a positive and negative unit test was added. The good test CA certificate was copied from another unit test. I'm going to file an issue for updating all test certificates as all the ones I checked seem to expire in 2032 which is only 8 years away. #### Documentation None.
1 parent 79357e8 commit f25fd8d

File tree

6 files changed

+96
-1
lines changed

6 files changed

+96
-1
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: service
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add support for ca certificates in telemetry metrics otlp grpc exporter
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [11633]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: Before this change the Certificate value in config was silently ignored.
19+
20+
# Optional: The change log or logs in which this entry should be included.
21+
# e.g. '[user]' or '[user, api]'
22+
# Include 'user' if the change is relevant to end users.
23+
# Include 'api' if there is a change to a library API.
24+
# Default: '[user]'
25+
change_logs: []

service/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ require (
6060
go.uber.org/multierr v1.11.0
6161
go.uber.org/zap v1.27.0
6262
gonum.org/v1/gonum v0.15.1
63+
google.golang.org/grpc v1.67.1
6364
)
6465

6566
require (
@@ -120,7 +121,6 @@ require (
120121
golang.org/x/text v0.20.0 // indirect
121122
google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect
122123
google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect
123-
google.golang.org/grpc v1.67.1 // indirect
124124
google.golang.org/protobuf v1.35.2 // indirect
125125
gopkg.in/yaml.v3 v3.0.1 // indirect
126126
)

service/telemetry/internal/otelinit/config.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
sdkmetric "go.opentelemetry.io/otel/sdk/metric"
3030
"go.opentelemetry.io/otel/sdk/metric/metricdata"
3131
"go.opentelemetry.io/otel/sdk/resource"
32+
"google.golang.org/grpc/credentials"
3233

3334
semconv "go.opentelemetry.io/collector/semconv/v1.18.0"
3435
)
@@ -224,6 +225,12 @@ func initOTLPgRPCExporter(ctx context.Context, otlpConfig *config.OTLPMetric) (s
224225
opts = append(opts, otlpmetricgrpc.WithEndpoint(u.Host))
225226
if u.Scheme == "http" {
226227
opts = append(opts, otlpmetricgrpc.WithInsecure())
228+
} else if otlpConfig.Certificate != nil {
229+
creds, err := credentials.NewClientTLSFromFile(*otlpConfig.Certificate, "")
230+
if err != nil {
231+
return nil, fmt.Errorf("could not create client tls credentials: %w", err)
232+
}
233+
opts = append(opts, otlpmetricgrpc.WithTLSCredentials(creds))
227234
}
228235
}
229236

service/telemetry/internal/otelinit/config_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package otelinit
66
import (
77
"context"
88
"errors"
9+
"fmt"
910
"net/url"
11+
"path/filepath"
1012
"reflect"
1113
"sync"
1214
"testing"
@@ -527,6 +529,46 @@ func TestMetricReader(t *testing.T) {
527529
},
528530
wantErr: errors.New("unsupported temporality preference \"invalid\""),
529531
},
532+
{
533+
name: "periodic/otlp-grpc-good-ca-certificate",
534+
reader: config.MetricReader{
535+
Periodic: &config.PeriodicMetricReader{
536+
Exporter: config.MetricExporter{
537+
OTLP: &config.OTLPMetric{
538+
Protocol: "grpc/protobuf",
539+
Endpoint: "https://localhost:4317",
540+
Compression: strPtr("gzip"),
541+
Timeout: intPtr(1000),
542+
Certificate: strPtr(filepath.Join("testdata", "ca.crt")),
543+
Headers: map[string]string{
544+
"test": "test1",
545+
},
546+
},
547+
},
548+
},
549+
},
550+
wantReader: sdkmetric.NewPeriodicReader(otlpGRPCExporter),
551+
},
552+
{
553+
name: "periodic/otlp-grpc-bad-ca-certificate",
554+
reader: config.MetricReader{
555+
Periodic: &config.PeriodicMetricReader{
556+
Exporter: config.MetricExporter{
557+
OTLP: &config.OTLPMetric{
558+
Protocol: "grpc/protobuf",
559+
Endpoint: "https://localhost:4317",
560+
Compression: strPtr("gzip"),
561+
Timeout: intPtr(1000),
562+
Certificate: strPtr(filepath.Join("testdata", "bad_cert.crt")),
563+
Headers: map[string]string{
564+
"test": "test1",
565+
},
566+
},
567+
},
568+
},
569+
},
570+
wantErr: fmt.Errorf("could not create client tls credentials: %w", errors.New("credentials: failed to append certificates")),
571+
},
530572
}
531573
for _, tt := range testCases {
532574
t.Run(tt.name, func(t *testing.T) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This is intentionally not a PEM formatted cert file.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDNjCCAh4CCQC0I5IQT7eziDANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJB
3+
VTESMBAGA1UECAwJQXVzdHJhbGlhMQ8wDQYDVQQHDAZTeWRuZXkxEjAQBgNVBAoM
4+
CU15T3JnTmFtZTEVMBMGA1UEAwwMTXlDb21tb25OYW1lMB4XDTIyMDgwMzA0MTky
5+
MVoXDTMyMDczMTA0MTkyMVowXTELMAkGA1UEBhMCQVUxEjAQBgNVBAgMCUF1c3Ry
6+
YWxpYTEPMA0GA1UEBwwGU3lkbmV5MRIwEAYDVQQKDAlNeU9yZ05hbWUxFTATBgNV
7+
BAMMDE15Q29tbW9uTmFtZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
8+
AMhGP0dy3zvkdx9zI+/XVjPOWlER0OUp7Sgzidc3nLOk42+bH4ofIVNtOFVqlNKi
9+
O1bImu238VdBhd6R5IZZ1ZdIMcCeDgSJYu2X9wA3m4PKz8IdXo5ly2OHghhmCvqG
10+
WxgqDj5wPXiczQwuf1EcDMtRWbXJ6Z/XH1U68R/kRdNLkiZ2LwtjoQpis5XYckLL
11+
CrdF+AL6GeDIe0Mh9QGs26Vux+2kvaOGNUWRPE6Wt4GkqyKqmzYfR9HbflJ4xHT2
12+
I+jE1lg+jMBeom7z8Z90RE4GGcHjO+Vens/88r5EAjTnFj1Kb5gL2deSHY1m/++R
13+
Z/kRyg+zQJyw4fAzlAA4+VkCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAM3gRdTKX
14+
eGwGYVmmKqA2vTxeigQYLHml7OSopcWj2wJfxfp49HXPRuvgpQn9iubxO3Zmhd83
15+
2X1E+T0A8oy5CfxgpAhHb3lY0jm3TjKXm6m+dSODwL3uND8tX+SqR8sRTFxPvPuo
16+
pmvhdTZoRI3EzIiHLTgCuSU25JNP/vrVoKk0JvCkDYTU/WcVfj0v95DTMoWR4JGz
17+
mtBwrgD0EM2XRw5ZMc7sMPli1gqmCbCQUrDZ+rPB78WDCBILBd8Cz75qYTUp98BY
18+
akJyBckdJHAdyEQYDKa9HpmpexOO7IhSXCTEN1DEBgpZgEi/lBDRG/b0OzenUUgt
19+
LUABtWt3pNQ9HA==
20+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)