feat(cloudbees): Operations Center + Feature Management enterprise support - #468
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughThis PR adds CloudBees Operations Center and Feature Management platform support to Aurora's CloudBees CI integration. New API clients enable discovery of managed controllers and querying of flag changes across deployments. Extended RCA actions support cross-controller incident investigation and optional feature-flag correlation. A new multi-step auth flow and platform credential routes support enterprise deployments. ChangesCloudBees Enterprise Platform Integration
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 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 `@server/chat/backend/agent/tools/cloudbees_rca_tool.py`:
- Around line 157-171: The code returns a field named "warnings" mapped from the
variable error after calling oc_client.query_recent_builds_across_controllers,
which is confusing; update this by either changing the client's return name or
mapping the returned error value to a clearer local name before building the
JSON. Specifically, modify the call/response handling around
query_recent_builds_across_controllers (the tuple currently unpacked as success,
builds, error) so that the third element is named warnings (or warnings_list)
and use that when returning {"builds": builds, "count": len(builds),
"time_window_hours": time_window_hours, "warnings": warnings}, or alternatively
change the client function signature to return (success, builds, warnings)
consistently; keep oc_client.close() in the finally block unchanged.
In `@server/connectors/cloudbees_connector/fm_client.py`:
- Around line 81-89: The retry branch after receiving a 429 does not update the
rate limiter state, so update _last_request_time (or call _rate_limit_wait())
after the successful retry to reflect the retry's timestamp; specifically, in
the block around the second client.request (the retry using
client.request(method=method, url=url, params=params)), ensure you update the
module/class attribute _last_request_time (or invoke _rate_limit_wait())
immediately after the retry response is obtained and before returning or
proceeding, and preserve existing 429 handling (i.e., still return the same
error if the retry is 429).
In `@server/connectors/cloudbees_connector/oc_client.py`:
- Around line 175-231: The time_window_hours parameter in
query_recent_builds_across_controllers is unused; filter builds by timestamp
before returning them. After collecting builds into all_builds (and before
sorting), compute a cutoff = current_time_ms - time_window_hours * 3600 * 1000
and keep only builds where build.get("timestamp", 0) >= cutoff; ensure you
handle None/missing timestamps by excluding them, preserve existing
controller/job annotations (_controller, _job), and then sort and return as
before (using MAX_CONTROLLERS and MAX_BUILDS_PER_CONTROLLER unchanged).
In `@server/routes/cloudbees/cloudbees_routes.py`:
- Around line 366-368: The code returns the raw error from
oc_client.discover_controllers() directly in the HTTP response (the error
variable used in jsonify), which can leak sensitive info; change the response to
sanitize or replace the error with a safe message (e.g., "Failed to discover
controllers") and log the original error internally using the existing logger
before returning the generic message. Update the block that checks success from
oc_client.discover_controllers() to: log the original error
(logger.error/exception with the error variable), set a sanitized_error
string/fallback, and return jsonify({"connected": True, "controllers": [],
"error": sanitized_error}), 502 instead of returning the raw error.
- Around line 268-270: The handler currently returns the raw error from
oc_client.get_server_info() (variables success, error, user_id); change it to
use the same safe_errors whitelist logic used in the /connect route: if error is
in safe_errors return that message to the client, otherwise return a generic
"Failed to validate Operations Center credentials" message while keeping the
full error in the server log via logger.warning; ensure you reference the
safe_errors set and apply the check before building the jsonify response.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 6bf9f2d1-257b-425e-8746-5503dea60749
📒 Files selected for processing (6)
server/chat/backend/agent/tools/cloudbees_rca_tool.pyserver/connectors/cloudbees_connector/__init__.pyserver/connectors/cloudbees_connector/fm_client.pyserver/connectors/cloudbees_connector/oc_client.pyserver/connectors/cloudbees_connector/platform_client.pyserver/routes/cloudbees/cloudbees_routes.py
There was a problem hiding this comment.
Actionable comments posted: 6
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
client/src/hooks/use-github-status.ts (1)
120-120:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winRemove dead cleanup code for non-existent
focusevent listener.Line 120 removes a
focusevent listener that is never added in this effect (lines 114-116 show onlyproviderStateChanged,message, andvisibilitychangeare registered). This cleanup is dead code left from incomplete refactoring.🧹 Proposed fix
return () => { window.removeEventListener('providerStateChanged', handleProviderChange); window.removeEventListener('message', handleAuthMessage); - window.removeEventListener('focus', checkStatus); document.removeEventListener('visibilitychange', handleVisibility); };🤖 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 `@client/src/hooks/use-github-status.ts` at line 120, The cleanup in the effect contains a stale call removing a 'focus' listener that is never added; remove the dead window.removeEventListener('focus', checkStatus) line and ensure the effect's cleanup only unregisters the actual listeners that were registered (e.g., providerStateChanged, the message handler, and 'visibilitychange') so that removeEventListener targets match the corresponding addEventListener calls in use-github-status (look for the providerStateChanged and checkStatus/message handler registrations).client/src/components/github-provider-integration.tsx (1)
314-321:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftFix GitHub metadata regeneration/pending UX (no-op polling still called)
In
client/src/components/github-provider-integration.tsx(lines 314-321),startMetadataPollingimmediately returns after clearingpollingRef(disabled polling). It’s still invoked:
- from
loadSavedRepos(around line 329) after fetching selections- from
handleRegenerate(around line 551) after settingmetadata_status: 'generating'Since the
/repo-metadata/generateendpoint enqueues async work and only updatesconnected_repos.metadata_statusin the DB, the client never re-fetchesrepo-selectionsto transition repometadata_statusfrompending/generatingtoready—so users will likely see “Generating description…” until they manually refresh/reconnect.Either re-enable a lightweight revalidation/polling for GitHub (like the GitLab connect page does), or remove
startMetadataPollingand its call sites and update the UI to reflect that only manual refresh will show completion. Also keep theissue#471`` rationale scoped to dev-only if that’s truly the intent.🤖 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 `@client/src/components/github-provider-integration.tsx` around lines 314 - 321, startMetadataPolling currently clears pollingRef then returns, so callers (startMetadataPolling invoked from loadSavedRepos and handleRegenerate) never revalidate repo selections after triggering repo-metadata/generate, leaving connected_repos.metadata_status stuck in pending/generating; either re-enable a lightweight revalidation loop or remove the no-op and update callers/UI. Fix: modify startMetadataPolling to implement a lightweight polling/revalidation (e.g., setInterval that fetches repo selections every N seconds and clears itself when no repos are pending) or delete startMetadataPolling and remove its invocations in loadSavedRepos and handleRegenerate and ensure the UI for metadata_status explicitly indicates manual refresh is required; reference startMetadataPolling, loadSavedRepos, handleRegenerate, and connected_repos.metadata_status to locate changes and keep the issue `#471` dev-only rationale if you retain a disabled path.server/routes/cloudbees/cloudbees_routes.py (1)
344-350:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPAT/Bearer connections are misreported as disconnected in
/platform-status.Line 345 requires
username, but PAT mode intentionally stores OC credentials with an empty username. Valid bearer connections will showconnected: false.Suggested fix
- if oc_creds and oc_creds.get("base_url") and oc_creds.get("username") and oc_creds.get("api_token"): + if oc_creds and oc_creds.get("base_url") and oc_creds.get("api_token"): + auth_mode = (oc_creds.get("auth_mode") or "basic").lower() + has_required_identity = auth_mode == "bearer" or bool(oc_creds.get("username")) + if not has_required_identity: + return jsonify({ + "operations_center": {"connected": False}, + "feature_management": fm_status, + }) oc_status = { "connected": True, "url": oc_creds["base_url"], "username": oc_creds["username"], }🤖 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 `@server/routes/cloudbees/cloudbees_routes.py` around lines 344 - 350, The code is incorrectly requiring a non-empty username for OC PAT/bearer auth, causing valid bearer connections to appear disconnected; update the condition that builds oc_status (where oc_creds is returned from get_token_data(CLOUDBEES_OC_PROVIDER)) to consider the credentials "connected" when base_url and api_token are present even if username is empty, and populate oc_status["username"] using oc_creds.get("username") (which may be None or empty) rather than gate connection on it; keep using oc_creds["base_url"] and oc_creds["api_token"] for validation so bearer/PAT users are reported connected.
♻️ Duplicate comments (1)
server/connectors/cloudbees_connector/oc_client.py (1)
208-264:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
time_window_hoursis still ignored in cross-controller queries.Line 209 accepts
time_window_hours, but returned builds are never filtered by cutoff before sorting/return. This causes stale build data in enterprise RCA results.Suggested fix
+from datetime import datetime, timedelta, timezone ... # Sort by timestamp descending + if time_window_hours > 0: + cutoff_ms = int( + (datetime.now(timezone.utc) - timedelta(hours=time_window_hours)).timestamp() * 1000 + ) + all_builds = [ + b for b in all_builds + if isinstance(b.get("timestamp"), (int, float)) and b.get("timestamp", 0) >= cutoff_ms + ] + all_builds.sort(key=lambda b: b.get("timestamp", 0), reverse=True)🤖 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 `@server/connectors/cloudbees_connector/oc_client.py` around lines 208 - 264, query_recent_builds_across_controllers currently accepts time_window_hours but never applies it; compute a cutoff (e.g., cutoff_ms = int(time.time() * 1000) - time_window_hours * 3600 * 1000) and filter all_builds to only include builds with build.get("timestamp", 0) >= cutoff_ms before sorting/returning; ensure time is imported (or use time.time()) and keep the filtering step just prior to the existing sort to avoid changing job/build-fetch logic inside get_controller_client/list_builds.
🤖 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 `@client/src/app/cloudbees/auth/components/CloudBeesAuthPage.tsx`:
- Around line 109-111: The fetch response mapping in the CloudBeesAuthPage
component is using the wrong path; update the handler for
fetch("/api/cloudbees/status?full=true") so it checks and uses d?.summary (not
d?.status?.summary") when calling setSummary, i.e. replace the nested status
access with the top-level summary in the .then callback that currently invokes
setSummary.
- Around line 336-343: The success UI is shown even when the PUT to
/api/cloudbees/rca-settings fails because non-2xx responses aren't checked;
update the fetch handling in the CloudBeesAuthPage component to inspect the
fetch response (e.g., response.ok) after the await
fetch("/api/cloudbees/rca-settings", ...) call and only call
setRcaEnabled(checked) and toast(...) when the response is OK; if not OK, throw
or handle the error and show an error toast instead so the toggle UI doesn't
reflect an unpersisted change.
- Around line 144-145: Replace the generic CustomEvent("providerStateChanged")
dispatches with the CloudBees-specific event required by the connector contract:
dispatch new Event("cloudBeesStateChanged") (use Event, not CustomEvent). Update
each dispatch site in CloudBeesAuthPage.tsx where window.dispatchEvent(new
CustomEvent("providerStateChanged")) is called so they instead call
window.dispatchEvent(new Event("cloudBeesStateChanged")), ensuring disconnect
and status revalidation emit the provider-specific event name.
In `@client/src/hooks/use-github-status.ts`:
- Around line 111-116: Remove the no-op visibility handler and its registration:
delete the empty handleVisibility function and the
document.addEventListener('visibilitychange', handleVisibility) line so no
unused listener is attached; ensure only the remaining listeners
(window.addEventListener('providerStateChanged', handleProviderChange') and
window.addEventListener('message', handleAuthMessage') remain unchanged to
preserve behavior.
In `@server/connectors/cloudbees_connector/oc_client.py`:
- Around line 73-97: The current host-comparison in the controller validation
(variables oc_host, ctrl_host, oc_domain, ctrl_domain) is insecure because it
simply joins trailing labels and can be bypassed (e.g., co.uk or IP octet
suffixes); replace this heuristic with a robust check: parse both hosts, treat
IP literals separately by using ipaddress.ip_address and require exact IP
equality for IPs, and for domain names use a public suffix list-based extraction
(e.g., tldextract or publicsuffix2) to get the registrable/registered domain for
self.base_url and controller_url and compare those registered domains for
equality; ensure you raise the same ValueError when they do not match and keep
the invalid-URL guard for empty ctrl_host.
In `@server/routes/cloudbees/cloudbees_routes.py`:
- Around line 270-274: The CloudBeesOCClient created in the route handlers
(instances in the CloudBeesOCClient creation blocks and used to call
get_server_info and similar methods around lines shown) are never closed; update
the handlers to ensure the client is always closed after use by wrapping usage
in a try/finally (or using the client's context manager if it implements
__enter__/__exit__) and call the client's close method (e.g., oc_client.close())
in the finally block; apply the same pattern to the other route path(s) where
CloudBeesOCClient is constructed (also the block around the other occurrence
noted) so connections/file descriptors are released under error and normal
execution.
---
Outside diff comments:
In `@client/src/components/github-provider-integration.tsx`:
- Around line 314-321: startMetadataPolling currently clears pollingRef then
returns, so callers (startMetadataPolling invoked from loadSavedRepos and
handleRegenerate) never revalidate repo selections after triggering
repo-metadata/generate, leaving connected_repos.metadata_status stuck in
pending/generating; either re-enable a lightweight revalidation loop or remove
the no-op and update callers/UI. Fix: modify startMetadataPolling to implement a
lightweight polling/revalidation (e.g., setInterval that fetches repo selections
every N seconds and clears itself when no repos are pending) or delete
startMetadataPolling and remove its invocations in loadSavedRepos and
handleRegenerate and ensure the UI for metadata_status explicitly indicates
manual refresh is required; reference startMetadataPolling, loadSavedRepos,
handleRegenerate, and connected_repos.metadata_status to locate changes and keep
the issue `#471` dev-only rationale if you retain a disabled path.
In `@client/src/hooks/use-github-status.ts`:
- Line 120: The cleanup in the effect contains a stale call removing a 'focus'
listener that is never added; remove the dead
window.removeEventListener('focus', checkStatus) line and ensure the effect's
cleanup only unregisters the actual listeners that were registered (e.g.,
providerStateChanged, the message handler, and 'visibilitychange') so that
removeEventListener targets match the corresponding addEventListener calls in
use-github-status (look for the providerStateChanged and checkStatus/message
handler registrations).
In `@server/routes/cloudbees/cloudbees_routes.py`:
- Around line 344-350: The code is incorrectly requiring a non-empty username
for OC PAT/bearer auth, causing valid bearer connections to appear disconnected;
update the condition that builds oc_status (where oc_creds is returned from
get_token_data(CLOUDBEES_OC_PROVIDER)) to consider the credentials "connected"
when base_url and api_token are present even if username is empty, and populate
oc_status["username"] using oc_creds.get("username") (which may be None or
empty) rather than gate connection on it; keep using oc_creds["base_url"] and
oc_creds["api_token"] for validation so bearer/PAT users are reported connected.
---
Duplicate comments:
In `@server/connectors/cloudbees_connector/oc_client.py`:
- Around line 208-264: query_recent_builds_across_controllers currently accepts
time_window_hours but never applies it; compute a cutoff (e.g., cutoff_ms =
int(time.time() * 1000) - time_window_hours * 3600 * 1000) and filter all_builds
to only include builds with build.get("timestamp", 0) >= cutoff_ms before
sorting/returning; ensure time is imported (or use time.time()) and keep the
filtering step just prior to the existing sort to avoid changing job/build-fetch
logic inside get_controller_client/list_builds.
🪄 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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: dbdd80f0-6a98-4e52-9a20-a7f066b715b6
⛔ Files ignored due to path filters (1)
client/public/cloudbees.svgis excluded by!**/*.svg
📒 Files selected for processing (14)
client/src/app/api/cloudbees/connect-platform/route.tsclient/src/app/api/cloudbees/controllers/route.tsclient/src/app/api/cloudbees/platform-status/route.tsclient/src/app/cloudbees/auth/components/CloudBeesAuthPage.tsxclient/src/app/cloudbees/auth/page.tsxclient/src/components/github-provider-integration.tsxclient/src/hooks/use-github-status.tsserver/chat/backend/agent/skills/integrations/cloudbees/SKILL.mdserver/chat/backend/agent/skills/integrations/cloudbees_oc/SKILL.mdserver/chat/backend/agent/tools/cloud_tools.pyserver/chat/background/prediscovery_task.pyserver/connectors/cloudbees_connector/oc_client.pyserver/routes/cloudbees/cloudbees_routes.pywebsite/docs/integrations/cloudbees.md
Backend: - Use 'with' for OC/FM client context managers in RCA tool - Remove unused 'time' import - Update rate limit tracking after 429 retry - Use time_window_hours parameter in cross-controller query - Sanitize error messages in routes (no internal hostnames) - Close OC clients properly in routes - Strengthen domain matching (prevent evil-company.com bypass) Frontend: - Remove unused imports (Button, Badge, router) - Fix status summary mapping - Dispatch providerStateChanged after connect - Only toast RCA toggle success on actual success - Remove empty visibility handler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…e support - CloudBeesOCClient: discovers managed controllers, queries across them - CloudBeesFMClient: queries feature flag changes for incident correlation - CloudBeesPlatformClient: orchestration layer combining OC + FM - Enhanced RCA tool: new actions (flag_changes, cross_controller_deployments, controller_list) - New routes: /connect-platform, /platform-status, /controllers, /disconnect-platform - Graceful degradation: missing credentials return helpful messages, not errors - Additive: existing single-controller flow completely unchanged Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Path injection: URL-encode app_id/flag_name in FM client - SSRF: validate controller URLs match OC domain before sending creds - Resource leak: add context manager support + close() in action handlers - Remove trace_context delegation to wrong provider - Add single retry on FM 429 responses - Cache platform_status instead of hitting FM API every call - Sanitize error messages from OC (no raw exceptions to caller) - Validate URL schemes (require http/https) - Guard against empty app_id in flag_changes action Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three connection modes in one clean flow: - Single Controller: direct Jenkins/CloudBees CI connection (existing) - Operations Center: multi-controller management with controller discovery - Personal Access Token: platform-level auth for organizations using PATs Optional Feature Management section under OC mode for flag correlation. Displays discovered controllers after successful OC connection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Critical fixes: - Field name alignment: frontend now sends oc_url/api_token/fm_api_token (matches backend) - PAT mode: backend now supports Bearer token auth when username is empty - OC client: supports both Basic Auth and Bearer token modes - Disconnect: removes both single-controller AND platform credentials - Controllers: fetched on page load from /controllers endpoint - Connect response: includes discovered controllers list Other fixes: - Client-side URL scheme validation (http/https only) - 0 controllers: shows guidance message instead of dead-end - Clear all form fields on disconnect - Remove trace_context from tool description (action doesn't exist) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove all Card wrappers and bordered containers - Mode picker: divider-separated list with hover arrows - Forms: transparent inputs, rounded-xl, generous spacing - Connected: minimal data display with status dots - Feature management: collapsible <details> instead of card section - Matches sign-in page typography and spacing philosophy - No decorative elements, trusts the content Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- SKILL.md: document enterprise actions (flag_changes, cross_controller_deployments, controller_list) - Add cloudbees_oc skill entry for SkillRegistry detection - SSRF: relax validation to allow sibling subdomains (same registrable domain) - Prediscovery: add OC exploration instructions to prompt - MCP: verify cloudbees_rca is available via MCP tool registry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Covers all three connection modes (Single Controller, Operations Center, PAT), webhook setup, RCA actions (standard + enterprise), feature flag correlation, and auto-trigger configuration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Complete redesign as a multi-step wizard: - Step 1: Choose connection mode (OC, Single, PAT) with descriptive cards - Step 2: Enter credentials with inline instruction box - Step 3: Webhook setup with copy-able URL and Jenkinsfile snippet - Connected: Controller list + 'what happens next' section - Progress bar tracks position through the flow - Full max-w-2xl width, generous spacing, no cramped forms Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… webhook, deployments) Connected state is now a full dashboard: - 4-column stats grid (jobs, nodes, executors, queue) - Job health bar with colored segments + legend - RCA auto-trigger toggle switch - Webhook URL with copy + Jenkinsfile snippet (collapsible) - Recent deployments list with status dots - Controllers list (OC mode) - All in the same dark minimal aesthetic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Refs #471 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ctions - Removed all trace_context references (action no longer exists) - Flag_changes: explicitly states 'only call if FM is connected + have app_id' - cross_controller_deployments: only if OC is connected - Prevents agent from calling actions that will always error Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…DBEES Hidden by default (.env.example=false). Set NEXT_PUBLIC_ENABLE_CLOUDBEES=true to show. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Backend: - Use 'with' for OC/FM client context managers in RCA tool - Remove unused 'time' import - Update rate limit tracking after 429 retry - Use time_window_hours parameter in cross-controller query - Sanitize error messages in routes (no internal hostnames) - Close OC clients properly in routes - Strengthen domain matching (prevent evil-company.com bypass) Frontend: - Remove unused imports (Button, Badge, router) - Fix status summary mapping - Dispatch providerStateChanged after connect - Only toast RCA toggle success on actual success - Remove empty visibility handler Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9823bad to
e5e5617
Compare
|
All 6 fixed in 51075be. To test locally: set NEXT_PUBLIC_ENABLE_CLOUDBEES=true in .env and recreate frontend. |
Was missing from docker-compose.yaml (make dev), not just docker-compose.prod-local.yml. Without this, the flag never reaches the frontend container regardless of .env settings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Code review (follow-up)Re-reviewed after the two fix commits. The PAT-mode username gate, the missing
aurora/server/chat/backend/agent/tools/cloudbees_rca_tool.py Lines 143 to 150 in 61cb050 aurora/server/connectors/cloudbees_connector/fm_client.py Lines 129 to 139 in 61cb050
aurora/client/src/app/cloudbees/auth/components/CloudBeesAuthPage.tsx Lines 86 to 93 in 61cb050 aurora/server/routes/cloudbees/cloudbees_routes.py Lines 119 to 123 in 61cb050
aurora/server/chat/backend/agent/tools/cloudbees_rca_tool.py Lines 50 to 59 in 61cb050
aurora/client/docker-entrypoint.sh Lines 18 to 28 in 61cb050 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
- is_cloudbees_connected now checks OC/PAT creds (not just legacy single-controller) - _get_oc_client_for_user passes auth_mode, fixing PAT users unable to use RCA - Add debug logging for incomplete credentials in RCA tool - Add NEXT_PUBLIC_ENABLE_CLOUDBEES to env.ts EnvKey type - Replace magic number 5 with MAX_BUILDS_PER_CONTROLLER constant - Use context managers (with) for OC and FM clients in connect-platform route - Validate response.ok before setting webhook info state - Replace presentational <label> elements with <p> for accessibility - Document PAT mode capabilities in integration docs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Break the 1012-line monolith into focused presentational components: - ModeSelector (step 1): connection mode selection - CredentialForms (step 2): OC, single controller, and PAT forms - WebhookSetup (step 3): webhook URL display and Jenkinsfile snippet - ConnectedDashboard: stats, job health, RCA toggle, deployments, controllers Parent retains all state, effects, and handler logic. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without this, the CloudBees integration doesn't appear in prod/docker deployments because env-config.js never gets the variable injected at container startup. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Strip username from localStorage cache (only store connected + baseUrl) - Replace all raw fetch() calls with apiRequest for consistent auth/error handling - Replace brittle domain heuristic with tldextract for controller URL validation - Add separate MAX_JOBS_PER_CONTROLLER constant (50) for job iteration limit - Validate app_id is present before calling flag_changes action - Fix naive datetime comparison in fm_client (ensure tz-aware, catch TypeError) - Add tldextract to requirements.txt Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TypeScript: - Number.isNaN instead of isNaN - Mark all component props as Readonly - Replace array index keys with stable identifiers - Extract nested ternary into variable - Use globalThis instead of window - Use optional chaining (result?.controllers?.length) - Extract nested template literal Python: - Fix NOSONAR comment syntax (remove trailing colon) - Replace unused variables with _ - Use logger.exception instead of logger.error in except blocks - Reduce cognitive complexity in connect_platform (extract _validate_and_store_fm) - Reduce cognitive complexity in discover_controllers (extract _fetch_controller_data, _parse_controller_response) - Reduce cognitive complexity in query_recent_builds (extract _query_single_controller) - Reduce cognitive complexity in get_recent_flag_changes (extract _is_recently_modified, _parse_timestamp) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use NEXT_PUBLIC_BACKEND_URL + NGROK_URL fallback pattern (same as Dynatrace) instead of the non-standard BACKEND_URL. Setting NGROK_URL once now works for all connectors in local OSS dev. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make tldextract import lazy with fallback to simple suffix matching so the app doesn't crash if the package isn't installed yet - Merge the two status calls into one: use /status?full=true directly instead of calling getStatus() then status?full=true separately, cutting Jenkins round trips in half on dashboard load Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- _verify_webhook_user: check both cloudbees and cloudbees_oc providers (was returning 403 for OC-only users) - connect-platform: generate webhook_secret for OC credentials (was storing empty secret, making webhook URL snippet useless) - _get_stored_cloudbees_credentials: fall through to cloudbees_oc when legacy cloudbees provider not found - _build_client: handle bearer/PAT auth mode, instantiate OC client when username is empty - cloudbees_rca_tool: fall through to OC client when legacy client unavailable for single-controller actions - CSS: change styled-jsx to global scope so animate-step-in reaches child components (ModeSelector, CredentialForms, etc.) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CloudBees OC/PAT parity check (00520c5)Verified the "make OC/PAT a first-class citizen" change. The connection / webhook / deployment / auto-RCA / tool-registration layer is now genuinely at parity for OC/PAT. One real gap remains. Deep build-introspection breaks for pure OC/PAT users. The single-controller action fallthrough hands a aurora/server/chat/backend/agent/tools/cloudbees_rca_tool.py Lines 189 to 192 in 00520c5 Those helpers call aurora/server/chat/backend/agent/tools/jenkins_rca_tool.py Lines 176 to 180 in 00520c5
aurora/server/connectors/cloudbees_connector/oc_client.py Lines 135 to 156 in 00520c5 For a user with no legacy Minor (non-blocking):
aurora/server/routes/cloudbees/cloudbees_routes.py Lines 153 to 172 in 00520c5
aurora/server/routes/cloudbees/cloudbees_routes.py Lines 492 to 499 in 00520c5 🤖 Generated with Claude Code |
For OC-only users, build_detail/pipeline_stages/stage_log/build_logs/ test_results/blue_ocean actions now require a controller_url parameter. The agent must first call controller_list or cross_controller_deployments to discover controller URLs, then pass the relevant one. Previously these actions passed a CloudBeesOCClient to JenkinsClient-shaped helpers, causing AttributeError on every call. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ars) Both branches added feature flags to the same locations — keep both NEXT_PUBLIC_ENABLE_CLOUDBEES and NEXT_PUBLIC_ENABLE_BITBUCKET_OAUTH. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The connected-accounts endpoint returns provider keys exactly as stored in user_tokens (cloudbees_oc, cloudbees_fm). The frontend connector card checks for "cloudbees". Added a UI alias map so these sub-providers register under the unified "cloudbees" key in the response. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…T cards show Connected
|



Summary
Enhances the CloudBees connector from a simple Jenkins reskin to full enterprise support with Operations Center multi-controller management and Feature Management flag correlation.
What's new
Operations Center Client
Feature Management Client
Enhanced RCA Tool — 3 new actions
flag_changes— "show me recent feature flag toggles that might correlate with this incident"cross_controller_deployments— "what deployed across all controllers in the last 4 hours?"controller_list— "what controllers are managed by this Operations Center?"New routes
POST /connect-platform— connect OC + FM credentialsGET /platform-status— check what's connectedGET /controllers— list discovered controllersPOST /disconnect-platform— remove platform credentialsArchitecture
Security hardening (from review)
app_id/flag_nameURL-encoded viaurllib.parse.quoteBackwards compatibility
/connect, all existing RCA actions) completely unchangeduser_tokenstable with new provider names)Test plan
flag_changesaction — verify flag data returnedcross_controller_deployments— verify cross-controller aggregation🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation