MCPcopy Index your code
hub / github.com/cloudquery/cloudquery / MaybeInjectDestination

Function MaybeInjectDestination

cli/internal/platform/inject.go:280–358  ·  view source on GitHub ↗

MaybeInjectDestination injects a `platform` destination carrying a freshly minted cqpd_ token — but only when the spec opts in by listing `platform` in a source's `destinations`. If the user already declares a `platform` destination themselves (e.g. for debugging), theirs is used as-is. With no opt-

(ctx context.Context, logger zerolog.Logger, token, teamName string, sources []*specs.Source, destinations []*specs.Destination)

Source from the content-addressed store, hash-verified

278// destination themselves (e.g. for debugging), theirs is used as-is. With no
279// opt-in, or on any credential/tenant failure, the spec is returned unchanged.
280func MaybeInjectDestination(ctx context.Context, logger zerolog.Logger, token, teamName string, sources []*specs.Source, destinations []*specs.Destination) ([]*specs.Destination, error) {
281 if os.Getenv(envDisable) == "1" {
282 return destinations, nil
283 }
284 if env.IsCloud() {
285 return destinations, nil
286 }
287
288 // Opt-in only: inject solely when a source targets the platform destination.
289 // No source references it → nothing to do (no cloud calls, no surprise
290 // dual-write).
291 if !anySourceTargetsPlatform(sources) {
292 return destinations, nil
293 }
294 // The user defined the `platform` destination themselves (debugging/override)
295 // — respect it, don't inject over it.
296 if hasPlatformDestination(destinations) {
297 return destinations, nil
298 }
299
300 // Direct token: a pre-minted cqpd_ token supplied via env (CQ_PLATFORM_TOKEN
301 // or a cqpd_ in CLOUDQUERY_API_KEY) injects the destination without cloud
302 // login, tenant discovery or a session mint — the token already identifies
303 // the tenant and carries its API URL.
304 if t := platformToken(); t != "" {
305 // Recommended plugin version: the env override wins (so skip the lookup),
306 // otherwise ask the platform's whoami so the headless flow pins the right
307 // version — the non-headless path gets this from the session mint instead.
308 recommendedVersion := ""
309 if os.Getenv(envPluginVersion) == "" {
310 recommendedVersion = recommendedVersionFromWhoami(ctx, logger, t)
311 }
312 // No tenant id: the direct path doesn't parse the token's claims.
313 return injectPlatformDestination(logger, destinations, sources, t, recommendedVersion, ""), nil
314 }
315
316 // The caller only fetches a token for cloudquery-registry specs; resolve
317 // directly so source-only specs can still inject. Failure just skips.
318 if token == "" {
319 var err error
320 if token, teamName, err = resolveCredentials(ctx); err != nil {
321 logger.Debug().Err(err).Msg("platform destination: credentials unavailable, skipping auto-injection")
322 return destinations, nil
323 }
324 }
325 if token == "" || teamName == "" {
326 return destinations, nil
327 }
328
329 cl, err := api.NewClient(token)
330 if err != nil {
331 logger.Debug().Err(err).Msg("platform destination: api client init failed, skipping auto-injection")
332 return destinations, nil
333 }
334
335 tenants, err := activeTenants(ctx, cl, teamName)
336 if err != nil {
337 logger.Debug().Err(err).Msg("platform destination: tenant discovery failed, skipping auto-injection")

Calls 9

anySourceTargetsPlatformFunction · 0.85
hasPlatformDestinationFunction · 0.85
platformTokenFunction · 0.85
activeTenantsFunction · 0.85
resolveTenantFunction · 0.85
mintSessionFunction · 0.85
StringMethod · 0.45