feat: add Parseable Cloud API key login#110
Conversation
📝 WalkthroughWalkthroughAdds Parseable Cloud profile creation and login support, extends profile/config data for cloud credentials, centralizes request auth header handling, and updates tail streaming to use cloud-aware metadata. ChangesCloud profile and authentication support
Sequence Diagram(s)sequenceDiagram
participant CloudProfileAddCmd
participant validateCloudAPIKey
participant AddAuthHeaders
participant Orchestrator API
participant saveCloudProfile
participant WriteConfigToFile
CloudProfileAddCmd->>validateCloudAPIKey: validate API key
validateCloudAPIKey->>AddAuthHeaders: set cloud auth headers
AddAuthHeaders-->>validateCloudAPIKey: request headers
validateCloudAPIKey->>Orchestrator API: GET /api/v1/apikey/validate
Orchestrator API-->>validateCloudAPIKey: JSON response
validateCloudAPIKey-->>CloudProfileAddCmd: validation data
CloudProfileAddCmd->>saveCloudProfile: persist profile
saveCloudProfile->>WriteConfigToFile: write config
WriteConfigToFile-->>saveCloudProfile: done
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
cmd/login.go (1)
60-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated cloud-profile construction.
cloudProfileFromAPIKeybuilds aconfig.Profilefrom the validation result identically toCloudProfileAddCmd.RunEincmd/cloud.go(lines 96-105). Consider extracting a single helper (e.g.profileFromValidation(apiKey, orchestratorURL, result)) used by both paths so the field mapping stays in sync.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@cmd/login.go` around lines 60 - 77, The cloud-profile construction logic is duplicated between cloudProfileFromAPIKey and CloudProfileAddCmd.RunE, so extract the shared mapping into a single helper such as profileFromValidation that accepts the apiKey, orchestratorURL, and validation result and returns the config.Profile. Update both call sites to use that helper so the field assignments stay consistent in one place.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@cmd/cloud.go`:
- Around line 184-200: saveCloudProfile currently treats every
ReadConfigFromFile error as an empty config and then writes it back, which can
wipe existing profiles, and it also overwrites an existing profile when the
derived or provided name already exists. Update saveCloudProfile to distinguish
a missing config file from other read errors so non-fatal parse/read failures
are surfaced instead of replacing the config, and add an overwrite check before
assigning fileConfig.Profiles[name]. Use the existing stepConfirmReplace pattern
from the interactive login flow to warn or confirm when a profile name collision
would replace an existing entry, then only call WriteConfigToFile after the user
has explicitly accepted the overwrite.
- Around line 33-37: The default Cloud orchestrator URL is currently pointing at
the staging endpoint, so `defaultCloudOrchestratorURL` in `cmd/cloud.go` should
be changed to the production orchestrator unless staging is explicitly intended.
Update the default used by the Cloud validation flow, and make sure the
`envCloudOrchestratorURL` override still works so users can opt into a different
endpoint if needed.
In `@cmd/tail.go`:
- Around line 120-132: The tailAuthMetadata helper is missing bearer-token
handling and currently falls back to Basic auth for token-only profiles. Update
tailAuthMetadata to mirror the same auth precedence used by AddAuthHeaders:
handle profile.Token before the Basic fallback, returning an Authorization
header with Bearer <token> when a token is present, while keeping the existing
cloud x-api-key and tenant behavior unchanged.
In `@pkg/config/config.go`:
- Line 101: The config write path in the file-opening logic does not harden
permissions for already-existing files, so broader modes can persist after
writing sensitive values like api_key. Update the config save flow around
os.OpenFile in the config write function to explicitly set restrictive
permissions on the opened file after it is created/opened, using
file.Chmod(0600) or equivalent, so both new and existing config files end up
with 0600.
---
Nitpick comments:
In `@cmd/login.go`:
- Around line 60-77: The cloud-profile construction logic is duplicated between
cloudProfileFromAPIKey and CloudProfileAddCmd.RunE, so extract the shared
mapping into a single helper such as profileFromValidation that accepts the
apiKey, orchestratorURL, and validation result and returns the config.Profile.
Update both call sites to use that helper so the field assignments stay
consistent in one place.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 19834b75-b4c7-47e5-8e5b-cdc99993cf39
📒 Files selected for processing (13)
cmd/cloud.gocmd/login.gocmd/promql.gocmd/queryList.gocmd/tail.gomain.gopkg/config/config.gopkg/datasets/datasets.gopkg/http/http.gopkg/model/login/login.gopkg/model/promql.gopkg/model/query.gopkg/model/savedQueries.go
Summary
Adds Parseable Cloud API key support to
pb.Users can now create a Cloud profile using either:
or interactive login:
Then select Parseable Cloud and paste API key.
What Changed
Added pb cloud profile add
Enabled Parseable Cloud option in interactive pb login
Added cloud-aware profile fields:
Added API key validation through orchestrator:
Added cloud request auth headers:
Kept self-hosted BasicAuth/token profiles backward compatible
Config file writes with 0600 permissions because API key is stored locally
Summary by CodeRabbit
New Features
Bug Fixes
Style