From fedebd66adfc1ee35725e1ba8d31815fdb0bc97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Sibiril?= <81782+aureliensibiril@users.noreply.github.com> Date: Fri, 29 May 2026 18:45:18 +0200 Subject: [PATCH] Persist Datadog domain settings on reconnect MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com> --- pkg/probo/connector_service.go | 11 +++++ pkg/server/api/console/v1/resolver.go | 69 ++++++++++++++++----------- 2 files changed, 51 insertions(+), 29 deletions(-) diff --git a/pkg/probo/connector_service.go b/pkg/probo/connector_service.go index 3f33de97b..865037901 100644 --- a/pkg/probo/connector_service.go +++ b/pkg/probo/connector_service.go @@ -65,6 +65,12 @@ type ( OrganizationID gid.GID Provider coredata.ConnectorProvider Connection connector.Connection + // RawSettings, when non-empty, replaces the connector's + // provider-specific settings on reconnect. Datadog captures its + // per-customer API domain on every OAuth callback (the domain + // drives the driver's API host), so a reconnect must refresh it; + // empty leaves the existing settings intact. + RawSettings json.RawMessage } ) @@ -356,6 +362,11 @@ func (s *ConnectorService) Reconnect( preserveConnectionFields(req.Connection, cnnctr.Connection) cnnctr.Connection = req.Connection + + if len(req.RawSettings) > 0 { + cnnctr.RawSettings = []byte(req.RawSettings) + } + cnnctr.UpdatedAt = time.Now() return cnnctr.Update(ctx, conn, scope, s.svc.encryptionKey) diff --git a/pkg/server/api/console/v1/resolver.go b/pkg/server/api/console/v1/resolver.go index 9e4b8cadf..0fb8c29b1 100644 --- a/pkg/server/api/console/v1/resolver.go +++ b/pkg/server/api/console/v1/resolver.go @@ -189,6 +189,40 @@ func handleConnectorComplete( var cnnctr *coredata.Connector + // Datadog returns the customer's API domain as a `domain` query + // parameter on every OAuth callback; it drives the driver's API + // host, so capture and validate it on both the create and the + // reconnect path (a reconnect from a different site must refresh + // the stored domain). + var datadogRawSettings json.RawMessage + + if connectorProvider == coredata.ConnectorProviderDatadog { + domain := query.Get("domain") + if !connector.IsValidDatadogDomain(domain) { + logger.WarnCtx(r.Context(), "rejecting invalid datadog domain", + log.String("provider", string(connectorProvider)), + ) + httpserver.RenderError(w, http.StatusBadRequest, fmt.Errorf("invalid domain")) + + return + } + + region, _ := connector.DatadogSiteForDomain(domain) + + raw, err := json.Marshal(&coredata.DatadogConnectorSettings{ + Region: region, + Domain: domain, + }) + if err != nil { + logger.ErrorCtx(r.Context(), "cannot marshal datadog settings", log.Error(err)) + httpserver.RenderError(w, http.StatusInternalServerError, fmt.Errorf("internal error")) + + return + } + + datadogRawSettings = raw + } + // If a connector_id was passed in the state, this is a // reconnection — update the existing connector's token. if state.ConnectorID != "" { @@ -206,6 +240,7 @@ func handleConnectorComplete( OrganizationID: organizationID, Provider: connectorProvider, Connection: connection, + RawSettings: datadogRawSettings, }, ) if err != nil { @@ -293,35 +328,11 @@ func handleConnectorComplete( } } - // Datadog returns the customer's API domain as a `domain` - // query parameter on the callback (CompleteWithState has - // already validated it by building the token URL from it). - // Re-validate defensively, reverse-map to the site key, and - // persist both on the connector settings. - if connectorProvider == coredata.ConnectorProviderDatadog { - domain := query.Get("domain") - if !connector.IsValidDatadogDomain(domain) { - logger.WarnCtx(r.Context(), "rejecting invalid datadog domain", - log.String("provider", string(connectorProvider)), - ) - httpserver.RenderError(w, http.StatusBadRequest, fmt.Errorf("invalid domain")) - - return - } - - region, _ := connector.DatadogSiteForDomain(domain) - raw, err := json.Marshal(&coredata.DatadogConnectorSettings{ - Region: region, - Domain: domain, - }) - if err != nil { - logger.ErrorCtx(r.Context(), "cannot marshal datadog settings", log.Error(err)) - httpserver.RenderError(w, http.StatusInternalServerError, fmt.Errorf("internal error")) - - return - } - - createReq.RawSettings = raw + // Datadog's per-customer settings were captured and validated + // above (the same block also feeds the reconnect path); apply + // them to the create request. + if datadogRawSettings != nil { + createReq.RawSettings = datadogRawSettings } cnnctr, err = svc.Connectors.Create(r.Context(), scope, createReq)