From 55735220330644395e0636e2a1411077a21c4e72 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Tue, 26 Mar 2024 09:57:05 +0100 Subject: [PATCH 01/17] feat(endpoint_info.go): try to add endpoint with no success --- pkg/diagnose/connectivity/endpoint_info.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index c90294d30cd19..1860465e846e7 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -41,14 +41,30 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { {endpoints.V1SeriesEndpoint, "POST", emptyPayload}, {endpoints.V1CheckRunsEndpoint, "POST", checkRunPayload}, {endpoints.V1IntakeEndpoint, "POST", emptyPayload}, - + {endpoints.V1SketchSeriesEndpoint, "POST", emptyPayload}, // This one does not work // This endpoint behaves differently depending on `site` when using `emptyPayload`. Do not modify `nil` here ! {endpoints.V1ValidateEndpoint, "GET", nil}, {endpoints.V1MetadataEndpoint, "POST", emptyPayload}, // v2 endpoints {endpoints.SeriesEndpoint, "POST", emptyPayload}, + {endpoints.EventsEndpoint, "POST", emptyPayload}, // This one does not work + {endpoints.ServiceChecksEndpoint, "GET", emptyPayload},// This one does not work {endpoints.SketchSeriesEndpoint, "POST", emptyPayload}, + {endpoints.HostMetadataEndpoint, "POST", emptyPayload},// This one does not work + + // Process endpoints + {endpoints.ProcessesEndpoint, "HEAD", nil}, + {endpoints.ProcessDiscoveryEndpoint, "HEAD", nil}, + {endpoints.ProcessLifecycleEndpoint, "HEAD", nil}, + {endpoints.RtProcessesEndpoint, "HEAD", nil}, + {endpoints.ContainerEndpoint, "HEAD", nil}, + {endpoints.RtContainerEndpoint, "HEAD", nil}, + {endpoints.ConnectionsEndpoint, "HEAD", nil}, + {endpoints.LegacyOrchestratorEndpoint, "HEAD", nil}, + {endpoints.OrchestratorEndpoint, "HEAD", nil}, + {endpoints.OrchestratorManifestEndpoint, "HEAD", nil}, + // Flare endpoint {transaction.Endpoint{Route: helpers.GetFlareEndpoint(cfg), Name: "flare"}, "HEAD", nil}, From 20de1927f2f4634a9cef5467c6ba3a8758b20249 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Thu, 4 Apr 2024 13:44:38 +0200 Subject: [PATCH 02/17] remove endpoint that fail during diagnose command --- pkg/diagnose/connectivity/endpoint_info.go | 29 +++++++++++----------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 1860465e846e7..557a3fb01c14e 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -41,30 +41,29 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { {endpoints.V1SeriesEndpoint, "POST", emptyPayload}, {endpoints.V1CheckRunsEndpoint, "POST", checkRunPayload}, {endpoints.V1IntakeEndpoint, "POST", emptyPayload}, - {endpoints.V1SketchSeriesEndpoint, "POST", emptyPayload}, // This one does not work + // {endpoints.V1SketchSeriesEndpoint, "POST", emptyPayload}, // This one does not work // This endpoint behaves differently depending on `site` when using `emptyPayload`. Do not modify `nil` here ! {endpoints.V1ValidateEndpoint, "GET", nil}, {endpoints.V1MetadataEndpoint, "POST", emptyPayload}, // v2 endpoints {endpoints.SeriesEndpoint, "POST", emptyPayload}, - {endpoints.EventsEndpoint, "POST", emptyPayload}, // This one does not work - {endpoints.ServiceChecksEndpoint, "GET", emptyPayload},// This one does not work + // {endpoints.EventsEndpoint, "POST", emptyPayload}, // This one does not work + // {endpoints.ServiceChecksEndpoint, "GET", emptyPayload},// This one does not work {endpoints.SketchSeriesEndpoint, "POST", emptyPayload}, - {endpoints.HostMetadataEndpoint, "POST", emptyPayload},// This one does not work + // {endpoints.HostMetadataEndpoint, "POST", emptyPayload},// This one does not work // Process endpoints - {endpoints.ProcessesEndpoint, "HEAD", nil}, - {endpoints.ProcessDiscoveryEndpoint, "HEAD", nil}, - {endpoints.ProcessLifecycleEndpoint, "HEAD", nil}, - {endpoints.RtProcessesEndpoint, "HEAD", nil}, - {endpoints.ContainerEndpoint, "HEAD", nil}, - {endpoints.RtContainerEndpoint, "HEAD", nil}, - {endpoints.ConnectionsEndpoint, "HEAD", nil}, - {endpoints.LegacyOrchestratorEndpoint, "HEAD", nil}, - {endpoints.OrchestratorEndpoint, "HEAD", nil}, - {endpoints.OrchestratorManifestEndpoint, "HEAD", nil}, - + //{endpoints.ProcessesEndpoint, "HEAD", nil}, + //{endpoints.ProcessDiscoveryEndpoint, "HEAD", nil}, + //{endpoints.ProcessLifecycleEndpoint, "HEAD", nil}, + //{endpoints.RtProcessesEndpoint, "HEAD", nil}, + //{endpoints.ContainerEndpoint, "HEAD", nil}, + //{endpoints.RtContainerEndpoint, "HEAD", nil}, + //{endpoints.ConnectionsEndpoint, "HEAD", nil}, + //{endpoints.LegacyOrchestratorEndpoint, "HEAD", nil}, + //{endpoints.OrchestratorEndpoint, "HEAD", nil}, + //{endpoints.OrchestratorManifestEndpoint, "HEAD", nil}, // Flare endpoint {transaction.Endpoint{Route: helpers.GetFlareEndpoint(cfg), Name: "flare"}, "HEAD", nil}, From 911cc345ecd78456e262be6a78411eafbee59e1b Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Fri, 5 Apr 2024 13:25:12 +0200 Subject: [PATCH 03/17] Update working endpoints in endpoints.go --- .../defaultforwarder/endpoints/endpoints.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/comp/forwarder/defaultforwarder/endpoints/endpoints.go b/comp/forwarder/defaultforwarder/endpoints/endpoints.go index 1dacd8fbacfdf..109da34906b4d 100644 --- a/comp/forwarder/defaultforwarder/endpoints/endpoints.go +++ b/comp/forwarder/defaultforwarder/endpoints/endpoints.go @@ -11,26 +11,26 @@ import "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/transac var ( // V1SeriesEndpoint is a v1 endpoint used to send series - V1SeriesEndpoint = transaction.Endpoint{Route: "/api/v1/series", Name: "series_v1"} + V1SeriesEndpoint = transaction.Endpoint{Route: "/api/v1/series", Name: "series_v1"} // works // V1CheckRunsEndpoint is a v1 endpoint used to send checks results - V1CheckRunsEndpoint = transaction.Endpoint{Route: "/api/v1/check_run", Name: "check_run_v1"} + V1CheckRunsEndpoint = transaction.Endpoint{Route: "/api/v1/check_run", Name: "check_run_v1"} // works // V1IntakeEndpoint is a v1 endpoint, used by Agent v.5, still used for metadata - V1IntakeEndpoint = transaction.Endpoint{Route: "/intake/", Name: "intake"} + V1IntakeEndpoint = transaction.Endpoint{Route: "/intake/", Name: "intake"} // works // V1SketchSeriesEndpoint is a v1 endpoint used to send sketches V1SketchSeriesEndpoint = transaction.Endpoint{Route: "/api/v1/sketches", Name: "sketches_v1"} //nolint unused for now // V1ValidateEndpoint is a v1 endpoint used to validate API keys - V1ValidateEndpoint = transaction.Endpoint{Route: "/api/v1/validate", Name: "validate_v1"} + V1ValidateEndpoint = transaction.Endpoint{Route: "/api/v1/validate", Name: "validate_v1"} // works // V1MetadataEndpoint is a v1 endpoint used for metadata (only used for inventory metadata for now) - V1MetadataEndpoint = transaction.Endpoint{Route: "/api/v1/metadata", Name: "metadata_v1"} + V1MetadataEndpoint = transaction.Endpoint{Route: "/api/v1/metadata", Name: "metadata_v1"} // works // SeriesEndpoint is the v2 endpoint used to send series - SeriesEndpoint = transaction.Endpoint{Route: "/api/v2/series", Name: "series_v2"} + SeriesEndpoint = transaction.Endpoint{Route: "/api/v2/series", Name: "series_v2"} // works // EventsEndpoint is the v2 endpoint used to send events EventsEndpoint = transaction.Endpoint{Route: "/api/v2/events", Name: "events_v2"} // ServiceChecksEndpoint is the v2 endpoint used to send service checks ServiceChecksEndpoint = transaction.Endpoint{Route: "/api/v2/service_checks", Name: "services_checks_v2"} // SketchSeriesEndpoint is the v2 endpoint used to send sketches - SketchSeriesEndpoint = transaction.Endpoint{Route: "/api/beta/sketches", Name: "sketches_v2"} + SketchSeriesEndpoint = transaction.Endpoint{Route: "/api/beta/sketches", Name: "sketches_v2"} // works // HostMetadataEndpoint is the v2 endpoint used to send host medatada HostMetadataEndpoint = transaction.Endpoint{Route: "/api/v2/host_metadata", Name: "host_metadata_v2"} From 06fc3820b9709787c21687f572c2ed4221961ec9 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 10 Apr 2024 10:00:52 +0200 Subject: [PATCH 04/17] Update endpoints in defaultforwarder/endpoints.go and add connectivity tests in diagnose/README.md --- .../defaultforwarder/endpoints/endpoints.go | 10 +++++----- pkg/diagnose/README.md | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/comp/forwarder/defaultforwarder/endpoints/endpoints.go b/comp/forwarder/defaultforwarder/endpoints/endpoints.go index 109da34906b4d..ebda2f5465e3d 100644 --- a/comp/forwarder/defaultforwarder/endpoints/endpoints.go +++ b/comp/forwarder/defaultforwarder/endpoints/endpoints.go @@ -35,15 +35,15 @@ var ( HostMetadataEndpoint = transaction.Endpoint{Route: "/api/v2/host_metadata", Name: "host_metadata_v2"} // ProcessesEndpoint is a v1 endpoint used to send processes checks - ProcessesEndpoint = transaction.Endpoint{Route: "/api/v1/collector", Name: "process"} + ProcessesEndpoint = transaction.Endpoint{Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) // ProcessDiscoveryEndpoint is a v1 endpoint used to sends process discovery checks - ProcessDiscoveryEndpoint = transaction.Endpoint{Route: "/api/v1/discovery", Name: "process_discovery"} + ProcessDiscoveryEndpoint = transaction.Endpoint{Route: "/api/v1/discovery", Name: "process_discovery"} // work with processes subdomain (get 403) // ProcessLifecycleEndpoint is a v2 endpoint used to send process lifecycle events - ProcessLifecycleEndpoint = transaction.Endpoint{Route: "/api/v2/proclcycle", Name: "process_lifecycle"} + ProcessLifecycleEndpoint = transaction.Endpoint{Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found // RtProcessesEndpoint is a v1 endpoint used to send real time process checks - RtProcessesEndpoint = transaction.Endpoint{Route: "/api/v1/collector", Name: "rtprocess"} + RtProcessesEndpoint = transaction.Endpoint{Route: "/api/v1/collector", Name: "rtprocess"} // work with processes subdomain (get 403) // ContainerEndpoint is a v1 endpoint used to send container checks - ContainerEndpoint = transaction.Endpoint{Route: "/api/v1/container", Name: "container"} + ContainerEndpoint = transaction.Endpoint{Route: "/api/v1/container", Name: "container"} // work with processes subdomain (get 403) // RtContainerEndpoint is a v1 endpoint used to send real time container checks RtContainerEndpoint = transaction.Endpoint{Route: "/api/v1/container", Name: "rtcontainer"} // ConnectionsEndpoint is a v1 endpoint used to send connection checks diff --git a/pkg/diagnose/README.md b/pkg/diagnose/README.md index 93145757c12d8..ec6f4c4deded0 100644 --- a/pkg/diagnose/README.md +++ b/pkg/diagnose/README.md @@ -62,3 +62,21 @@ func diagnose(diagCfg diagnosis.Config) []diagnosis.Diagnosis { ## Context of a diagnose function execution Normally, registered diagnose suite functions will be executed in context of the running agent service (or other services) but if ```Config.ForceLocal``` configuration is specified the registered diagnose function will be executed in the context of agent diagnose CLI command (if possible). + +## Which connectivity to endpoint are tested ? +With diagnose command, the Agent try to reach out a lot of endpoints, these ones are listed below: + +| Subdomain | Route | HTTP Method | Status Code expected | +|-----------|-------|-------------|----------------------| +| https://app.datadoghq.com | /api/v1/series | POST | 200 | +| https://app.datadoghq.com | /api/v1/check_run | POST | 200 | +| https://app.datadoghq.com | /intake/ | POST | 200 | +| https://app.datadoghq.com | /api/v1/validate | GET | 200 | +| https://app.datadoghq.com | /api/v1/metadata | POST | 200 | +| https://app.datadoghq.com | /api/v2/series | POST | 200 | +| https://app.datadoghq.com | /api/beta/sketches | POST | 200 | +| https://\-flare.agent.datadoghq.com | /support/flare | HEAD | 307 | +| https://process.datadoghq.com | /intake/status | GET | 200 | + + + From b00f3373aa8a3d67975d5afe15e2d2c3bdeefb4a Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Thu, 11 Apr 2024 13:58:54 +0200 Subject: [PATCH 05/17] Add subdomain field in endpoint struct to allow other subdomains --- .../defaultforwarder/endpoints/endpoints.go | 42 ++++++++--------- .../defaultforwarder/transaction/endpoint.go | 14 ++++++ .../transaction/endpoint_test.go | 46 +++++++++++++++++++ pkg/diagnose/connectivity/core_endpoint.go | 7 ++- .../connectivity/core_endpoint_test.go | 8 +++- 5 files changed, 90 insertions(+), 27 deletions(-) create mode 100644 comp/forwarder/defaultforwarder/transaction/endpoint_test.go diff --git a/comp/forwarder/defaultforwarder/endpoints/endpoints.go b/comp/forwarder/defaultforwarder/endpoints/endpoints.go index ebda2f5465e3d..48fb0790dd82b 100644 --- a/comp/forwarder/defaultforwarder/endpoints/endpoints.go +++ b/comp/forwarder/defaultforwarder/endpoints/endpoints.go @@ -11,47 +11,47 @@ import "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/transac var ( // V1SeriesEndpoint is a v1 endpoint used to send series - V1SeriesEndpoint = transaction.Endpoint{Route: "/api/v1/series", Name: "series_v1"} // works + V1SeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/series", Name: "series_v1"} // works // V1CheckRunsEndpoint is a v1 endpoint used to send checks results - V1CheckRunsEndpoint = transaction.Endpoint{Route: "/api/v1/check_run", Name: "check_run_v1"} // works + V1CheckRunsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/check_run", Name: "check_run_v1"} // works // V1IntakeEndpoint is a v1 endpoint, used by Agent v.5, still used for metadata - V1IntakeEndpoint = transaction.Endpoint{Route: "/intake/", Name: "intake"} // works + V1IntakeEndpoint = transaction.Endpoint{Subdomain: "", Route: "/intake/", Name: "intake"} // works // V1SketchSeriesEndpoint is a v1 endpoint used to send sketches - V1SketchSeriesEndpoint = transaction.Endpoint{Route: "/api/v1/sketches", Name: "sketches_v1"} //nolint unused for now + V1SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/sketches", Name: "sketches_v1"} //nolint unused for now // V1ValidateEndpoint is a v1 endpoint used to validate API keys - V1ValidateEndpoint = transaction.Endpoint{Route: "/api/v1/validate", Name: "validate_v1"} // works + V1ValidateEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/validate", Name: "validate_v1"} // works // V1MetadataEndpoint is a v1 endpoint used for metadata (only used for inventory metadata for now) - V1MetadataEndpoint = transaction.Endpoint{Route: "/api/v1/metadata", Name: "metadata_v1"} // works + V1MetadataEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/metadata", Name: "metadata_v1"} // works // SeriesEndpoint is the v2 endpoint used to send series - SeriesEndpoint = transaction.Endpoint{Route: "/api/v2/series", Name: "series_v2"} // works + SeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/series", Name: "series_v2"} // works // EventsEndpoint is the v2 endpoint used to send events - EventsEndpoint = transaction.Endpoint{Route: "/api/v2/events", Name: "events_v2"} + EventsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/events", Name: "events_v2"} // ServiceChecksEndpoint is the v2 endpoint used to send service checks - ServiceChecksEndpoint = transaction.Endpoint{Route: "/api/v2/service_checks", Name: "services_checks_v2"} + ServiceChecksEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/service_checks", Name: "services_checks_v2"} // SketchSeriesEndpoint is the v2 endpoint used to send sketches - SketchSeriesEndpoint = transaction.Endpoint{Route: "/api/beta/sketches", Name: "sketches_v2"} // works + SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/beta/sketches", Name: "sketches_v2"} // works // HostMetadataEndpoint is the v2 endpoint used to send host medatada - HostMetadataEndpoint = transaction.Endpoint{Route: "/api/v2/host_metadata", Name: "host_metadata_v2"} + HostMetadataEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/host_metadata", Name: "host_metadata_v2"} // ProcessesEndpoint is a v1 endpoint used to send processes checks - ProcessesEndpoint = transaction.Endpoint{Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) + ProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) // ProcessDiscoveryEndpoint is a v1 endpoint used to sends process discovery checks - ProcessDiscoveryEndpoint = transaction.Endpoint{Route: "/api/v1/discovery", Name: "process_discovery"} // work with processes subdomain (get 403) + ProcessDiscoveryEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/discovery", Name: "process_discovery"} // work with processes subdomain (get 403) // ProcessLifecycleEndpoint is a v2 endpoint used to send process lifecycle events - ProcessLifecycleEndpoint = transaction.Endpoint{Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found + ProcessLifecycleEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found // RtProcessesEndpoint is a v1 endpoint used to send real time process checks - RtProcessesEndpoint = transaction.Endpoint{Route: "/api/v1/collector", Name: "rtprocess"} // work with processes subdomain (get 403) + RtProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "rtprocess"} // work with processes subdomain (get 403) // ContainerEndpoint is a v1 endpoint used to send container checks - ContainerEndpoint = transaction.Endpoint{Route: "/api/v1/container", Name: "container"} // work with processes subdomain (get 403) + ContainerEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/container", Name: "container"} // work with processes subdomain (get 403) // RtContainerEndpoint is a v1 endpoint used to send real time container checks - RtContainerEndpoint = transaction.Endpoint{Route: "/api/v1/container", Name: "rtcontainer"} + RtContainerEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/container", Name: "rtcontainer"} // ConnectionsEndpoint is a v1 endpoint used to send connection checks - ConnectionsEndpoint = transaction.Endpoint{Route: "/api/v1/connections", Name: "connections"} + ConnectionsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/connections", Name: "connections"} // LegacyOrchestratorEndpoint is a v1 endpoint used to send orchestrator checks - LegacyOrchestratorEndpoint = transaction.Endpoint{Route: "/api/v1/orchestrator", Name: "orchestrator"} + LegacyOrchestratorEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/orchestrator", Name: "orchestrator"} // OrchestratorEndpoint is a v2 endpoint used to send orchestrator checks - OrchestratorEndpoint = transaction.Endpoint{Route: "/api/v2/orch", Name: "orchestrator"} + OrchestratorEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/orch", Name: "orchestrator"} // OrchestratorManifestEndpoint is a v2 endpoint used to send orchestrator manifests - OrchestratorManifestEndpoint = transaction.Endpoint{Route: "/api/v2/orchmanif", Name: "orchmanifest"} + OrchestratorManifestEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/orchmanif", Name: "orchmanifest"} ) diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint.go b/comp/forwarder/defaultforwarder/transaction/endpoint.go index b766be196f8ff..b8cdf6955a352 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint.go @@ -5,8 +5,12 @@ package transaction +import "strings" + // Endpoint is an endpoint type Endpoint struct { + //Subdomain of the endpoint + Subdomain string // Route to hit in the HTTP transaction Route string // Name of the endpoint for the telemetry metrics @@ -17,3 +21,13 @@ type Endpoint struct { func (e Endpoint) String() string { return e.Route } + +// GetEndpoint returns the full endpoint URL +func (e Endpoint) GetEndpoint() string { + if e.Subdomain == "" { + e.Subdomain = "https://app.datadoghq.com" + } + e.Subdomain = strings.TrimSuffix(e.Subdomain, "/") + e.Route = strings.TrimPrefix(e.Route, "/") + return e.Subdomain + "/" + e.Route +} diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go new file mode 100644 index 0000000000000..b54bb0586a067 --- /dev/null +++ b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go @@ -0,0 +1,46 @@ +package transaction + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEndpoint_GetEndpointWithSubdomain(t *testing.T) { + // Create a test endpoint with a subdomain + endpoint := Endpoint{ + Subdomain: "https://example", + Route: "/api/v1/data", + Name: "TestEndpoint", + } + result := endpoint.GetEndpoint() + expected := "https://example/api/v1/data" + assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) + + endpoint = Endpoint{ + Subdomain: "https://example/", + Route: "/api/v1/data", + Name: "TestEndpoint", + } + result = endpoint.GetEndpoint() + assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) + + endpoint = Endpoint{ + Subdomain: "https://example", + Route: "api/v1/data", + Name: "TestEndpoint", + } + result = endpoint.GetEndpoint() + assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) +} + +func TestEndpoint_GetEndpointWithoutSubdomain(t *testing.T) { + // Create a test endpoint without a subdomain + endpoint := Endpoint{ + Route: "/api/v1/data", + Name: "TestEndpoint", + } + result := endpoint.GetEndpoint() + expected := "https://app.datadoghq.com/api/v1/data" + assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) +} diff --git a/pkg/diagnose/connectivity/core_endpoint.go b/pkg/diagnose/connectivity/core_endpoint.go index f1295b2c3d242..c9ab73eefd2ec 100644 --- a/pkg/diagnose/connectivity/core_endpoint.go +++ b/pkg/diagnose/connectivity/core_endpoint.go @@ -96,11 +96,10 @@ func Diagnose(diagCfg diagnosis.Config) []diagnosis.Diagnosis { logURL = endpointInfo.Endpoint.Route statusCode, err = sendHTTPHEADRequestToEndpoint(logURL, clientWithOneRedirects()) } else { - domain, _ := domainResolver.Resolve(endpointInfo.Endpoint) httpTraces = []string{} ctx := httptrace.WithClientTrace(context.Background(), createDiagnoseTraces(&httpTraces)) - statusCode, responseBody, logURL, err = sendHTTPRequestToEndpoint(ctx, client, domain, endpointInfo, apiKey) + statusCode, responseBody, logURL, err = sendHTTPRequestToEndpoint(ctx, client, endpointInfo, apiKey) } // Check if there is a response and if it's valid @@ -149,8 +148,8 @@ func createDiagnosisString(diagnosis string, report string) string { // sendHTTPRequestToEndpoint creates an URL based on the domain and the endpoint information // then sends an HTTP Request with the method and payload inside the endpoint information -func sendHTTPRequestToEndpoint(ctx context.Context, client *http.Client, domain string, endpointInfo endpointInfo, apiKey string) (int, []byte, string, error) { - url := createEndpointURL(domain, endpointInfo) +func sendHTTPRequestToEndpoint(ctx context.Context, client *http.Client, endpointInfo endpointInfo, apiKey string) (int, []byte, string, error) { + url := endpointInfo.Endpoint.GetEndpoint() logURL := scrubber.ScrubLine(url) // Create a request for the backend diff --git a/pkg/diagnose/connectivity/core_endpoint_test.go b/pkg/diagnose/connectivity/core_endpoint_test.go index a88bd0f8990ab..45e42c15d776e 100644 --- a/pkg/diagnose/connectivity/core_endpoint_test.go +++ b/pkg/diagnose/connectivity/core_endpoint_test.go @@ -16,6 +16,7 @@ import ( "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder" "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/endpoints" + "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/transaction" "github.com/DataDog/datadog-agent/pkg/config" ) @@ -46,16 +47,19 @@ func TestSendHTTPRequestToEndpoint(t *testing.T) { })) defer ts1.Close() + // Create a copy of endpointInfoTest with the correct URL + endpointInfoTestCopy := endpointInfo{Endpoint: transaction.Endpoint{Subdomain: ts1.URL, Route: "/api/v1/validate", Name: "validate_v1"}} + client := defaultforwarder.NewHTTPClient(config.Datadog) // With the correct API Key, it should be a 200 - statusCodeWithKey, responseBodyWithKey, _, errWithKey := sendHTTPRequestToEndpoint(context.Background(), client, ts1.URL, endpointInfoTest, apiKey1) + statusCodeWithKey, responseBodyWithKey, _, errWithKey := sendHTTPRequestToEndpoint(context.Background(), client, endpointInfoTestCopy, apiKey1) assert.NoError(t, errWithKey) assert.Equal(t, statusCodeWithKey, 200) assert.Equal(t, string(responseBodyWithKey), "OK") // With the wrong API Key, it should be a 400 - statusCode, responseBody, _, err := sendHTTPRequestToEndpoint(context.Background(), client, ts1.URL, endpointInfoTest, apiKey2) + statusCode, responseBody, _, err := sendHTTPRequestToEndpoint(context.Background(), client, endpointInfoTestCopy, apiKey2) assert.NoError(t, err) assert.Equal(t, statusCode, 400) assert.Equal(t, string(responseBody), "Bad Request") From 763f33a707c2ff1196a370804935df5c0f53388b Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Thu, 11 Apr 2024 14:26:01 +0200 Subject: [PATCH 06/17] Refactor endpoint structs and update connectivity diagnose tests --- .../defaultforwarder/endpoints/endpoints.go | 34 ++++++++++--------- .../transaction/endpoint_test.go | 7 ++++ pkg/diagnose/connectivity/endpoint_info.go | 19 +---------- 3 files changed, 26 insertions(+), 34 deletions(-) diff --git a/comp/forwarder/defaultforwarder/endpoints/endpoints.go b/comp/forwarder/defaultforwarder/endpoints/endpoints.go index 48fb0790dd82b..b84db00228248 100644 --- a/comp/forwarder/defaultforwarder/endpoints/endpoints.go +++ b/comp/forwarder/defaultforwarder/endpoints/endpoints.go @@ -11,28 +11,19 @@ import "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/transac var ( // V1SeriesEndpoint is a v1 endpoint used to send series - V1SeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/series", Name: "series_v1"} // works + V1SeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/series", Name: "series_v1"} // V1CheckRunsEndpoint is a v1 endpoint used to send checks results - V1CheckRunsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/check_run", Name: "check_run_v1"} // works + V1CheckRunsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/check_run", Name: "check_run_v1"} // V1IntakeEndpoint is a v1 endpoint, used by Agent v.5, still used for metadata - V1IntakeEndpoint = transaction.Endpoint{Subdomain: "", Route: "/intake/", Name: "intake"} // works - // V1SketchSeriesEndpoint is a v1 endpoint used to send sketches - V1SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/sketches", Name: "sketches_v1"} //nolint unused for now + V1IntakeEndpoint = transaction.Endpoint{Subdomain: "", Route: "/intake/", Name: "intake"} // V1ValidateEndpoint is a v1 endpoint used to validate API keys - V1ValidateEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/validate", Name: "validate_v1"} // works + V1ValidateEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/validate", Name: "validate_v1"} // V1MetadataEndpoint is a v1 endpoint used for metadata (only used for inventory metadata for now) - V1MetadataEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/metadata", Name: "metadata_v1"} // works - + V1MetadataEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/metadata", Name: "metadata_v1"} // SeriesEndpoint is the v2 endpoint used to send series - SeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/series", Name: "series_v2"} // works - // EventsEndpoint is the v2 endpoint used to send events - EventsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/events", Name: "events_v2"} - // ServiceChecksEndpoint is the v2 endpoint used to send service checks - ServiceChecksEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/service_checks", Name: "services_checks_v2"} + SeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/series", Name: "series_v2"} // SketchSeriesEndpoint is the v2 endpoint used to send sketches - SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/beta/sketches", Name: "sketches_v2"} // works - // HostMetadataEndpoint is the v2 endpoint used to send host medatada - HostMetadataEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/host_metadata", Name: "host_metadata_v2"} + SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/beta/sketches", Name: "sketches_v2"} // ProcessesEndpoint is a v1 endpoint used to send processes checks ProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) @@ -54,4 +45,15 @@ var ( OrchestratorEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/orch", Name: "orchestrator"} // OrchestratorManifestEndpoint is a v2 endpoint used to send orchestrator manifests OrchestratorManifestEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/orchmanif", Name: "orchmanifest"} + + /////////////// Unused Endpoints /////////////// + + // V1SketchSeriesEndpoint is a v1 endpoint used to send sketches + V1SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/sketches", Name: "sketches_v1"} //nolint + // EventsEndpoint is the v2 endpoint used to send events + EventsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/events", Name: "events_v2"} + // ServiceChecksEndpoint is the v2 endpoint used to send service checks + ServiceChecksEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/service_checks", Name: "services_checks_v2"} + // HostMetadataEndpoint is the v2 endpoint used to send host medatada + HostMetadataEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/host_metadata", Name: "host_metadata_v2"} ) diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go index b54bb0586a067..2f15fa619dc09 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go @@ -1,3 +1,10 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +// Package endpoints stores a collection of `transaction.Endpoint` mainly used by the forwarder package to send data to +// Datadog using the right request path for a given type of data. package transaction import ( diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 557a3fb01c14e..39ba29a88f9d3 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -41,29 +41,12 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { {endpoints.V1SeriesEndpoint, "POST", emptyPayload}, {endpoints.V1CheckRunsEndpoint, "POST", checkRunPayload}, {endpoints.V1IntakeEndpoint, "POST", emptyPayload}, - // {endpoints.V1SketchSeriesEndpoint, "POST", emptyPayload}, // This one does not work - // This endpoint behaves differently depending on `site` when using `emptyPayload`. Do not modify `nil` here ! - {endpoints.V1ValidateEndpoint, "GET", nil}, + {endpoints.V1ValidateEndpoint, "GET", nil}, // This endpoint behaves differently depending on `site` when using `emptyPayload`. Do not modify `nil` here ! {endpoints.V1MetadataEndpoint, "POST", emptyPayload}, // v2 endpoints {endpoints.SeriesEndpoint, "POST", emptyPayload}, - // {endpoints.EventsEndpoint, "POST", emptyPayload}, // This one does not work - // {endpoints.ServiceChecksEndpoint, "GET", emptyPayload},// This one does not work {endpoints.SketchSeriesEndpoint, "POST", emptyPayload}, - // {endpoints.HostMetadataEndpoint, "POST", emptyPayload},// This one does not work - - // Process endpoints - //{endpoints.ProcessesEndpoint, "HEAD", nil}, - //{endpoints.ProcessDiscoveryEndpoint, "HEAD", nil}, - //{endpoints.ProcessLifecycleEndpoint, "HEAD", nil}, - //{endpoints.RtProcessesEndpoint, "HEAD", nil}, - //{endpoints.ContainerEndpoint, "HEAD", nil}, - //{endpoints.RtContainerEndpoint, "HEAD", nil}, - //{endpoints.ConnectionsEndpoint, "HEAD", nil}, - //{endpoints.LegacyOrchestratorEndpoint, "HEAD", nil}, - //{endpoints.OrchestratorEndpoint, "HEAD", nil}, - //{endpoints.OrchestratorManifestEndpoint, "HEAD", nil}, // Flare endpoint {transaction.Endpoint{Route: helpers.GetFlareEndpoint(cfg), Name: "flare"}, "HEAD", nil}, From 6394fe93886c87d20ec19e652b105c7645f08338 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Thu, 11 Apr 2024 15:48:44 +0200 Subject: [PATCH 07/17] add endpoints in endpoints.go --- .../defaultforwarder/endpoints/endpoints.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/comp/forwarder/defaultforwarder/endpoints/endpoints.go b/comp/forwarder/defaultforwarder/endpoints/endpoints.go index b84db00228248..10096277b1845 100644 --- a/comp/forwarder/defaultforwarder/endpoints/endpoints.go +++ b/comp/forwarder/defaultforwarder/endpoints/endpoints.go @@ -25,26 +25,28 @@ var ( // SketchSeriesEndpoint is the v2 endpoint used to send sketches SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/beta/sketches", Name: "sketches_v2"} + // ProcessesStatusEndpoint is a v1 endpoint used to send processes checks + ProcessesStatusEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/intake/status", Name: "process_status"} // ProcessesEndpoint is a v1 endpoint used to send processes checks ProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) // ProcessDiscoveryEndpoint is a v1 endpoint used to sends process discovery checks ProcessDiscoveryEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/discovery", Name: "process_discovery"} // work with processes subdomain (get 403) // ProcessLifecycleEndpoint is a v2 endpoint used to send process lifecycle events - ProcessLifecycleEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found + ProcessLifecycleEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found // RtProcessesEndpoint is a v1 endpoint used to send real time process checks RtProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "rtprocess"} // work with processes subdomain (get 403) // ContainerEndpoint is a v1 endpoint used to send container checks ContainerEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/container", Name: "container"} // work with processes subdomain (get 403) // RtContainerEndpoint is a v1 endpoint used to send real time container checks - RtContainerEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/container", Name: "rtcontainer"} + RtContainerEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/container", Name: "rtcontainer"} // ConnectionsEndpoint is a v1 endpoint used to send connection checks - ConnectionsEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/connections", Name: "connections"} + ConnectionsEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/connections", Name: "connections"} // LegacyOrchestratorEndpoint is a v1 endpoint used to send orchestrator checks - LegacyOrchestratorEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v1/orchestrator", Name: "orchestrator"} + LegacyOrchestratorEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v1/orchestrator", Name: "orchestrator"} // OrchestratorEndpoint is a v2 endpoint used to send orchestrator checks - OrchestratorEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/orch", Name: "orchestrator"} + OrchestratorEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v2/orch", Name: "orchestrator"} // OrchestratorManifestEndpoint is a v2 endpoint used to send orchestrator manifests - OrchestratorManifestEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/v2/orchmanif", Name: "orchmanifest"} + OrchestratorManifestEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v2/orchmanif", Name: "orchmanifest"} // work with POST but got 401 /////////////// Unused Endpoints /////////////// From bd660ed248dd86543b0c17ac13c4684f565b27e4 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Fri, 12 Apr 2024 10:46:16 +0200 Subject: [PATCH 08/17] Refactor endpoint struct and update connectivity diagnose tests --- comp/forwarder/defaultforwarder/transaction/endpoint.go | 8 +++++--- pkg/diagnose/connectivity/core_endpoint.go | 7 ++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint.go b/comp/forwarder/defaultforwarder/transaction/endpoint.go index b8cdf6955a352..19a069f8098a0 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint.go @@ -23,11 +23,13 @@ func (e Endpoint) String() string { } // GetEndpoint returns the full endpoint URL -func (e Endpoint) GetEndpoint() string { +func (e Endpoint) GetEndpoint(domain string) string { if e.Subdomain == "" { - e.Subdomain = "https://app.datadoghq.com" + return domain + e.Route } e.Subdomain = strings.TrimSuffix(e.Subdomain, "/") e.Route = strings.TrimPrefix(e.Route, "/") - return e.Subdomain + "/" + e.Route + url := e.Subdomain + "/" + e.Route + + return url } diff --git a/pkg/diagnose/connectivity/core_endpoint.go b/pkg/diagnose/connectivity/core_endpoint.go index c9ab73eefd2ec..85f430b9d3ec2 100644 --- a/pkg/diagnose/connectivity/core_endpoint.go +++ b/pkg/diagnose/connectivity/core_endpoint.go @@ -96,10 +96,11 @@ func Diagnose(diagCfg diagnosis.Config) []diagnosis.Diagnosis { logURL = endpointInfo.Endpoint.Route statusCode, err = sendHTTPHEADRequestToEndpoint(logURL, clientWithOneRedirects()) } else { + domain, _ := domainResolver.Resolve(endpointInfo.Endpoint) httpTraces = []string{} ctx := httptrace.WithClientTrace(context.Background(), createDiagnoseTraces(&httpTraces)) - statusCode, responseBody, logURL, err = sendHTTPRequestToEndpoint(ctx, client, endpointInfo, apiKey) + statusCode, responseBody, logURL, err = sendHTTPRequestToEndpoint(ctx, client, domain, endpointInfo, apiKey) } // Check if there is a response and if it's valid @@ -148,8 +149,8 @@ func createDiagnosisString(diagnosis string, report string) string { // sendHTTPRequestToEndpoint creates an URL based on the domain and the endpoint information // then sends an HTTP Request with the method and payload inside the endpoint information -func sendHTTPRequestToEndpoint(ctx context.Context, client *http.Client, endpointInfo endpointInfo, apiKey string) (int, []byte, string, error) { - url := endpointInfo.Endpoint.GetEndpoint() +func sendHTTPRequestToEndpoint(ctx context.Context, client *http.Client, domain string, endpointInfo endpointInfo, apiKey string) (int, []byte, string, error) { + url := endpointInfo.Endpoint.GetEndpoint(domain) logURL := scrubber.ScrubLine(url) // Create a request for the backend From 164737f8cbd0989ea4b3ef11aff91da059a16c7f Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Fri, 12 Apr 2024 16:35:24 +0200 Subject: [PATCH 09/17] Refactor endpoint struct and update connectivity diagnose tests --- .../defaultforwarder/endpoints/endpoints.go | 26 ++++--- .../defaultforwarder/transaction/endpoint.go | 16 +++- .../transaction/endpoint_test.go | 76 ++++++++++--------- pkg/diagnose/connectivity/endpoint_info.go | 16 ++++ 4 files changed, 85 insertions(+), 49 deletions(-) diff --git a/comp/forwarder/defaultforwarder/endpoints/endpoints.go b/comp/forwarder/defaultforwarder/endpoints/endpoints.go index 10096277b1845..6506f394bb2ec 100644 --- a/comp/forwarder/defaultforwarder/endpoints/endpoints.go +++ b/comp/forwarder/defaultforwarder/endpoints/endpoints.go @@ -25,28 +25,30 @@ var ( // SketchSeriesEndpoint is the v2 endpoint used to send sketches SketchSeriesEndpoint = transaction.Endpoint{Subdomain: "", Route: "/api/beta/sketches", Name: "sketches_v2"} - // ProcessesStatusEndpoint is a v1 endpoint used to send processes checks - ProcessesStatusEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/intake/status", Name: "process_status"} + // ProcessStatusEndpoint is a v1 endpoint used to send process checks + ProcessStatusEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/status", Name: "process_status"} + // ProcessesIntakeStatusEndpoint is a v1 endpoint used to send processes checks + ProcessesIntakeStatusEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/intake/status", Name: "process_intake_status"} // ProcessesEndpoint is a v1 endpoint used to send processes checks - ProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) + ProcessesEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/api/v1/collector", Name: "process"} // work with processes subdomain (get 403) // ProcessDiscoveryEndpoint is a v1 endpoint used to sends process discovery checks - ProcessDiscoveryEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/discovery", Name: "process_discovery"} // work with processes subdomain (get 403) + ProcessDiscoveryEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/api/v1/discovery", Name: "process_discovery"} // work with processes subdomain (get 403) // ProcessLifecycleEndpoint is a v2 endpoint used to send process lifecycle events - ProcessLifecycleEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found + ProcessLifecycleEndpoint = transaction.Endpoint{Subdomain: "orchestrator", Route: "/api/v2/proclcycle", Name: "process_lifecycle"} // 404 not found // RtProcessesEndpoint is a v1 endpoint used to send real time process checks - RtProcessesEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/collector", Name: "rtprocess"} // work with processes subdomain (get 403) + RtProcessesEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/api/v1/collector", Name: "rtprocess"} // work with processes subdomain (get 403) // ContainerEndpoint is a v1 endpoint used to send container checks - ContainerEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/container", Name: "container"} // work with processes subdomain (get 403) + ContainerEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/api/v1/container", Name: "container"} // work with processes subdomain (get 403) // RtContainerEndpoint is a v1 endpoint used to send real time container checks - RtContainerEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/container", Name: "rtcontainer"} + RtContainerEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/api/v1/container", Name: "rtcontainer"} // ConnectionsEndpoint is a v1 endpoint used to send connection checks - ConnectionsEndpoint = transaction.Endpoint{Subdomain: "https://process.datadoghq.com/", Route: "/api/v1/connections", Name: "connections"} + ConnectionsEndpoint = transaction.Endpoint{Subdomain: "process", Route: "/api/v1/connections", Name: "connections"} // LegacyOrchestratorEndpoint is a v1 endpoint used to send orchestrator checks - LegacyOrchestratorEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v1/orchestrator", Name: "orchestrator"} + LegacyOrchestratorEndpoint = transaction.Endpoint{Subdomain: "orchestrator", Route: "/api/v1/orchestrator", Name: "orchestrator"} // OrchestratorEndpoint is a v2 endpoint used to send orchestrator checks - OrchestratorEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v2/orch", Name: "orchestrator"} + OrchestratorEndpoint = transaction.Endpoint{Subdomain: "orchestrator", Route: "/api/v2/orch", Name: "orchestrator"} // OrchestratorManifestEndpoint is a v2 endpoint used to send orchestrator manifests - OrchestratorManifestEndpoint = transaction.Endpoint{Subdomain: "https://orchestrator.datadoghq.com", Route: "/api/v2/orchmanif", Name: "orchmanifest"} // work with POST but got 401 + OrchestratorManifestEndpoint = transaction.Endpoint{Subdomain: "orchestrator", Route: "/api/v2/orchmanif", Name: "orchmanifest"} // work with POST but got 401 /////////////// Unused Endpoints /////////////// diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint.go b/comp/forwarder/defaultforwarder/transaction/endpoint.go index 19a069f8098a0..2488eaad60aa9 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint.go @@ -25,11 +25,21 @@ func (e Endpoint) String() string { // GetEndpoint returns the full endpoint URL func (e Endpoint) GetEndpoint(domain string) string { if e.Subdomain == "" { - return domain + e.Route + e.Subdomain = "app" } + e.Subdomain = strings.TrimSuffix(e.Subdomain, "/") + e.Subdomain = strings.TrimPrefix(e.Subdomain, "/") + + domain = strings.TrimSuffix(domain, "/") e.Route = strings.TrimPrefix(e.Route, "/") - url := e.Subdomain + "/" + e.Route - + + url := domain + "/" + e.Route + + url = strings.TrimPrefix(url, "https://") + url = "https://" + url + + url = strings.Replace(url, "app", e.Subdomain, 1) + return url } diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go index 2f15fa619dc09..bebdd8c582053 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go @@ -13,41 +13,49 @@ import ( "github.com/stretchr/testify/assert" ) -func TestEndpoint_GetEndpointWithSubdomain(t *testing.T) { - // Create a test endpoint with a subdomain - endpoint := Endpoint{ - Subdomain: "https://example", - Route: "/api/v1/data", - Name: "TestEndpoint", +func TestGetEndpoint(t *testing.T) { + tests := []struct { + name string + endpoint Endpoint + domain string + want string + }{ + { + name: "default subdomain applied when empty", + endpoint: Endpoint{Route: "docs"}, + domain: "https://dev.example.com", + want: "https://dev.example.com/docs", + }, + { + name: "explicit subdomain replacement", + endpoint: Endpoint{Subdomain: "admin", Route: "docs"}, + domain: "app.example.com", + want: "https://admin.example.com/docs", + }, + { + name: "no subdomain, app not in domain", + endpoint: Endpoint{Subdomain: "app/", Route: "docs"}, + domain: "myappsite.com", + want: "https://myappsite.com/docs", + }, + { + name: "subdomain app with app in domain", + endpoint: Endpoint{Subdomain: "app", Route: "support"}, + domain: "https://app.company.com", + want: "https://app.company.com/support", + }, + { + name: "complex route and domain", + endpoint: Endpoint{Subdomain: "api", Route: "/v1/users"}, + domain: "https://app.service.com", + want: "https://api.service.com/v1/users", + }, } - result := endpoint.GetEndpoint() - expected := "https://example/api/v1/data" - assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) - endpoint = Endpoint{ - Subdomain: "https://example/", - Route: "/api/v1/data", - Name: "TestEndpoint", + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.endpoint.GetEndpoint(tt.domain) + assert.Equal(t, tt.want, got) + }) } - result = endpoint.GetEndpoint() - assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) - - endpoint = Endpoint{ - Subdomain: "https://example", - Route: "api/v1/data", - Name: "TestEndpoint", - } - result = endpoint.GetEndpoint() - assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) -} - -func TestEndpoint_GetEndpointWithoutSubdomain(t *testing.T) { - // Create a test endpoint without a subdomain - endpoint := Endpoint{ - Route: "/api/v1/data", - Name: "TestEndpoint", - } - result := endpoint.GetEndpoint() - expected := "https://app.datadoghq.com/api/v1/data" - assert.Equal(t, expected, result, "Expected endpoint URL %s, but got %s", expected, result) } diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 39ba29a88f9d3..1be20ba3f3cc0 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -48,6 +48,22 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { {endpoints.SeriesEndpoint, "POST", emptyPayload}, {endpoints.SketchSeriesEndpoint, "POST", emptyPayload}, + // Process endpoints + {endpoints.ProcessStatusEndpoint, "GET", nil}, + {endpoints.ProcessesIntakeStatusEndpoint, "GET", nil}, + //{endpoints.ProcessesEndpoint, "POST", emptyPayload}, + //{endpoints.ProcessDiscoveryEndpoint, "POST", emptyPayload}, + //{endpoints.RtProcessesEndpoint, "POST", emptyPayload}, + //{endpoints.ContainerEndpoint, "POST", emptyPayload}, + //{endpoints.RtContainerEndpoint, "POST", emptyPayload}, + //{endpoints.ConnectionsEndpoint, "POST", emptyPayload}, + + // Orchestrator endpoints + //{endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, + //{endpoints.LegacyOrchestratorEndpoint, "POST", emptyPayload}, + //{endpoints.OrchestratorEndpoint, "POST", emptyPayload}, + //{endpoints.OrchestratorManifestEndpoint, "POST", emptyPayload}, + // Flare endpoint {transaction.Endpoint{Route: helpers.GetFlareEndpoint(cfg), Name: "flare"}, "HEAD", nil}, } From 44556b18f06907cf86b5aef0b308fde40fad7a6b Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Sat, 13 Apr 2024 07:53:00 +0200 Subject: [PATCH 10/17] Crash test some endpoints --- pkg/diagnose/connectivity/endpoint_info.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 1be20ba3f3cc0..882433790c039 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -51,7 +51,7 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { // Process endpoints {endpoints.ProcessStatusEndpoint, "GET", nil}, {endpoints.ProcessesIntakeStatusEndpoint, "GET", nil}, - //{endpoints.ProcessesEndpoint, "POST", emptyPayload}, + {endpoints.ProcessesEndpoint, "POST", emptyPayload}, //{endpoints.ProcessDiscoveryEndpoint, "POST", emptyPayload}, //{endpoints.RtProcessesEndpoint, "POST", emptyPayload}, //{endpoints.ContainerEndpoint, "POST", emptyPayload}, @@ -59,7 +59,7 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { //{endpoints.ConnectionsEndpoint, "POST", emptyPayload}, // Orchestrator endpoints - //{endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, + {endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, //{endpoints.LegacyOrchestratorEndpoint, "POST", emptyPayload}, //{endpoints.OrchestratorEndpoint, "POST", emptyPayload}, //{endpoints.OrchestratorManifestEndpoint, "POST", emptyPayload}, From 3e50333e45b531aa5d968ddfcdf5974d70adc0f8 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Mon, 15 Apr 2024 14:09:46 +0200 Subject: [PATCH 11/17] Refactor endpoint struct and update connectivity diagnose tests --- pkg/diagnose/connectivity/core_endpoint_test.go | 8 ++------ pkg/diagnose/connectivity/endpoint_info.go | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/pkg/diagnose/connectivity/core_endpoint_test.go b/pkg/diagnose/connectivity/core_endpoint_test.go index 45e42c15d776e..a88bd0f8990ab 100644 --- a/pkg/diagnose/connectivity/core_endpoint_test.go +++ b/pkg/diagnose/connectivity/core_endpoint_test.go @@ -16,7 +16,6 @@ import ( "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder" "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/endpoints" - "github.com/DataDog/datadog-agent/comp/forwarder/defaultforwarder/transaction" "github.com/DataDog/datadog-agent/pkg/config" ) @@ -47,19 +46,16 @@ func TestSendHTTPRequestToEndpoint(t *testing.T) { })) defer ts1.Close() - // Create a copy of endpointInfoTest with the correct URL - endpointInfoTestCopy := endpointInfo{Endpoint: transaction.Endpoint{Subdomain: ts1.URL, Route: "/api/v1/validate", Name: "validate_v1"}} - client := defaultforwarder.NewHTTPClient(config.Datadog) // With the correct API Key, it should be a 200 - statusCodeWithKey, responseBodyWithKey, _, errWithKey := sendHTTPRequestToEndpoint(context.Background(), client, endpointInfoTestCopy, apiKey1) + statusCodeWithKey, responseBodyWithKey, _, errWithKey := sendHTTPRequestToEndpoint(context.Background(), client, ts1.URL, endpointInfoTest, apiKey1) assert.NoError(t, errWithKey) assert.Equal(t, statusCodeWithKey, 200) assert.Equal(t, string(responseBodyWithKey), "OK") // With the wrong API Key, it should be a 400 - statusCode, responseBody, _, err := sendHTTPRequestToEndpoint(context.Background(), client, endpointInfoTestCopy, apiKey2) + statusCode, responseBody, _, err := sendHTTPRequestToEndpoint(context.Background(), client, ts1.URL, endpointInfoTest, apiKey2) assert.NoError(t, err) assert.Equal(t, statusCode, 400) assert.Equal(t, string(responseBody), "Bad Request") diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 882433790c039..3dd89705f7122 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -59,7 +59,7 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { //{endpoints.ConnectionsEndpoint, "POST", emptyPayload}, // Orchestrator endpoints - {endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, + //{endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, //{endpoints.LegacyOrchestratorEndpoint, "POST", emptyPayload}, //{endpoints.OrchestratorEndpoint, "POST", emptyPayload}, //{endpoints.OrchestratorManifestEndpoint, "POST", emptyPayload}, From afad24538f739b88b8f518c9166ac90dd28f9179 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 17 Apr 2024 10:37:51 +0200 Subject: [PATCH 12/17] Make 400 with specific body message from processes endpoint work in diagnose --- pkg/diagnose/connectivity/core_endpoint.go | 24 ++++++++++++---------- pkg/diagnose/connectivity/endpoint_info.go | 16 +++++++-------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/pkg/diagnose/connectivity/core_endpoint.go b/pkg/diagnose/connectivity/core_endpoint.go index 85f430b9d3ec2..eff48bf6d8066 100644 --- a/pkg/diagnose/connectivity/core_endpoint.go +++ b/pkg/diagnose/connectivity/core_endpoint.go @@ -168,18 +168,20 @@ func sendHTTPRequestToEndpoint(ctx context.Context, client *http.Client, domain resp, err := client.Do(req) - if err != nil { - return 0, nil, logURL, fmt.Errorf("cannot send the HTTP request to '%v' : %v", logURL, scrubber.ScrubLine(err.Error())) - } - defer func() { _ = resp.Body.Close() }() + if (err == nil) || (endpointInfo.Endpoint.Subdomain == "process" && resp.StatusCode == http.StatusBadRequest) { + defer func() { _ = resp.Body.Close() }() + // Get the endpoint response + body, err := io.ReadAll(resp.Body) + if err != nil { + return 0, nil, logURL, fmt.Errorf("fail to read the response Body: %s", scrubber.ScrubLine(err.Error())) + } else if strings.Contains(string(body), "invalid message format") { + resp.StatusCode = -1 + } - // Get the endpoint response - body, err := io.ReadAll(resp.Body) - if err != nil { - return 0, nil, logURL, fmt.Errorf("fail to read the response Body: %s", scrubber.ScrubLine(err.Error())) + return resp.StatusCode, body, logURL, nil } - return resp.StatusCode, body, logURL, nil + return 0, nil, logURL, fmt.Errorf("cannot send the HTTP request to '%v' : %v", logURL, scrubber.ScrubLine(err.Error())) } // createEndpointUrl joins a domain with an endpoint @@ -201,9 +203,9 @@ func verifyEndpointResponse(statusCode int, responseBody []byte, err error) (str if statusCode >= 400 { newErr = fmt.Errorf("bad request") verifyReport = fmt.Sprintf("Received response : '%v'\n", scrubber.ScrubLine(string(responseBody))) + } else if statusCode != -1 { + verifyReport += fmt.Sprintf("Received status code %v from the endpoint", statusCode) } - - verifyReport += fmt.Sprintf("Received status code %v from the endpoint", statusCode) return verifyReport, newErr } diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 3dd89705f7122..8866f719c85a4 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -52,17 +52,17 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { {endpoints.ProcessStatusEndpoint, "GET", nil}, {endpoints.ProcessesIntakeStatusEndpoint, "GET", nil}, {endpoints.ProcessesEndpoint, "POST", emptyPayload}, - //{endpoints.ProcessDiscoveryEndpoint, "POST", emptyPayload}, - //{endpoints.RtProcessesEndpoint, "POST", emptyPayload}, - //{endpoints.ContainerEndpoint, "POST", emptyPayload}, - //{endpoints.RtContainerEndpoint, "POST", emptyPayload}, - //{endpoints.ConnectionsEndpoint, "POST", emptyPayload}, + {endpoints.ProcessDiscoveryEndpoint, "POST", emptyPayload}, + {endpoints.RtProcessesEndpoint, "POST", emptyPayload}, + {endpoints.ContainerEndpoint, "POST", emptyPayload}, + {endpoints.RtContainerEndpoint, "POST", emptyPayload}, + {endpoints.ConnectionsEndpoint, "POST", emptyPayload}, // Orchestrator endpoints - //{endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, + {endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, //{endpoints.LegacyOrchestratorEndpoint, "POST", emptyPayload}, - //{endpoints.OrchestratorEndpoint, "POST", emptyPayload}, - //{endpoints.OrchestratorManifestEndpoint, "POST", emptyPayload}, + {endpoints.OrchestratorEndpoint, "POST", emptyPayload}, + {endpoints.OrchestratorManifestEndpoint, "POST", emptyPayload}, // Flare endpoint {transaction.Endpoint{Route: helpers.GetFlareEndpoint(cfg), Name: "flare"}, "HEAD", nil}, From 5d44b4218d38ed4aaf6a3efdca88c47d8d8419cf Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 17 Apr 2024 11:03:28 +0200 Subject: [PATCH 13/17] Revert commented out endpoint in endpoint_info.go --- pkg/diagnose/connectivity/endpoint_info.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/diagnose/connectivity/endpoint_info.go b/pkg/diagnose/connectivity/endpoint_info.go index 8866f719c85a4..f17bf26734128 100644 --- a/pkg/diagnose/connectivity/endpoint_info.go +++ b/pkg/diagnose/connectivity/endpoint_info.go @@ -59,8 +59,8 @@ func getEndpointsInfo(cfg config.Reader) []endpointInfo { {endpoints.ConnectionsEndpoint, "POST", emptyPayload}, // Orchestrator endpoints - {endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, - //{endpoints.LegacyOrchestratorEndpoint, "POST", emptyPayload}, + //{endpoints.ProcessLifecycleEndpoint, "POST", emptyPayload}, + {endpoints.LegacyOrchestratorEndpoint, "POST", emptyPayload}, {endpoints.OrchestratorEndpoint, "POST", emptyPayload}, {endpoints.OrchestratorManifestEndpoint, "POST", emptyPayload}, From 7cb67f86728bc59e65c4cc5571ef08994a3ab68a Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 17 Apr 2024 13:50:53 +0200 Subject: [PATCH 14/17] fix linter --- .../transaction/endpoint_test.go | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go index bebdd8c582053..ea7d1c16ca4e1 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint_test.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint_test.go @@ -15,40 +15,40 @@ import ( func TestGetEndpoint(t *testing.T) { tests := []struct { - name string - endpoint Endpoint - domain string - want string + name string + endpoint Endpoint + domain string + want string }{ { - name: "default subdomain applied when empty", - endpoint: Endpoint{Route: "docs"}, - domain: "https://dev.example.com", - want: "https://dev.example.com/docs", + name: "default subdomain applied when empty", + endpoint: Endpoint{Route: "docs"}, + domain: "https://dev.example.com", + want: "https://dev.example.com/docs", }, { - name: "explicit subdomain replacement", - endpoint: Endpoint{Subdomain: "admin", Route: "docs"}, - domain: "app.example.com", - want: "https://admin.example.com/docs", + name: "explicit subdomain replacement", + endpoint: Endpoint{Subdomain: "admin", Route: "docs"}, + domain: "app.example.com", + want: "https://admin.example.com/docs", }, { - name: "no subdomain, app not in domain", - endpoint: Endpoint{Subdomain: "app/", Route: "docs"}, - domain: "myappsite.com", - want: "https://myappsite.com/docs", + name: "no subdomain, app not in domain", + endpoint: Endpoint{Subdomain: "app/", Route: "docs"}, + domain: "myappsite.com", + want: "https://myappsite.com/docs", }, { - name: "subdomain app with app in domain", - endpoint: Endpoint{Subdomain: "app", Route: "support"}, - domain: "https://app.company.com", - want: "https://app.company.com/support", + name: "subdomain app with app in domain", + endpoint: Endpoint{Subdomain: "app", Route: "support"}, + domain: "https://app.company.com", + want: "https://app.company.com/support", }, { - name: "complex route and domain", - endpoint: Endpoint{Subdomain: "api", Route: "/v1/users"}, - domain: "https://app.service.com", - want: "https://api.service.com/v1/users", + name: "complex route and domain", + endpoint: Endpoint{Subdomain: "api", Route: "/v1/users"}, + domain: "https://app.service.com", + want: "https://api.service.com/v1/users", }, } From 34831953a79229c2427943ad3681c218c611911c Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 17 Apr 2024 14:22:54 +0200 Subject: [PATCH 15/17] fix endpoint creator --- comp/forwarder/defaultforwarder/transaction/endpoint.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/comp/forwarder/defaultforwarder/transaction/endpoint.go b/comp/forwarder/defaultforwarder/transaction/endpoint.go index 2488eaad60aa9..21adcc485733a 100644 --- a/comp/forwarder/defaultforwarder/transaction/endpoint.go +++ b/comp/forwarder/defaultforwarder/transaction/endpoint.go @@ -36,8 +36,9 @@ func (e Endpoint) GetEndpoint(domain string) string { url := domain + "/" + e.Route - url = strings.TrimPrefix(url, "https://") - url = "https://" + url + if !strings.Contains(url, "http://") && !strings.Contains(url, "https://") { + url = "https://" + url + } url = strings.Replace(url, "app", e.Subdomain, 1) From 3f2b9f1e25d3bef4b708b6584aabed92ef223cf0 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 17 Apr 2024 14:37:03 +0200 Subject: [PATCH 16/17] add other subdomain test --- pkg/diagnose/connectivity/core_endpoint_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pkg/diagnose/connectivity/core_endpoint_test.go b/pkg/diagnose/connectivity/core_endpoint_test.go index a88bd0f8990ab..cfd80cab0c8d2 100644 --- a/pkg/diagnose/connectivity/core_endpoint_test.go +++ b/pkg/diagnose/connectivity/core_endpoint_test.go @@ -24,6 +24,7 @@ var ( apiKey2 = "api_key2" endpointInfoTest = endpointInfo{Endpoint: endpoints.V1ValidateEndpoint} + endpointProcessTest = endpointInfo{Endpoint: endpoints.ProcessStatusEndpoint} ) func TestCreateEndpointUrl(t *testing.T) { @@ -59,6 +60,12 @@ func TestSendHTTPRequestToEndpoint(t *testing.T) { assert.NoError(t, err) assert.Equal(t, statusCode, 400) assert.Equal(t, string(responseBody), "Bad Request") + + // With a different subdomain endpoint + statusCodeProcess, responseBodyProcess, _, errProcess := sendHTTPRequestToEndpoint(context.Background(), client, ts1.URL, endpointProcessTest, apiKey1) + assert.NoError(t, errProcess) + assert.Equal(t, statusCodeProcess, 200) + assert.Equal(t, string(responseBodyProcess), "OK") } func TestAcceptRedirection(t *testing.T) { From 9f9d970ab16843b6cd4e12054bc84a4a9583c1d0 Mon Sep 17 00:00:00 2001 From: Louis Coquerelle Date: Wed, 17 Apr 2024 14:53:55 +0200 Subject: [PATCH 17/17] fix linter --- pkg/diagnose/connectivity/core_endpoint_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/diagnose/connectivity/core_endpoint_test.go b/pkg/diagnose/connectivity/core_endpoint_test.go index cfd80cab0c8d2..6f673f34bb106 100644 --- a/pkg/diagnose/connectivity/core_endpoint_test.go +++ b/pkg/diagnose/connectivity/core_endpoint_test.go @@ -23,7 +23,7 @@ var ( apiKey1 = "api_key1" apiKey2 = "api_key2" - endpointInfoTest = endpointInfo{Endpoint: endpoints.V1ValidateEndpoint} + endpointInfoTest = endpointInfo{Endpoint: endpoints.V1ValidateEndpoint} endpointProcessTest = endpointInfo{Endpoint: endpoints.ProcessStatusEndpoint} )