diff --git a/api/cloudcontroller/wrapper/b3_trace_request.go b/api/cloudcontroller/wrapper/b3_trace_request.go new file mode 100644 index 00000000000..678e6f7fddd --- /dev/null +++ b/api/cloudcontroller/wrapper/b3_trace_request.go @@ -0,0 +1,39 @@ +package wrapper + +import ( + "code.cloudfoundry.org/cli/api/cloudcontroller" +) + +// TODO +// 1. do not overwrite headers if explicitly set +// 2. headers should go on other clients (uaa/routing) as well (with same value) +// 3. tests +// 4. what to set span to? + +// TraceHeaderRequest is a wrapper that adds b3 trace headers to requests. +type TraceHeaderRequest struct { + b3trace string + b3span string + connection cloudcontroller.Connection +} + +// NewTraceHeaderRequest returns a pointer to a TraceHeaderRequest wrapper. +func NewTraceHeaderRequest(trace, span string) *TraceHeaderRequest { + return &TraceHeaderRequest{ + b3trace: trace, + b3span: span, + } +} + +// Add tracing headers +func (t *TraceHeaderRequest) Make(request *cloudcontroller.Request, passedResponse *cloudcontroller.Response) error { + request.Header.Add("X-B3-Traceid", t.b3trace) + request.Header.Add("X-B3-Spanid", t.b3span) + return t.connection.Make(request, passedResponse) +} + +// Wrap sets the connection in the TraceHeaderRequest and returns itself. +func (t *TraceHeaderRequest) Wrap(innerconnection cloudcontroller.Connection) cloudcontroller.Connection { + t.connection = innerconnection + return t +} diff --git a/command/v7/shared/new_clients.go b/command/v7/shared/new_clients.go index 4486bd8ffab..490dc02a15a 100644 --- a/command/v7/shared/new_clients.go +++ b/command/v7/shared/new_clients.go @@ -1,6 +1,9 @@ package shared import ( + "crypto/rand" + "encoding/hex" + "code.cloudfoundry.org/cli/actor/v7action" "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3" ccWrapper "code.cloudfoundry.org/cli/api/cloudcontroller/wrapper" @@ -46,6 +49,7 @@ func NewWrappedCloudControllerClient(config command.Config, ui command.UI, extra ccWrappers = append(ccWrappers, ccWrapper.NewRequestLogger(ui.RequestLoggerFileWriter(location))) } + ccWrappers = append(ccWrappers, ccWrapper.NewTraceHeaderRequest(generateB3TraceID(), generateB3TraceID())) ccWrappers = append(ccWrappers, extraWrappers...) ccWrappers = append(ccWrappers, ccWrapper.NewRetryRequest(config.RequestRetryCount())) @@ -153,3 +157,12 @@ func connectToCF(config command.Config, ui command.UI, ccClient *ccv3.Client, mi return ccClient, nil } + +func generateB3TraceID() string { + traceIDBytes := make([]byte, 16) + if _, err := rand.Read(traceIDBytes); err != nil { + panic(err) + } + + return hex.EncodeToString(traceIDBytes) +}