Skip to content

Commit

Permalink
Set Headers when using gRPC (#1702)
Browse files Browse the repository at this point in the history
  • Loading branch information
marctc authored Feb 26, 2025
1 parent b91e8c2 commit 2ded441
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 6 deletions.
7 changes: 7 additions & 0 deletions pkg/export/otel/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ type otlpOptions struct {
URLPath string
SkipTLSVerify bool
HTTPHeaders map[string]string
GRPCHeaders map[string]string
}

func (o *otlpOptions) AsMetricHTTP() []otlpmetrichttp.Option {
Expand Down Expand Up @@ -261,6 +262,9 @@ func (o *otlpOptions) AsMetricGRPC() []otlpmetricgrpc.Option {
if o.SkipTLSVerify {
opts = append(opts, otlpmetricgrpc.WithTLSCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})))
}
if len(o.GRPCHeaders) > 0 {
opts = append(opts, otlpmetricgrpc.WithHeaders(o.GRPCHeaders))
}
return opts
}

Expand Down Expand Up @@ -293,6 +297,9 @@ func (o *otlpOptions) AsTraceGRPC() []otlptracegrpc.Option {
if o.SkipTLSVerify {
opts = append(opts, otlptracegrpc.WithTLSCredentials(credentials.NewTLS(&tls.Config{InsecureSkipVerify: true})))
}
if len(o.GRPCHeaders) > 0 {
opts = append(opts, otlptracegrpc.WithHeaders(o.GRPCHeaders))
}
return opts
}

Expand Down
4 changes: 4 additions & 0 deletions pkg/export/otel/grafana.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,9 @@ func (cfg *GrafanaOTLP) setupOptions(opt *otlpOptions) {
opt.HTTPHeaders = map[string]string{}
}
opt.HTTPHeaders["Authorization"] = cfg.AuthHeader()
if opt.GRPCHeaders == nil {
opt.GRPCHeaders = map[string]string{}
}
opt.GRPCHeaders["Authorization"] = cfg.AuthHeader()
}
}
8 changes: 8 additions & 0 deletions pkg/export/otel/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ func TestHTTPMetricsWithGrafanaOptions(t *testing.T) {
// Basic + output of: echo -n 12345:affafafaafkd | gbase64 -w 0
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
GRPCHeaders: map[string]string{
// Basic + output of: echo -n 12345:affafafaafkd | gbase64 -w 0
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
}, &mcfg)
})
mcfg.CommonEndpoint = "https://localhost:3939"
Expand All @@ -104,6 +108,10 @@ func TestHTTPMetricsWithGrafanaOptions(t *testing.T) {
// Basic + output of: echo -n 12345:affafafaafkd | gbase64 -w 0
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
GRPCHeaders: map[string]string{
// Basic + output of: echo -n 12345:affafafaafkd | gbase64 -w 0
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
}, &mcfg)
})
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/export/otel/traces.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ func getTracesExporter(ctx context.Context, cfg TracesConfig, ctxInfo *global.Co
Insecure: opts.Insecure,
InsecureSkipVerify: cfg.InsecureSkipVerify,
},
Headers: convertHeaders(opts.GRPCHeaders),
}
set := getTraceSettings(ctxInfo, t)
return factory.CreateTraces(ctx, set, config)
Expand Down Expand Up @@ -797,7 +798,7 @@ func getHTTPTracesEndpointOptions(cfg *TracesConfig) (otlpOptions, error) {
}

func getGRPCTracesEndpointOptions(cfg *TracesConfig) (otlpOptions, error) {
opts := otlpOptions{}
opts := otlpOptions{GRPCHeaders: map[string]string{}}
log := tlog().With("transport", "grpc")
murl, _, err := parseTracesEndpoint(cfg)
if err != nil {
Expand All @@ -817,6 +818,9 @@ func getGRPCTracesEndpointOptions(cfg *TracesConfig) (otlpOptions, error) {
opts.SkipTLSVerify = true
}

cfg.Grafana.setupOptions(&opts)
maps.Copy(opts.GRPCHeaders, headersFromEnv(envHeaders))
maps.Copy(opts.GRPCHeaders, headersFromEnv(envTracesHeaders))
return opts, nil
}

Expand Down
65 changes: 60 additions & 5 deletions pkg/export/otel/traces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ func TestHTTPTracesWithGrafanaOptions(t *testing.T) {
// Basic + output of: echo -n 12345:affafafaafkd | gbase64 -w 0
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
GRPCHeaders: map[string]string{
// Basic + output of: echo -n 12345:affafafaafkd | gbase64 -w 0
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
}, &mcfg)
})
mcfg.CommonEndpoint = "https://localhost:3939"
Expand All @@ -108,6 +112,10 @@ func TestHTTPTracesWithGrafanaOptions(t *testing.T) {
// Base64 representation of 12345:affafafaafkd
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
GRPCHeaders: map[string]string{
// Base64 representation of 12345:affafafaafkd
"Authorization": "Basic MTIzNDU6YWZmYWZhZmFhZmtk",
},
}, &mcfg)
})
}
Expand Down Expand Up @@ -200,7 +208,7 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
}

t.Run("testing with two endpoints", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3232"}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3232", GRPCHeaders: map[string]string{}}, &tcfg)
})

tcfg = TracesConfig{
Expand All @@ -209,7 +217,7 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
}

t.Run("testing with only common endpoint", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3131"}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3131", GRPCHeaders: map[string]string{}}, &tcfg)
})

tcfg = TracesConfig{
Expand All @@ -218,7 +226,7 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
Instrumentations: []string{instrumentations.InstrumentationALL},
}
t.Run("testing with insecure endpoint", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3232", Insecure: true}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3232", Insecure: true, GRPCHeaders: map[string]string{}}, &tcfg)
})

tcfg = TracesConfig{
Expand All @@ -228,11 +236,58 @@ func TestGRPCTracesEndpointOptions(t *testing.T) {
}

t.Run("testing with skip TLS verification", func(t *testing.T) {
testTracesGRPOptions(t, otlpOptions{Endpoint: "localhost:3232", SkipTLSVerify: true}, &tcfg)
testTracesGRPCOptions(t, otlpOptions{Endpoint: "localhost:3232", SkipTLSVerify: true, GRPCHeaders: map[string]string{}}, &tcfg)
})
}

func testTracesGRPOptions(t *testing.T, expected otlpOptions, tcfg *TracesConfig) {
func TestGRPCTracesEndpointHeaders(t *testing.T) {
type testCase struct {
Description string
Env map[string]string
ExpectedHeaders map[string]string
Grafana GrafanaOTLP
}
for _, tc := range []testCase{
{Description: "No headers",
ExpectedHeaders: map[string]string{}},
{Description: "defining common OTLP_HEADERS",
Env: map[string]string{"OTEL_EXPORTER_OTLP_HEADERS": "Foo=Bar ==,Authorization=Base 2222=="},
ExpectedHeaders: map[string]string{"Foo": "Bar ==", "Authorization": "Base 2222=="}},
{Description: "defining common OTLP_TRACES_HEADERS",
Env: map[string]string{"OTEL_EXPORTER_OTLP_TRACES_HEADERS": "Foo=Bar ==,Authorization=Base 1234=="},
ExpectedHeaders: map[string]string{"Foo": "Bar ==", "Authorization": "Base 1234=="}},
{Description: "OTLP_TRACES_HEADERS takes precedence over OTLP_HEADERS",
Env: map[string]string{
"OTEL_EXPORTER_OTLP_HEADERS": "Foo=Bar ==,Authorization=Base 3210==",
"OTEL_EXPORTER_OTLP_TRACES_HEADERS": "Authorization=Base 1111==",
},
ExpectedHeaders: map[string]string{"Foo": "Bar ==", "Authorization": "Base 1111=="}},
} {
// mutex to avoid running testcases in parallel so we don't mess up with env vars
mt := sync.Mutex{}
t.Run(fmt.Sprint(tc.Description), func(t *testing.T) {
mt.Lock()
restore := restoreEnvAfterExecution()
defer func() {
restore()
mt.Unlock()
}()
for k, v := range tc.Env {
require.NoError(t, os.Setenv(k, v))
}

opts, err := getGRPCTracesEndpointOptions(&TracesConfig{
TracesEndpoint: "https://localhost:1234/v1/traces",
Grafana: &tc.Grafana,
Instrumentations: []string{instrumentations.InstrumentationALL},
})
require.NoError(t, err)
assert.Equal(t, tc.ExpectedHeaders, opts.GRPCHeaders)
})
}
}

func testTracesGRPCOptions(t *testing.T, expected otlpOptions, tcfg *TracesConfig) {
defer restoreEnvAfterExecution()()
opts, err := getGRPCTracesEndpointOptions(tcfg)
require.NoError(t, err)
Expand Down

0 comments on commit 2ded441

Please sign in to comment.