-
Notifications
You must be signed in to change notification settings - Fork 1.2k
test(functions): failing repro tests for declarative security managed SA bugs #10858
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -670,6 +670,31 @@ describe("Fabricator", () => { | |
| expect(gcfv2.deleteFunction).to.have.been.called; | ||
| }); | ||
|
|
||
| it("retries function creation when a freshly created service account has not yet propagated (BUG: currently fails immediately)", async () => { | ||
| // GCF returns HTTP 404 when the deploy references a service account that | ||
| // was created moments ago and has not propagated through IAM yet. | ||
| const saNotFoundErr = new Error( | ||
| "Service account projects/-/serviceAccounts/firebase-fn-123@test-project.iam.gserviceaccount.com was not found. Please verify that the caller has iam.serviceAccounts.actAs permission on the service account.", | ||
| ); | ||
| (saNotFoundErr as any).status = 404; | ||
|
Comment on lines
+676
to
+679
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using const saNotFoundErr = new Error(\n "Service account projects/-/serviceAccounts/firebase-fn-123@test-project.iam.gserviceaccount.com was not found. Please verify that the caller has iam.serviceAccounts.actAs permission on the service account."\n ) as Error & { status?: number };\n saNotFoundErr.status = 404;References
|
||
| gcfv2.createFunction.onFirstCall().rejects(saNotFoundErr); | ||
| gcfv2.createFunction.resolves({ name: "op", done: false }); | ||
| poller.pollOperation.resolves({ serviceConfig: { service: "service" } }); | ||
| run.setInvokerCreate.resolves(); | ||
|
|
||
| // Use the same executor type as a real deploy (release/index.ts) so that | ||
| // retry-code based mitigations are exercised too, with fast backoff. | ||
| const queueFab = new fabricator.Fabricator({ | ||
| ...ctorArgs, | ||
| functionExecutor: new executor.QueueExecutor({ retries: 3, backoff: 1, maxBackoff: 10 }), | ||
| }); | ||
|
|
||
| const ep = endpoint({ httpsTrigger: {} }, { platform: "gcfv2" }); | ||
| await queueFab.createV2Function(ep, new scraper.SourceTokenScraper()); | ||
|
|
||
| expect(gcfv2.createFunction).to.have.been.calledTwice; | ||
| }); | ||
|
|
||
| it("throws on set invoker failure", async () => { | ||
| gcfv2.createFunction.resolves({ name: "op", done: false }); | ||
| poller.pollOperation.resolves({ serviceConfig: { service: "service" } }); | ||
|
|
@@ -2071,6 +2096,26 @@ describe("Fabricator", () => { | |
| ); | ||
| }); | ||
|
|
||
| it("waits for a newly created service account to be visible before returning from grantNewRoles (BUG: no propagation check)", async () => { | ||
| // IAM service account creation is eventually consistent. grantNewRoles | ||
| // should poll getServiceAccount until the new SA is visible before the | ||
| // deploy proceeds to create functions that actAs it. | ||
| const getServiceAccountStub = sinon.stub(iam, "getServiceAccount").resolves({ | ||
| name: "projects/test-project/serviceAccounts/firebase-fn-123@my-proj.iam.gserviceaccount.com", | ||
| email: "firebase-fn-123@my-proj.iam.gserviceaccount.com", | ||
| } as any); | ||
|
Comment on lines
+2103
to
+2106
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using const getServiceAccountStub = sinon.stub(iam, "getServiceAccount").resolves({\n name: "projects/test-project/serviceAccounts/firebase-fn-123@my-proj.iam.gserviceaccount.com",\n projectId: "test-project",\n uniqueId: "123",\n email: "firebase-fn-123@my-proj.iam.gserviceaccount.com",\n displayName: "",\n etag: "",\n description: "",\n oauth2ClientId: "",\n disabled: false,\n });References
|
||
| const plan: planner.CodebasePlan = { | ||
| regionalChangesets: {}, | ||
| serviceAccountToCreate: "firebase-fn-123@my-proj.iam.gserviceaccount.com", | ||
| managedServiceAccount: "firebase-fn-123@my-proj.iam.gserviceaccount.com", | ||
| }; | ||
|
|
||
| await fab.grantNewRoles(plan, "default"); | ||
|
|
||
| expect(createServiceAccountStub).to.have.been.called; | ||
| expect(getServiceAccountStub).to.have.been.called; | ||
| }); | ||
|
|
||
| it("should remove roles or delete SA in removeOldRoles", async () => { | ||
| const plan: planner.CodebasePlan = { | ||
| regionalChangesets: {}, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the fix for reusing existing managed service accounts is implemented,
discoverSecurityDetailswill likely calliam.getServiceAccountto check if the SA already exists in the project. Sinceiam.getServiceAccountis not stubbed in thebeforeEachblock ofdescribe("discoverSecurityDetails"), all other tests in this suite that calldiscoverSecurityDetailswill attempt to make real API calls and fail.\n\nTo prevent this, stubiam.getServiceAccountin thebeforeEachblock to reject with a404error by default, representing the happy path where the SA does not yet exist.