diff --git a/api/cloudcontroller/wrapper/trace_request.go b/api/cloudcontroller/wrapper/trace_request.go index 87d3298dae..73f6fe47ba 100644 --- a/api/cloudcontroller/wrapper/trace_request.go +++ b/api/cloudcontroller/wrapper/trace_request.go @@ -12,9 +12,9 @@ type CCTraceHeaderRequest struct { } // NewCCTraceHeaderRequest returns a pointer to a CCTraceHeaderRequest wrapper. -func NewCCTraceHeaderRequest(trace, span string) *CCTraceHeaderRequest { +func NewCCTraceHeaderRequest(trace string) *CCTraceHeaderRequest { return &CCTraceHeaderRequest{ - headers: shared.NewTraceHeaders(trace, span), + headers: shared.NewTraceHeaders(trace), } } diff --git a/api/cloudcontroller/wrapper/trace_request_test.go b/api/cloudcontroller/wrapper/trace_request_test.go index b4719c7b0f..e7a1c5b3b4 100644 --- a/api/cloudcontroller/wrapper/trace_request_test.go +++ b/api/cloudcontroller/wrapper/trace_request_test.go @@ -23,16 +23,14 @@ var _ = Describe("CCTraceHeaderRequest", func() { makeErr error traceHeader string - spanHeader string ) BeforeEach(func() { fakeConnection = new(cloudcontrollerfakes.FakeConnection) traceHeader = "trace-id" - spanHeader = "span-id" - wrapper = NewCCTraceHeaderRequest(traceHeader, spanHeader).Wrap(fakeConnection) + wrapper = NewCCTraceHeaderRequest(traceHeader).Wrap(fakeConnection) body := bytes.NewReader([]byte("foo")) @@ -54,7 +52,7 @@ var _ = Describe("CCTraceHeaderRequest", func() { It("Adds the request headers", func() { Expect(makeErr).NotTo(HaveOccurred()) Expect(request.Header.Get("X-B3-TraceId")).To(Equal(traceHeader)) - Expect(request.Header.Get("X-B3-SpanId")).To(Equal(spanHeader)) + Expect(request.Header.Get("X-B3-SpanId")).ToNot(BeEmpty()) }) It("Calls the inner connection", func() { diff --git a/api/router/wrapper/trace_request.go b/api/router/wrapper/trace_request.go index 724cb6ee3a..a96a1ce2ee 100644 --- a/api/router/wrapper/trace_request.go +++ b/api/router/wrapper/trace_request.go @@ -12,9 +12,9 @@ type RoutingTraceHeaderRequest struct { } // NewRoutingTraceHeaderRequest returns a pointer to a RoutingTraceHeaderRequest wrapper. -func NewRoutingTraceHeaderRequest(trace, span string) *RoutingTraceHeaderRequest { +func NewRoutingTraceHeaderRequest(trace string) *RoutingTraceHeaderRequest { return &RoutingTraceHeaderRequest{ - headers: shared.NewTraceHeaders(trace, span), + headers: shared.NewTraceHeaders(trace), } } diff --git a/api/router/wrapper/trace_request_test.go b/api/router/wrapper/trace_request_test.go index fd4a1bd36e..91a420f38e 100644 --- a/api/router/wrapper/trace_request_test.go +++ b/api/router/wrapper/trace_request_test.go @@ -23,16 +23,13 @@ var _ = Describe("CCTraceHeaderRequest", func() { makeErr error traceHeader string - spanHeader string ) BeforeEach(func() { fakeConnection = new(routerfakes.FakeConnection) traceHeader = "trace-id" - spanHeader = "span-id" - - wrapper = NewRoutingTraceHeaderRequest(traceHeader, spanHeader).Wrap(fakeConnection) + wrapper = NewRoutingTraceHeaderRequest(traceHeader).Wrap(fakeConnection) body := bytes.NewReader([]byte("foo")) @@ -54,7 +51,7 @@ var _ = Describe("CCTraceHeaderRequest", func() { It("Adds the request headers", func() { Expect(makeErr).NotTo(HaveOccurred()) Expect(request.Header.Get("X-B3-TraceId")).To(Equal(traceHeader)) - Expect(request.Header.Get("X-B3-SpanId")).To(Equal(spanHeader)) + Expect(request.Header.Get("X-B3-SpanId")).ToNot(BeEmpty()) }) It("Calls the inner connection", func() { diff --git a/api/shared/trace_headers.go b/api/shared/trace_headers.go index 1aec94d62f..e913b5c64c 100644 --- a/api/shared/trace_headers.go +++ b/api/shared/trace_headers.go @@ -2,6 +2,8 @@ package shared import ( "net/http" + + "code.cloudfoundry.org/cli/util/trace" ) const ( @@ -12,14 +14,12 @@ const ( // TraceHeaders sets b3 trace headers to requests. type TraceHeaders struct { b3trace string - b3span string } // NewTraceHeaders returns a pointer to a TraceHeaderRequest. -func NewTraceHeaders(trace, span string) *TraceHeaders { +func NewTraceHeaders(trace string) *TraceHeaders { return &TraceHeaders{ b3trace: trace, - b3span: span, } } @@ -30,6 +30,8 @@ func (t *TraceHeaders) SetHeaders(request *http.Request) { request.Header.Add(B3TraceIDHeader, t.b3trace) } if request.Header.Get(B3SpanIDHeader) == "" { - request.Header.Add(B3SpanIDHeader, t.b3span) + request.Header.Add(B3SpanIDHeader, trace.GenerateRandomTraceID(16)) } + + // request.Header.Add(("B3", request.Header.Get(B3TraceIDHeader)+request.Header.Get(B3SpanIDHeader))) } diff --git a/api/shared/trace_headers_test.go b/api/shared/trace_headers_test.go index c5efe888b0..660dde0f30 100644 --- a/api/shared/trace_headers_test.go +++ b/api/shared/trace_headers_test.go @@ -13,7 +13,7 @@ var _ = Describe("B3 Trace Headers", func() { Describe("SetHeaders", func() { Context("when there are already headers set", func() { It("does not add the headers", func() { - traceHeaders := NewTraceHeaders("new_trace_id", "new_span_id") + traceHeaders := NewTraceHeaders("new_trace_id") request := &http.Request{ Header: http.Header{}, } @@ -28,14 +28,14 @@ var _ = Describe("B3 Trace Headers", func() { Context("when there are no headers set", func() { It("adds the headers", func() { - traceHeaders := NewTraceHeaders("new_trace_id", "new_span_id") + traceHeaders := NewTraceHeaders("new_trace_id") request := &http.Request{ Header: http.Header{}, } traceHeaders.SetHeaders(request) Expect(request.Header.Get("X-B3-TraceId")).To(Equal("new_trace_id")) - Expect(request.Header.Get("X-B3-SpanId")).To(Equal("new_span_id")) + Expect(request.Header.Get("X-B3-SpanId")).ToNot(BeEmpty()) }) }) }) diff --git a/api/uaa/wrapper/trace_request.go b/api/uaa/wrapper/trace_request.go index 635812ed82..dedebf6e75 100644 --- a/api/uaa/wrapper/trace_request.go +++ b/api/uaa/wrapper/trace_request.go @@ -14,9 +14,9 @@ type UAATraceHeaderRequest struct { } // NewUAATraceHeaderRequest returns a pointer to a UAATraceHeaderRequest wrapper. -func NewUAATraceHeaderRequest(trace, span string) *UAATraceHeaderRequest { +func NewUAATraceHeaderRequest(trace string) *UAATraceHeaderRequest { return &UAATraceHeaderRequest{ - headers: shared.NewTraceHeaders(trace, span), + headers: shared.NewTraceHeaders(trace), } } diff --git a/api/uaa/wrapper/trace_request_test.go b/api/uaa/wrapper/trace_request_test.go index 9f9aae3910..fc97879290 100644 --- a/api/uaa/wrapper/trace_request_test.go +++ b/api/uaa/wrapper/trace_request_test.go @@ -23,16 +23,14 @@ var _ = Describe("CCTraceHeaderRequest", func() { makeErr error traceHeader string - spanHeader string ) BeforeEach(func() { fakeConnection = new(uaafakes.FakeConnection) traceHeader = "trace-id" - spanHeader = "span-id" - wrapper = NewUAATraceHeaderRequest(traceHeader, spanHeader).Wrap(fakeConnection) + wrapper = NewUAATraceHeaderRequest(traceHeader).Wrap(fakeConnection) body := bytes.NewReader([]byte("foo")) @@ -54,7 +52,7 @@ var _ = Describe("CCTraceHeaderRequest", func() { It("Adds the request headers", func() { Expect(makeErr).NotTo(HaveOccurred()) Expect(request.Header.Get("X-B3-TraceId")).To(Equal(traceHeader)) - Expect(request.Header.Get("X-B3-SpanId")).To(Equal(spanHeader)) + Expect(request.Header.Get("X-B3-SpanId")).ToNot(BeEmpty()) }) It("Calls the inner connection", func() { diff --git a/command/config.go b/command/config.go index 84e7abdb8f..bde3b4a754 100644 --- a/command/config.go +++ b/command/config.go @@ -16,7 +16,6 @@ type Config interface { AuthorizationEndpoint() string APIVersion() string B3TraceID() string - B3SpanID() string BinaryName() string BinaryVersion() string CFPassword() string diff --git a/command/v7/shared/new_clients.go b/command/v7/shared/new_clients.go index 3e6cae4efd..b1e719c592 100644 --- a/command/v7/shared/new_clients.go +++ b/command/v7/shared/new_clients.go @@ -47,7 +47,7 @@ func NewWrappedCloudControllerClient(config command.Config, ui command.UI, extra } ccWrappers = append(ccWrappers, extraWrappers...) - ccWrappers = append(ccWrappers, ccWrapper.NewCCTraceHeaderRequest(config.B3TraceID(), config.B3SpanID())) + ccWrappers = append(ccWrappers, ccWrapper.NewCCTraceHeaderRequest(config.B3TraceID())) ccWrappers = append(ccWrappers, ccWrapper.NewRetryRequest(config.RequestRetryCount())) return ccv3.NewClient(ccv3.Config{ @@ -86,7 +86,7 @@ func newWrappedUAAClient(config command.Config, ui command.UI) (*uaa.Client, err uaaAuthWrapper := uaaWrapper.NewUAAAuthentication(uaaClient, config) uaaClient.WrapConnection(uaaAuthWrapper) - uaaClient.WrapConnection(uaaWrapper.NewUAATraceHeaderRequest(config.B3TraceID(), config.B3SpanID())) + uaaClient.WrapConnection(uaaWrapper.NewUAATraceHeaderRequest(config.B3TraceID())) uaaClient.WrapConnection(uaaWrapper.NewRetryRequest(config.RequestRetryCount())) err = uaaClient.SetupResources(config.UAAEndpoint(), config.AuthorizationEndpoint()) @@ -123,6 +123,8 @@ func newWrappedRoutingClient(config command.Config, ui command.UI, uaaClient *ua authWrapper := routingWrapper.NewUAAAuthentication(uaaClient, config) routingWrappers = append(routingWrappers, authWrapper) + routingWrappers = append(routingWrappers, routingWrapper.NewRoutingTraceHeaderRequest(config.B3TraceID())) + routingConfig.Wrappers = routingWrappers routingClient := router.NewClient(routingConfig) diff --git a/go.mod b/go.mod index 04b2f59fe2..380d0cea59 100644 --- a/go.mod +++ b/go.mod @@ -24,6 +24,7 @@ require ( github.com/distribution/reference v0.6.0 github.com/fatih/color v1.18.0 github.com/google/go-querystring v1.1.0 + github.com/google/uuid v1.6.0 github.com/jessevdk/go-flags v1.6.1 github.com/lunixbochs/vtclean v1.0.0 github.com/mattn/go-colorable v0.1.13 diff --git a/util/configv3/env.go b/util/configv3/env.go index 023cfb2454..75e198cfa0 100644 --- a/util/configv3/env.go +++ b/util/configv3/env.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "code.cloudfoundry.org/cli/util/random" + "code.cloudfoundry.org/cli/util/trace" ) // EnvOverride represents all the environment variables read by the CF CLI @@ -23,7 +23,6 @@ type EnvOverride struct { CFTrace string CFUsername string CFB3TraceID string - CFB3SpanID string DockerPassword string CNBCredentials string Experimental string @@ -167,14 +166,7 @@ func (config *Config) StartupTimeout() time.Duration { func (config *Config) B3TraceID() string { if config.ENV.CFB3TraceID == "" { - config.ENV.CFB3TraceID = random.GenerateHex(32) + config.ENV.CFB3TraceID = trace.GenerateUUIDTraceID() } return config.ENV.CFB3TraceID } - -func (config *Config) B3SpanID() string { - if config.ENV.CFB3SpanID == "" { - config.ENV.CFB3SpanID = random.GenerateHex(16) - } - return config.ENV.CFB3SpanID -} diff --git a/util/configv3/load_config.go b/util/configv3/load_config.go index e421b9a6cc..228c4f3f80 100644 --- a/util/configv3/load_config.go +++ b/util/configv3/load_config.go @@ -128,7 +128,6 @@ func LoadConfig(flags ...FlagOverride) (*Config, error) { CFTrace: os.Getenv("CF_TRACE"), CFUsername: os.Getenv("CF_USERNAME"), CFB3TraceID: os.Getenv("CF_B3_TRACE_ID"), - CFB3SpanID: os.Getenv("CF_B3_SPAN_ID"), DockerPassword: os.Getenv("CF_DOCKER_PASSWORD"), CNBCredentials: os.Getenv("CNB_REGISTRY_CREDS"), Experimental: os.Getenv("CF_CLI_EXPERIMENTAL"), diff --git a/util/random/hex.go b/util/random/hex.go deleted file mode 100644 index cd46ae4939..0000000000 --- a/util/random/hex.go +++ /dev/null @@ -1,15 +0,0 @@ -package random - -import ( - "crypto/rand" - "encoding/hex" -) - -func GenerateHex(length int) string { - b := make([]byte, length/2) - if _, err := rand.Read(b); err != nil { - panic(err) - } - - return hex.EncodeToString(b) -} diff --git a/util/trace/trace.go b/util/trace/trace.go new file mode 100644 index 0000000000..3bd530f1e2 --- /dev/null +++ b/util/trace/trace.go @@ -0,0 +1,25 @@ +package trace + +import ( + "crypto/rand" + "encoding/hex" + "strings" + + "github.com/google/uuid" +) + +// GenerateUUIDTraceID returns a UUID v4 string with the dashes removed as a 32 lower-hex encoded string. +func GenerateUUIDTraceID() string { + uuidV4 := uuid.New() + return strings.ReplaceAll(uuidV4.String(), "-", "") +} + +// GenerateRandomTraceID returns a random hex string of the given length. +func GenerateRandomTraceID(length int) string { + b := make([]byte, length/2) + if _, err := rand.Read(b); err != nil { + panic(err) + } + + return hex.EncodeToString(b) +} diff --git a/util/trace/trace_suite_test.go b/util/trace/trace_suite_test.go new file mode 100644 index 0000000000..943b695d17 --- /dev/null +++ b/util/trace/trace_suite_test.go @@ -0,0 +1,13 @@ +package trace_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "testing" +) + +func TestTrace(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Trace Suite") +} diff --git a/util/trace/trace_test.go b/util/trace/trace_test.go new file mode 100644 index 0000000000..c35ad11cad --- /dev/null +++ b/util/trace/trace_test.go @@ -0,0 +1,19 @@ +package trace_test + +import ( + "code.cloudfoundry.org/cli/util/trace" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("GenerateHex", func() { + It("returns random trace id", func() { + Expect(trace.GenerateUUIDTraceID()).To(HaveLen(32)) + }) +}) + +var _ = Describe("GenerateRandomTraceID", func() { + It("returns random trace id", func() { + Expect(trace.GenerateRandomTraceID(32)).To(HaveLen(16)) + }) +})