Skip to content

Commit

Permalink
fix(js/plugins/google-cloud): pass projectId through to GoogleAuth cl…
Browse files Browse the repository at this point in the history
…ient
  • Loading branch information
MichaelDoyle committed Feb 19, 2025
1 parent 3c3c1b6 commit 1687048
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 84 deletions.
34 changes: 22 additions & 12 deletions js/plugins/google-cloud/src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,23 @@ import { GcpPrincipal, GcpTelemetryConfig } from './types.js';
* searches for credential files in standard locations, before using this
* method.
*
* See also: https://github.com/googleapis/google-auth-library-nodejs?tab=readme-ov-file#loading-credentials-from-environment-variables
* @see https://github.com/googleapis/google-auth-library-nodejs?tab=readme-ov-file#loading-credentials-from-environment-variables
*
* @param projectId if provided, will take precendence over projectId from credential
*/
export async function credentialsFromEnvironment(): Promise<
Partial<GcpTelemetryConfig>
> {
export async function credentialsFromEnvironment(
projectId?: string
): Promise<Partial<GcpTelemetryConfig>> {
let authClient: GoogleAuth;
let options: Partial<GcpTelemetryConfig> = {};

if (projectId !== undefined) {
logger.debug(`Using Google Cloud projectId=${projectId}`);
options.projectId = projectId;
}

if (process.env.GCLOUD_SERVICE_ACCOUNT_CREDS) {
logger.debug('Retrieving credentials from GCLOUD_SERVICE_ACCOUNT_CREDS');
logger.debug('Using credentials from GCLOUD_SERVICE_ACCOUNT_CREDS');
const serviceAccountCreds = JSON.parse(
process.env.GCLOUD_SERVICE_ACCOUNT_CREDS
);
Expand All @@ -48,14 +55,15 @@ export async function credentialsFromEnvironment(): Promise<
} else {
authClient = new GoogleAuth();
}

try {
const projectId = await authClient.getProjectId();
if (projectId && projectId.length > 0) {
options.projectId = projectId;
}
options.projectId ||= await authClient.getProjectId();
} catch (error) {
logger.warn(error);
}

logger.debug(`Final projectId=${options.projectId}`);

return options;
}

Expand All @@ -68,8 +76,10 @@ export async function credentialsFromEnvironment(): Promise<
* can be handy to get access to the current credential for logging debugging
* information or other purposes.
**/
export async function resolveCurrentPrincipal(): Promise<GcpPrincipal> {
const envCredentials = await credentialsFromEnvironment();
export async function resolveCurrentPrincipal(
projectId?: string
): Promise<GcpPrincipal> {
const envCredentials = await credentialsFromEnvironment(projectId);
let adcCredentials = {} as CredentialBody;
try {
adcCredentials = await auth.getCredentials();
Expand All @@ -83,7 +93,7 @@ export async function resolveCurrentPrincipal(): Promise<GcpPrincipal> {
envCredentials.credentials?.client_email ?? adcCredentials.client_email;

return {
projectId: envCredentials.projectId,
projectId: projectId ?? envCredentials.projectId,
serviceAccountEmail,
};
}
4 changes: 2 additions & 2 deletions js/plugins/google-cloud/src/gcpLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,10 @@ export class GcpLogger {
transports.push(
this.shouldExport(env)
? new LoggingWinston({
projectId: this.config.projectId,
labels: { module: 'genkit' },
prefix: 'genkit',
logName: 'genkit_log',
projectId: this.config.projectId,
credentials: this.config.credentials,
autoRetry: true,
defaultCallback: await this.getErrorHandler(),
Expand All @@ -80,7 +80,7 @@ export class GcpLogger {
private async getErrorHandler(): Promise<(err: Error | null) => void> {
// only log the first time
let instructionsLogged = false;
let helpInstructions = await loggingDeniedHelpText();
let helpInstructions = await loggingDeniedHelpText(this.config.projectId);

return async (err: Error | null) => {
// Use the defaultLogger so that logs don't get swallowed by
Expand Down
14 changes: 8 additions & 6 deletions js/plugins/google-cloud/src/gcpOpenTelemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,9 @@ export class GcpOpenTelemetry {
spanExporter = new AdjustingTraceExporter(
this.shouldExportTraces()
? new TraceExporter({
// Creds for non-GCP environments; otherwise credentials will be
// automatically detected via ADC
// provided projectId should take precedence over env vars, etc
projectId: this.config.projectId,
// creds for non-GCP environments, in lieu of using ADC.
credentials: this.config.credentials,
})
: new InMemorySpanExporter(),
Expand All @@ -134,7 +135,7 @@ export class GcpOpenTelemetry {
(err) => {
return tracingDenied(err);
},
await tracingDeniedHelpText()
await tracingDeniedHelpText(this.config.projectId)
)
);
return spanExporter;
Expand Down Expand Up @@ -186,15 +187,16 @@ export class GcpOpenTelemetry {
product: 'genkit',
version: GENKIT_VERSION,
},
// Creds for non-GCP environments; otherwise credentials will be
// automatically detected via ADC
// provided projectId should take precedence over env vars, etc
projectId: this.config.projectId,
// creds for non-GCP environments, in lieu of using ADC.
credentials: this.config.credentials,
},
getErrorHandler(
(err) => {
return metricsDenied(err);
},
await metricsDeniedHelpText()
await metricsDeniedHelpText(this.config.projectId)
)
)
: new InMemoryMetricExporter(AggregationTemporality.DELTA);
Expand Down
2 changes: 1 addition & 1 deletion js/plugins/google-cloud/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function enableGoogleCloudTelemetry(
async function configureGcpPlugin(
options?: GcpTelemetryConfigOptions
): Promise<GcpTelemetryConfig> {
const envOptions = await credentialsFromEnvironment();
const envOptions = await credentialsFromEnvironment(options?.projectId);
return {
projectId: options?.projectId || envOptions.projectId,
credentials: options?.credentials || envOptions.credentials,
Expand Down
19 changes: 11 additions & 8 deletions js/plugins/google-cloud/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,19 +155,22 @@ export function metricsDenied(
return requestDenied(err);
}

export async function permissionDeniedHelpText(role: string) {
const principal = await resolveCurrentPrincipal();
export async function permissionDeniedHelpText(
role: string,
projectId?: string
) {
const principal = await resolveCurrentPrincipal(projectId);
return `Add the role '${role}' to your Service Account in the IAM & Admin page on the Google Cloud console, or use the following command:\n\ngcloud projects add-iam-policy-binding ${principal.projectId ?? '${PROJECT_ID}'} \\\n --member=serviceAccount:${principal.serviceAccountEmail || '${SERVICE_ACCT}'} \\\n --role=${role}`;
}

export async function loggingDeniedHelpText() {
return permissionDeniedHelpText('roles/logging.logWriter');
export async function loggingDeniedHelpText(projectId?: string) {
return permissionDeniedHelpText('roles/logging.logWriter', projectId);
}

export async function tracingDeniedHelpText() {
return permissionDeniedHelpText('roles/cloudtrace.agent');
export async function tracingDeniedHelpText(projectId?: string) {
return permissionDeniedHelpText('roles/cloudtrace.agent', projectId);
}

export async function metricsDeniedHelpText() {
return permissionDeniedHelpText('roles/monitoring.metricWriter');
export async function metricsDeniedHelpText(projectId?: string) {
return permissionDeniedHelpText('roles/monitoring.metricWriter', projectId);
}
94 changes: 39 additions & 55 deletions js/testapps/dev-ui-gallery/src/genkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,18 @@ import { devLocalVectorstore } from '@genkit-ai/dev-local-vectorstore';
import { genkitEval, GenkitMetric } from '@genkit-ai/evaluator';
import { enableFirebaseTelemetry } from '@genkit-ai/firebase';
import { gemini15Flash, googleAI } from '@genkit-ai/googleai';
import { textEmbedding004, vertexAI } from '@genkit-ai/vertexai';
import {
vertexAIEvaluation,
VertexAIEvaluationMetricType,
} from '@genkit-ai/vertexai/evaluation';
import {
claude35Sonnet,
claude35SonnetV2,
claude3Haiku,
claude3Opus,
claude3Sonnet,
codestral,
llama31,
llama32,
mistralLarge,
mistralNemo,
vertexAIModelGarden,
} from '@genkit-ai/vertexai/modelgarden';
import { textEmbedding004 } from '@genkit-ai/vertexai';
import { genkit } from 'genkit';
import { logger } from 'genkit/logging';
import { chroma } from 'genkitx-chromadb';
import { ollama } from 'genkitx-ollama';
import { pinecone } from 'genkitx-pinecone';

logger.setLogLevel('info');
logger.setLogLevel('debug');

enableFirebaseTelemetry({
forceDevExport: false,
projectId: 'weather-gen-test-next',
forceDevExport: true,
metricExportIntervalMillis: 5_000,
metricExportTimeoutMillis: 5_000,
autoInstrumentation: true,
Expand Down Expand Up @@ -95,41 +79,25 @@ export const ai = genkit({
],
serverAddress: 'http://127.0.0.1:11434', // default local address
}),
vertexAI({
location: 'us-central1',
}),
vertexAIModelGarden({
location: 'us-central1', // gemini, llama
// location: 'us-east5', // anthropic
models: [
claude35Sonnet,
claude35SonnetV2,
claude3Haiku,
claude3Opus,
claude3Sonnet,
codestral,
llama31,
llama32,
mistralLarge,
mistralNemo,
],
}),
vertexAIEvaluation({
location: 'us-central1',
metrics: [
VertexAIEvaluationMetricType.BLEU,
VertexAIEvaluationMetricType.GROUNDEDNESS,
VertexAIEvaluationMetricType.SAFETY,
{
type: VertexAIEvaluationMetricType.ROUGE,
metricSpec: {
rougeType: 'rougeLsum',
useStemmer: true,
splitSummaries: 'true',
},
},
],
}),
// vertexAI({
// location: 'us-central1',
// }),
// vertexAIModelGarden({
// location: 'us-central1', // gemini, llama
// // location: 'us-east5', // anthropic
// models: [
// claude35Sonnet,
// claude35SonnetV2,
// claude3Haiku,
// claude3Opus,
// claude3Sonnet,
// codestral,
// llama31,
// llama32,
// mistralLarge,
// mistralNemo,
// ],
// }),

// vector stores
chroma([
Expand Down Expand Up @@ -165,5 +133,21 @@ export const ai = genkit({
GenkitMetric.MALICIOUSNESS,
],
}),
// vertexAIEvaluation({
// location: 'us-central1',
// metrics: [
// VertexAIEvaluationMetricType.BLEU,
// VertexAIEvaluationMetricType.GROUNDEDNESS,
// VertexAIEvaluationMetricType.SAFETY,
// {
// type: VertexAIEvaluationMetricType.ROUGE,
// metricSpec: {
// rougeType: 'rougeLsum',
// useStemmer: true,
// splitSummaries: 'true',
// },
// },
// ],
// }),
],
});

0 comments on commit 1687048

Please sign in to comment.