Repository navigation
fix(ri-exchange): resolve Azure credentials via per-subscription resolver - #934
Conversation
…lver buildAzureExchangeClient was calling azidentity.NewDefaultAzureCredential directly. In Lambda there is no ambient Azure identity so credential construction fails and the handler returns a 500, surfaced on the RI Exchange page as "Failed to load Azure reservations: Internal server error". Replace with credentials.ResolveAzureTokenCredentialWithOpts scoped to the registered CloudAccount whose ExternalID matches the requested subscription_id, mirroring the exact pattern used by scheduler.collectAzureForAccount and purchase/execution.go resolveAzureProvider. The Handler's wired credStore, signer, and issuerURL are forwarded so managed_identity, client_secret, and WIF auth modes all work correctly. Error classification: DB/credential failures are server-side faults (5xx); no matching CloudAccount is a graceful empty state (not an error) so the page shows "no reservations" instead of an opaque 500 banner when Azure is not configured for the tenant. Closes #932
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR refactors Azure credential resolution in the RI exchange handler to use per-subscription ChangesAzure RI Exchange Credential Resolution
Sequence DiagramsequenceDiagram
participant Handler as listExchangeableAzureRIs
participant ClientBuilder as buildAzureExchangeClient
participant ConfigStore as CloudAccount Lookup
participant CredResolver as ResolveAzureTokenCredentialWithOpts
participant ARMClient as armreservations.ClientFactory
Handler->>ClientBuilder: ctx, subscriptionID
ClientBuilder->>ConfigStore: GetCloudAccountByExternalID("azure", subscriptionID)
alt Account found
ConfigStore-->>ClientBuilder: CloudAccount
ClientBuilder->>CredResolver: Resolve credentials with signer/issuer
alt Credentials resolved
CredResolver-->>ClientBuilder: Azure token credential
ClientBuilder->>ARMClient: Create reservations client
ARMClient-->>ClientBuilder: Client
ClientBuilder-->>Handler: Client, nil error
Handler->>ARMClient: List reservations
else Credential resolution fails
CredResolver-->>ClientBuilder: Error
ClientBuilder-->>Handler: nil, wrapped error
Handler->>Handler: Return error
end
else No account registered
ConfigStore-->>ClientBuilder: nil, nil
ClientBuilder-->>Handler: nil, nil
Handler->>Handler: Return empty Reservations list
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Summary
azidentity.NewDefaultAzureCredentialinbuildAzureExchangeClientwithcredentials.ResolveAzureTokenCredentialWithOpts, scoped to the registeredCloudAccountwhoseExternalIDmatches the requestedsubscription_idquery param.scheduler.collectAzureForAccountandpurchase/execution.go resolveAzureProvider— no new auth path invented.CloudAccountis registered for the requested subscription, the handler returns an empty reservations list rather than an opaque 500.Closes #932
Test plan
go build ./internal/api/...passesgo test ./internal/api/... -run "TestListExchangeableAzureRIs|TestBuildAzureExchangeClient"— all 10 tests pass (5 pre-existing + 5 new)go test ./internal/api/... ./internal/credentials/...— 1483 tests passgofmt -lproduces no output on touched filesgo vet ./internal/api/...produces no outputNew tests cover: no Azure account registered (graceful empty), empty subscription with no accounts, DB lookup error (5xx, not 4xx), credential resolution failure (5xx), resolver called with correct (provider, subscriptionID) arguments.
Summary by CodeRabbit
Bug Fixes
Tests