Repository navigation
Conversation
…e registry The purchase and scheduler credentialed paths called the concrete Azure and GCP constructors directly, and the Azure path pinned the subscription through the deprecated ProviderConfig.Profile field. Add a small internal/providerfactory package that builds these providers through the cloud-commitments-go provider registry, using the typed AzureSubscriptionID/GCPProjectID fields and the AzureTokenCredential/ GCPTokenSource credential slots, and use it at those four call sites. The registry-built providers are identical to the legacy ones (tests compare them field by field against the real registered factories). One deliberate difference: NewGCP rejects an empty project ID instead of letting the registry's GCP factory ask the cloud for the credential's default project. A guard test fails if any non-test file under cmd/ or internal/ calls the concrete constructors again or sets ProviderConfig.Profile. The RI exchange handler's concrete AWS/Azure imports are left for a follow-up. Refs LeanerCloud#41 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Comment |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
First slice of the ARCH-12 cleanup. It is meant to change no behavior.
Root cause
The credentialed Azure and GCP paths in
internal/purchase/execution.go(resolveAzureProvider,resolveGCPProvider) andinternal/scheduler/scheduler.go(collectAzureForAccount,collectGCPForAccount) skipped the cloud-commitments-go provider registry. They called the concrete constructors directly:azureprovider.NewAzureProvider(&provider.ProviderConfig{Profile: sub})+SetCredential(cred), andgcpprovider.NewProviderWithCredentials(ctx, project, ts). The Azure path also pinned the subscription through the deprecatedProviderConfig.Profilefield.The pinned
pkg/providerregistry can already take credentials.ProviderConfighas typedAzureSubscriptionID/GCPProjectIDfields andAzureTokenCredential/GCPTokenSourceslots, and the registeredazure/gcpfactories (NewAzureProvider/NewProvider) install them. So the fix needs no change in cloud-commitments-go.Fix
internal/providerfactorypackage:NewAzure(subscriptionID, cred)andNewGCP(projectID, ts)build the provider withRegistry.GetProviderWithConfig. They use only the typed fields and credential slots, neverProfile.purchase/execution.gono longer imports the concrete Azure/GCP provider packages. The scheduler still imports them forIsPermissionError/AsPartialSubscriptionFailure.cmd/orinternal/setsProviderConfig.Profile. That clears the platform-side blocker to removing the field in cloud-commitments-go.Behavior notes (please review)
SetCredential(nil).ctxwhile the registry factory storescontext.Background(), but the GCP provider never reads that field.NewGCPrejects an empty project ID (and a nil token source) before calling the registry. The registry's GCP factory resolves an empty project ID with a livegetDefaultProjectlookup. The direct constructor never made that lookup, and it could pin the provider to a project other than the account's. The scheduler refuses an unpinned Azure account for the same reason.gcp_project_idgot a provider forprojects/that failed on first use.create provider: providerfactory: GCP project ID is required. On the purchase path the message iscredentials: create GCP provider for account ….Refs #41
Verification
Unit and fixture evidence only. The tests use fake credentials and token sources. No test calls a real cloud API, and constructing the providers makes no network calls.
Tests added (
internal/providerfactory/):TestNewAzure_PassesTypedConfigToRegistryandTestNewGCP_PassesTypedConfigToRegistryuse a private registry with recording fake factories. They check that the factory is called once withName, the typed ID field and the same credential instance (assert.Same). They also check thatProfileandProviderOverrideare unset.TestNewAzure_NilCredentialLeavesSlotNil,TestNewGCP_RejectsMissingInputsBeforeRegistry(the factory is never called) andTestBuild_PropagatesFactoryErrorsAndNilProviders.TestNewAzure_MatchesLegacyConstructionandTestNewGCP_MatchesLegacyConstructionbuild the provider both ways with the real registered factories and compare the whole structs. The Azure test first callsInvalidateAccountsCache()on the new provider, to match the cache-generation bump that legacySetCredentialmakes. Negative cases (a different credential, subscription or project) show the comparison isn't vacuous.TestNoRegistryBypassInProductionCodeis an AST guard. It fails if any non-test.gofile undercmd/orinternal/refers to the concrete Azure/GCP constructors or puts aProfilekey in aprovider.ProviderConfigliteral.Fail-before / pass-after:
Guard test: run against main's
execution.goandscheduler.go, it fails with 6 violations:execution.go:549NewAzureProvider + Profileexecution.go:583NewProviderWithCredentialsscheduler.go:912NewAzureProvider + Profilescheduler.go:980NewProviderWithCredentialsIt passes on this branch.
Mutation probes on the helper: each of these makes at least one test fail, and the equivalence tests catch all of them except the
Profileswap:Profileinstead ofAzureSubscriptionIDCombined-tree verification. This branch was tested together with the other queued branches on a local, never-pushed tree:
queue/platform@b56afb2b= origin/maina14dc8f2plus these heads, merged in this order:fix/issue-324andfix/issue-204both edit.github/workflows/ci.ymlnext to theazure-kv-access-policyjob. The tree kept #324's new "Run Function URL reader self-tests" step and #204's updated job comment; whichever PR merges second takes that same resolution.Linux, Go 1.26.9,
AWS_CONFIG_FILE=/dev/null AWS_SHARED_CREDENTIALS_FILE=/dev/null AWS_EC2_METADATA_DISABLED=true; Docker Postgres via testcontainers. The full suite ran oned0c7174, which differs fromb56afb2bonly by one.gitallowedline on fix/issue-324:go build ./...,go vet ./...,go vet -tags integration ./...and the fullgo test -race -short -count=1 ./....--build-tags integration.gocyclo -over 10is silent on the changed non-test files.-tags integration -count=1, 60-minute local timeout):internal/api,internal/purchase,internal/schedulerandinternal/serverall pass..gitallowedline. Re-run atb56afb2b: git-secrets, using the repo'sscripts/setup-git-secrets.shpatterns in a fresh repo with an isolated HOME, found nothing in the changed files, and a planted fake key was flagged.scripts/test-git-secrets-allowlist.sh: 137 PASS, 0 FAIL.Out of scope (left for follow-ups under #41)
internal/api/handler_ri_exchange.gostill imports the concrete AWS/Azure packages (providers/aws,providers/aws/recommendations,providers/aws/services/ec2,providers/azure/services/compute). Moving exchange operations onto a capability interface, or into one composition file, is a bigger change. Several in-flight branches also touch that file, so it's deferred.ProviderConfig.Profilefield itself lives in cloud-commitments-go (pkg/provider/interface.go). Removing it, along with theresolveAzureSubscriptionID/resolveGCPProjectIDfallbacks, is a go-side change. The platform no longer sets the field, so that change is unblocked here.purchasestill passes the built provider asProviderConfig.ProviderOverrideintoCreateAndValidateProvider, as before. Passing the typed config straight to the factory there would move construction to purchase time, so it is left unchanged.Maintainer: please mirror the issue's triage labels on this PR:
impact/internal,type/chore,triaged,priority/p3,severity/low,urgency/eventually,effort/m.🤖 Generated with Claude Code