Skip to content

Commit 4021b15

Browse files
branczclaude
andauthored
Add support for arbitrary headers (#6080)
* Add support for arbitrary headers * proto: Update * .github: Update buf * Makefile: Update buf dependency update command * proto: Regenerate descriptor.ts after merge with main The main branch had an outdated version of descriptor.ts that was missing several fields from the latest protobuf descriptors. After merging main, regenerated the proto files to bring them back in sync with the proto definitions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent 68261fc commit 4021b15

File tree

7 files changed

+470
-74
lines changed

7 files changed

+470
-74
lines changed

.github/workflows/proto-gen.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,9 @@ jobs:
4545
steps:
4646
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
4747

48-
- uses: bufbuild/buf-action@8f4a1456a0ab6a1eb80ba68e53832e6fcfacc16c # v1.3.0
48+
- uses: bufbuild/buf-setup-action@a47c93e0b1648d5651a065437926377d060baa99 # v1.50.0
4949
with:
50-
version: 1.55.1
51-
setup_only: true
50+
version: 1.61.0
5251

5352
- name: Generate
5453
run:

.github/workflows/proto-pr.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ jobs:
4646
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
4747

4848
- uses: bufbuild/buf-setup-action@a47c93e0b1648d5651a065437926377d060baa99 # v1.50.0
49+
with:
50+
version: 1.61.0
4951

5052
- name: version
5153
run: buf --version

.github/workflows/proto-push.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ jobs:
4949
- uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
5050

5151
- uses: bufbuild/buf-setup-action@a47c93e0b1648d5651a065437926377d060baa99 # v1.50.0
52+
with:
53+
version: 1.61.0
5254

5355
- name: version
5456
run: buf --version

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ proto/generate: proto/vendor
140140

141141
.PHONY: proto/vendor
142142
proto/vendor: proto/google/pprof/profile.proto
143-
cd proto && buf mod update
143+
cd proto && buf dep update
144144

145145
proto/google/pprof/profile.proto:
146146
mkdir -p proto/google/pprof

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ Flags:
166166
--external-label=KEY=VALUE;...
167167
Label(s) to attach to all profiles in
168168
scraper-only mode.
169+
--grpc-headers=KEY=VALUE;...
170+
Additional gRPC headers to send with each
171+
request to the remote store (key=value pairs).
169172
```
170173
<!-- prettier-ignore-end -->
171174

pkg/parca/parca.go

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import (
5757
"google.golang.org/grpc"
5858
"google.golang.org/grpc/credentials"
5959
"google.golang.org/grpc/credentials/insecure"
60+
"google.golang.org/grpc/metadata"
6061
"gopkg.in/yaml.v3"
6162

6263
debuginfopb "github.com/parca-dev/parca/gen/proto/go/parca/debuginfo/v1alpha1"
@@ -125,6 +126,7 @@ type Flags struct {
125126
Insecure bool `kong:"help='Send gRPC requests via plaintext instead of TLS.'"`
126127
InsecureSkipVerify bool `kong:"help='Skip TLS certificate verification.'"`
127128
ExternalLabel map[string]string `kong:"help='Label(s) to attach to all profiles in scraper-only mode.'"`
129+
GRPCHeaders map[string]string `kong:"help='Additional gRPC headers to send with each request to the remote store (key=value pairs).'"`
128130

129131
Hidden FlagsHidden `embed:"" prefix:""`
130132
}
@@ -661,6 +663,28 @@ func Run(ctx context.Context, logger log.Logger, reg *prometheus.Registry, flags
661663
return nil
662664
}
663665

666+
// customHeadersUnaryInterceptor adds custom headers to all unary RPC calls.
667+
func customHeadersUnaryInterceptor(headers map[string]string) grpc.UnaryClientInterceptor {
668+
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
669+
// Add headers to outgoing context
670+
for key, value := range headers {
671+
ctx = metadata.AppendToOutgoingContext(ctx, key, value)
672+
}
673+
return invoker(ctx, method, req, reply, cc, opts...)
674+
}
675+
}
676+
677+
// customHeadersStreamInterceptor adds custom headers to all streaming RPC calls.
678+
func customHeadersStreamInterceptor(headers map[string]string) grpc.StreamClientInterceptor {
679+
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
680+
// Add headers to outgoing context
681+
for key, value := range headers {
682+
ctx = metadata.AppendToOutgoingContext(ctx, key, value)
683+
}
684+
return streamer(ctx, desc, cc, method, opts...)
685+
}
686+
}
687+
664688
func runForwarder(
665689
ctx context.Context,
666690
logger log.Logger,
@@ -686,17 +710,27 @@ func runForwarder(
686710

687711
propagators := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})
688712

713+
// Build interceptor chains
714+
unaryInterceptors := []grpc.UnaryClientInterceptor{
715+
metrics.UnaryClientInterceptor(),
716+
}
717+
streamInterceptors := []grpc.StreamClientInterceptor{
718+
metrics.StreamClientInterceptor(),
719+
}
720+
721+
// Add custom headers interceptor if headers are configured
722+
if len(flags.GRPCHeaders) > 0 {
723+
unaryInterceptors = append([]grpc.UnaryClientInterceptor{customHeadersUnaryInterceptor(flags.GRPCHeaders)}, unaryInterceptors...)
724+
streamInterceptors = append([]grpc.StreamClientInterceptor{customHeadersStreamInterceptor(flags.GRPCHeaders)}, streamInterceptors...)
725+
}
726+
689727
opts := []grpc.DialOption{
690728
grpc.WithStatsHandler(otelgrpc.NewServerHandler(
691729
otelgrpc.WithTracerProvider(tracer),
692730
otelgrpc.WithPropagators(propagators),
693731
)),
694-
grpc.WithChainUnaryInterceptor(
695-
metrics.UnaryClientInterceptor(),
696-
),
697-
grpc.WithChainStreamInterceptor(
698-
metrics.StreamClientInterceptor(),
699-
),
732+
grpc.WithChainUnaryInterceptor(unaryInterceptors...),
733+
grpc.WithChainStreamInterceptor(streamInterceptors...),
700734
}
701735
if flags.Insecure {
702736
opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))

0 commit comments

Comments
 (0)