Skip to content
This repository was archived by the owner on Mar 11, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion env-tests-logging
38 changes: 34 additions & 4 deletions src/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,25 @@ export function getCloudFunctionDescriptor() {
};
}

/**
* Create a descriptor for Cloud Run.
*
* @returns {object}
*/
export async function getCloudRunDescriptor() {
const qualifiedZone = await gcpMetadata.instance('zone');
const location = zoneFromQualifiedZone(qualifiedZone);
return {
type: 'cloud_run_revision',
labels: {
location,
service_name: process.env.K_SERVICE,
revision_name: process.env.K_REVISION,
configuration_name: process.env.K_CONFIGURATION,
},
};
}

/**
* Create a descriptor for Google App Engine.
*
Expand Down Expand Up @@ -146,7 +165,6 @@ export function getGlobalDescriptor() {
*/
export async function getDefaultResource(auth: GoogleAuth) {
const env = await auth.getEnv();

switch (env) {
case GCPEnv.KUBERNETES_ENGINE:
return getGKEDescriptor().catch(() => getGlobalDescriptor());
Expand All @@ -155,9 +173,14 @@ export async function getDefaultResource(auth: GoogleAuth) {
case GCPEnv.CLOUD_FUNCTIONS:
return getCloudFunctionDescriptor();
case GCPEnv.COMPUTE_ENGINE:
// Test for compute engine should be done after all the rest -
// everything runs on top of compute engine.
return getGCEDescriptor().catch(() => getGlobalDescriptor());
// Google Cloud Run
if (process.env.K_CONFIGURATION) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason it doesn't follow a similar pattern as the rest of them? GCPEnv.CLOUD_RUN?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GCPEnv from google-auth-library detects cloudrun as compute_engine. So I look for the K_CONFIG envvar unique to cloud run within this switch case

Also I just filed issue for this in google-auth-lib here: googleapis/google-auth-library-nodejs#1155

return getCloudRunDescriptor().catch(() => getGlobalDescriptor());
} else {
// Test for compute engine should be done after all the rest -
// everything runs on top of compute engine.
return getGCEDescriptor().catch(() => getGlobalDescriptor());
}
default:
return getGlobalDescriptor();
}
Expand Down Expand Up @@ -190,6 +213,13 @@ export async function detectServiceContext(
// name from within the pod.
case GCPEnv.KUBERNETES_ENGINE:
case GCPEnv.COMPUTE_ENGINE:
// Google Cloud Run
if (process.env.K_CONFIGURATION) {
return {
service: process.env.K_SERVICE,
};
}
return null;
default:
return null;
}
Expand Down
111 changes: 110 additions & 1 deletion test/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ describe('metadata', () => {
let AUTH;
const ENV_CACHED = extend({}, process.env);

const INITIAL_ENV: {[key: string]: string | undefined} = {};

before(() => {
metadata = proxyquire('../src/metadata', {
'gcp-metadata': fakeGcpMetadata,
Expand Down Expand Up @@ -101,7 +103,6 @@ describe('metadata', () => {
'K_SERVICE',
'GOOGLE_CLOUD_REGION',
];
const INITIAL_ENV: {[key: string]: string | undefined} = {};

before(() => {
for (const key of TARGET_KEYS) {
Expand Down Expand Up @@ -152,6 +153,56 @@ describe('metadata', () => {
});
});

describe('getCloudRunDescriptor', () => {
const K_SERVICE = 'hello-world';
const K_REVISION = 'hello-world.1';
const K_CONFIGURATION = 'hello-world';
Comment on lines +157 to +159
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's make the values similar to actual ones.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the official documentation on the sample values. https://cloud.google.com/run/docs/reference/container-contract


const TARGET_KEYS = ['K_SERVICE', 'K_REVISION', 'K_CONFIGURATION'];

before(() => {
for (const key of TARGET_KEYS) {
INITIAL_ENV[key] = process.env[key];
}
});

after(() => {
for (const key of TARGET_KEYS) {
const val = INITIAL_ENV[key];
if (val === undefined) {
delete process.env[key];
} else {
process.env[key] = val;
}
}
});

beforeEach(() => {
for (const key of TARGET_KEYS) {
delete process.env[key];
}
process.env.K_SERVICE = K_SERVICE;
process.env.K_REVISION = K_REVISION;
process.env.K_CONFIGURATION = K_CONFIGURATION;
});

it('should return the correct descriptor', async () => {
const ZONE_ID = 'cyrodiil-anvil-2';
const ZONE_FULL = `projects/fake-project/zones/${ZONE_ID}`;
instanceOverride = {path: 'zone', successArg: ZONE_FULL};
const descriptor = await metadata.getCloudRunDescriptor();
assert.deepStrictEqual(descriptor, {
type: 'cloud_run_revision',
labels: {
service_name: K_SERVICE,
revision_name: K_REVISION,
configuration_name: K_CONFIGURATION,
location: ZONE_ID,
},
});
});
});

describe('getGAEDescriptor', () => {
const GAE_MODULE_NAME = 'gae-module-name';
const GAE_SERVICE = 'gae-service';
Expand Down Expand Up @@ -302,6 +353,47 @@ describe('metadata', () => {
});
});

describe('cloud run', () => {
after(() => {
delete process.env['K_CONFIGURATION'];
delete process.env['K_REVISION'];
delete process.env['K_SERVICE'];
});

it('should return correct descriptor', async () => {
const K_SERVICE = 'hello-world';
const K_CONFIGURATION = 'hello-world';
const K_REVISION = 'hello-world.1';
const ZONE_ID = 'cyrodiil-anvil-2';
const ZONE_FULL = `projects/fake-project/zones/${ZONE_ID}`;
process.env.K_SERVICE = K_SERVICE;
process.env.K_REVISION = K_REVISION;
process.env.K_CONFIGURATION = K_CONFIGURATION;
instanceOverride = [
{
path: 'zone',
successArg: ZONE_FULL,
},
];
const fakeAuth = {
async getEnv() {
return GCPEnv.COMPUTE_ENGINE;
},
};

const defaultResource = await metadata.getDefaultResource(fakeAuth);
assert.deepStrictEqual(defaultResource, {
type: 'cloud_run_revision',
labels: {
service_name: K_SERVICE,
revision_name: K_REVISION,
configuration_name: K_CONFIGURATION,
location: ZONE_ID,
},
});
});
});

describe('compute engine', () => {
it('should return correct descriptor', async () => {
const INSTANCE_ID = 1234567;
Expand Down Expand Up @@ -458,6 +550,23 @@ describe('metadata', () => {
assert.deepStrictEqual(sc1, {service: FUNCTION_NAME});
});

it('should return the correct descriptor for Cloud Run', async () => {
process.env.K_CONFIGURATION = 'hello-world';
const SERVICE_NAME = (process.env.K_SERVICE = 'hello-world');

const fakeAuth = {
async getEnv() {
return GCPEnv.COMPUTE_ENGINE;
},
};

const sc1 = await metadata.detectServiceContext(fakeAuth);
assert.deepStrictEqual(sc1, {service: SERVICE_NAME});

delete process.env['K_CONFIGURATION'];
delete process.env['K_SERVICE'];
});

it('should return null on GKE', async () => {
const fakeAuth = {
async getEnv() {
Expand Down