Merge PostHog self-hosted into a single PostHog provider

Fold POSTHOG_SELF_HOSTED into POSTHOG: one provider now covers Cloud (OAuth + region-pinned API key) and self-hosted (API key + instance URL), since both already share the driver, name resolver, and PostHogConnectorSettings{BaseURL}. The API-key form picks a deployment (Cloud US/EU or self-hosted URL); the resolver requires exactly one of region/instanceUrl.

Drop the POSTHOG_SELF_HOSTED enum value, registration, migration, and logo mapping. Extract the deployment selector into a dedicated PostHogDeploymentField component. Point the driver tests at us.posthog.com instead of the legacy app.posthog.com host.

Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
Aurélien Sibiril
2026-06-03 16:03:18 +02:00
parent 760f950a48
commit b4e6f73b78
13 changed files with 203 additions and 198 deletions

View File

@@ -46,7 +46,6 @@ func NewBuiltinRegistry() *Registry {
onePasswordRegistration(),
openaiRegistration(),
posthogRegistration(),
posthogSelfHostedRegistration(),
pagerdutyRegistration(),
resendRegistration(),
sentryRegistration(),

View File

@@ -24,13 +24,15 @@ import (
"go.probo.inc/probo/pkg/coredata"
)
// posthogRegistration is PostHog Cloud (US + EU). OAuth is the preferred
// path: oauth.posthog.com is PostHog's region-agnostic OAuth + API gateway,
// so one app serves both regions and the driver reaches the customer's data
// through it without a per-connection host. An API-key fallback is also
// supported, but personal API keys are region-pinned, so it requires the
// customer to pick their region (us/eu). Self-hosted instances are a separate
// provider (POSTHOG_SELF_HOSTED).
// posthogRegistration is PostHog — Cloud (US + EU) and self-hosted, under one
// provider. OAuth (CIMD public client) is the preferred path for Cloud: the
// region-agnostic oauth.posthog.com gateway handles the handshake for both
// regions, after which the driver resolves the data region (us/eu) itself,
// since that gateway does not serve the data API. An API-key fallback covers
// both deployments: Cloud personal API keys are region-pinned (the customer
// picks us/eu) and self-hosted connections carry an instance URL. Both store a
// single data-host BaseURL; cloud OAuth connections leave it empty for lazy
// region probing.
func posthogRegistration() *Registration {
return &Registration{
Provider: coredata.ConnectorProviderPostHog,
@@ -56,8 +58,13 @@ func posthogRegistration() *Registration {
// token surfaces on the first ListAccounts.
SupportsAPIKey: true,
// API-key connections are either PostHog Cloud (a region, us/eu) or
// self-hosted (an instance URL). The two are mutually exclusive, so
// neither is individually Required; apiKeyConnectorSettings enforces
// that exactly one is supplied.
ExtraSettings: []ExtraSetting{
{Key: "region", Label: "Region", Required: true},
{Key: "region", Label: "Region"},
{Key: "instanceUrl", Label: "Instance URL"},
},
NewDriver: func(_ context.Context, c *http.Client, conn *coredata.Connector, _ *log.Logger) (drivers.Driver, error) {

View File

@@ -1,71 +0,0 @@
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package provider
import (
"context"
"fmt"
"net/http"
"go.gearno.de/kit/log"
"go.probo.inc/probo/pkg/accessreview/drivers"
"go.probo.inc/probo/pkg/coredata"
)
// posthogSelfHostedRegistration is customer-hosted PostHog: API-key plus an
// operator-supplied instance URL (Metabase/Grafana style). It shares the
// PostHog driver and name resolver, pointed at the instance's BaseURL. OAuth
// is deliberately not offered here — a single static authorization URL cannot
// serve arbitrary per-customer instances, so self-hosted OAuth is a separate
// future effort. Cloud PostHog (POSTHOG) owns the OAuth path.
func posthogSelfHostedRegistration() *Registration {
return &Registration{
Provider: coredata.ConnectorProviderPostHogSelfHosted,
DisplayName: "PostHog (Self-Hosted)",
SupportsAPIKey: true,
ExtraSettings: []ExtraSetting{
{Key: "instanceUrl", Label: "Instance URL", Required: true},
},
NewDriver: func(_ context.Context, c *http.Client, conn *coredata.Connector, _ *log.Logger) (drivers.Driver, error) {
s, err := coredata.ConnectorSettings[coredata.PostHogConnectorSettings](conn)
if err != nil {
return nil, fmt.Errorf("cannot read posthog self-hosted connector settings: %w", err)
}
// Never fall back to the cloud gateway for a self-hosted
// connector — the instance URL is required at creation time.
if s.BaseURL == "" {
return nil, fmt.Errorf("cannot create posthog self-hosted driver: instance URL is required")
}
return drivers.NewPostHogDriver(c, s.BaseURL), nil
},
NewNameResolver: func(ctx context.Context, c *http.Client, conn *coredata.Connector, logger *log.Logger) drivers.NameResolver {
s, err := coredata.ConnectorSettings[coredata.PostHogConnectorSettings](conn)
if err != nil {
logger.ErrorCtx(ctx, "cannot read posthog self-hosted connector settings", log.Error(err))
return nil
}
if s.BaseURL == "" {
return nil
}
return drivers.NewPostHogNameResolver(c, s.BaseURL)
},
}
}