Skip to content

Commit

Permalink
feat: Utilize gcp-metadata's GCP Residency Check (#1513)
Browse files Browse the repository at this point in the history
* feat: utilize `gcp-residency` check

Removes 1 network check for workloads running on GCP

* test: Update tests for gcp residency detection

* refactor: streamline logic and update documentation

* chore: stash

* chore: Update `gcp-metadata`

* refactor: use `getGCPResidency`

* test: Dedup gcp-metadata tests

* fix: await
  • Loading branch information
d-goog authored Jun 29, 2023
1 parent 5e6d6a2 commit 43377ac
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 59 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"ecdsa-sig-formatter": "^1.0.11",
"fast-text-encoding": "^1.0.0",
"gaxios": "^5.0.0",
"gcp-metadata": "^5.2.0",
"gcp-metadata": "^5.3.0",
"gtoken": "^6.1.0",
"jws": "^4.0.0",
"lru-cache": "^6.0.0"
Expand Down
7 changes: 6 additions & 1 deletion src/auth/googleauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,18 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {

/**
* Determines whether the auth layer is running on Google Compute Engine.
* Checks for GCP Residency, then fallback to checking if metadata server
* is available.
*
* @returns A promise that resolves with the boolean.
* @api private
*/
async _checkIsGCE() {
if (this.checkIsGCE === undefined) {
this.checkIsGCE = await gcpMetadata.isAvailable();
this.checkIsGCE =
gcpMetadata.getGCPResidency() || (await gcpMetadata.isAvailable());
}

return this.checkIsGCE;
}

Expand Down
64 changes: 7 additions & 57 deletions test/test.googleauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
SECONDARY_HOST_ADDRESS,
resetIsAvailableCache,
} from 'gcp-metadata';
import * as gcpMetadata from 'gcp-metadata';
import * as nock from 'nock';
import * as os from 'os';
import * as path from 'path';
Expand Down Expand Up @@ -1137,66 +1138,15 @@ describe('googleauth', () => {
assert.strictEqual(undefined, client.scope);
});

it('_checkIsGCE should set the _isGCE flag when running on GCE', async () => {
assert.notStrictEqual(true, auth.isGCE);
const scope = nockIsGCE();
await auth._checkIsGCE();
assert.strictEqual(true, auth.isGCE);
scope.done();
});

it('_checkIsGCE should not set the _isGCE flag when not running on GCE', async () => {
const scope = nockNotGCE();
assert.notStrictEqual(true, auth.isGCE);
await auth._checkIsGCE();
assert.strictEqual(false as boolean, auth.isGCE);
scope.done();
});

it('_checkIsGCE should retry the check for isGCE on transient http errors', async () => {
assert.notStrictEqual(true, auth.isGCE);
// the first request will fail, the second one will succeed
const scopes = [nock500GCE(), nockIsGCE()];
await auth._checkIsGCE();
assert.strictEqual(true, auth.isGCE);
scopes.forEach(s => s.done());
});

it('_checkIsGCE should return false on unexpected errors', async () => {
assert.notStrictEqual(true, auth.isGCE);
const scope = nock500GCE();
assert.strictEqual(await auth._checkIsGCE(), false);
assert.strictEqual(auth.isGCE, false);
scope.done();
});
it("_checkIsGCE should be equalivalent should use GCP metadata's checks", async () => {
nockNotGCE();

it('_checkIsGCE should not retry the check for isGCE if it fails with an ENOTFOUND', async () => {
assert.notStrictEqual(true, auth.isGCE);
const scope = nockNotGCE();
await auth._checkIsGCE();
assert.strictEqual(false as boolean, auth.isGCE);
scope.done();
});

it('_checkIsGCE does not execute the second time when running on GCE', async () => {
// This test relies on the nock mock only getting called once.
assert.notStrictEqual(true, auth.isGCE);
const scope = nockIsGCE();
await auth._checkIsGCE();
assert.strictEqual(true, auth.isGCE);
await auth._checkIsGCE();
assert.strictEqual(true, auth.isGCE);
scope.done();
});
const expected = await (gcpMetadata.getGCPResidency() ||
gcpMetadata.isAvailable());

it('_checkIsGCE does not execute the second time when not running on GCE', async () => {
assert.notStrictEqual(true, auth.isGCE);
const scope = nockNotGCE();
await auth._checkIsGCE();
assert.strictEqual(false as boolean, auth.isGCE);
assert.strict.notEqual(auth.isGCE, true);
await auth._checkIsGCE();
assert.strictEqual(false as boolean, auth.isGCE);
scope.done();
assert.strictEqual(auth.isGCE, expected);
});

it('getCredentials should get metadata from the server when running on GCE', async () => {
Expand Down

0 comments on commit 43377ac

Please sign in to comment.