diff --git a/apps/dev-playground/.env.dist b/apps/dev-playground/.env.dist index cfb516d1..135da823 100644 --- a/apps/dev-playground/.env.dist +++ b/apps/dev-playground/.env.dist @@ -6,7 +6,7 @@ NODE_ENV='development' OTEL_EXPORTER_OTLP_ENDPOINT='http://localhost:4318' OTEL_RESOURCE_ATTRIBUTES='service.sample_attribute=dev' OTEL_SERVICE_NAME='dev-playground' -LAKEBASE_ENDPOINT='' # Format: projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} +LAKEBASE_ENDPOINT='' # Run: databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} — use the `name` field from the output PGHOST= PGUSER= PGDATABASE=databricks_postgres diff --git a/docs/docs/api/appkit/Function.generateDatabaseCredential.md b/docs/docs/api/appkit/Function.generateDatabaseCredential.md index 01c7755d..616b4e5e 100644 --- a/docs/docs/api/appkit/Function.generateDatabaseCredential.md +++ b/docs/docs/api/appkit/Function.generateDatabaseCredential.md @@ -29,10 +29,10 @@ https://docs.databricks.com/aws/en/oltp/projects/authentication ## Examples ```typescript -// Format: projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} -// Note: Use actual IDs from Databricks (project-id is a UUID) +// Use the `name` field from the Databricks CLI output: +// `databricks postgres list-endpoints projects/{project-id}/branches/{branch-id}` const credential = await generateDatabaseCredential(workspaceClient, { - endpoint: "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0" + endpoint: "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}" }); // Use credential.token as password @@ -44,9 +44,10 @@ const conn = await pg.connect({ ``` ```typescript -// Format: projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} +// Use the `name` field from the Databricks CLI output: +// `databricks postgres list-endpoints projects/{project-id}/branches/{branch-id}` const credential = await generateDatabaseCredential(workspaceClient, { - endpoint: "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0", + endpoint: "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}", claims: [{ permission_set: RequestedClaimsPermissionSet.READ_ONLY, resources: [{ table_name: "catalog.schema.users" }] diff --git a/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest.md b/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest.md index 766a82cc..259995cd 100644 --- a/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest.md +++ b/docs/docs/api/appkit/Interface.GenerateDatabaseCredentialRequest.md @@ -32,19 +32,14 @@ When specified, the token will only grant access to the specified tables. endpoint: string; ``` -Endpoint resource path with IDs assigned by Databricks. - -All segments are IDs from Databricks (not names you create): -- project-id: UUID format (e.g., `a1b2c3d4-e5f6-4789-a012-b3c4d5e6f789`) -- branch-id: Identifier from Databricks (e.g., `main`, `dev`) -- endpoint-id: Identifier from Databricks (e.g., `primary`, `analytics`) - -Format: `projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id}` - -**Important:** Copy from Databricks Lakebase UI - do not construct manually. +Endpoint resource path. Retrieve using the Databricks CLI: +``` +databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} +``` +Use the `name` field from the output. #### Example ```ts -"projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0" +"projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}" ``` diff --git a/docs/docs/api/appkit/Interface.LakebasePoolConfig.md b/docs/docs/api/appkit/Interface.LakebasePoolConfig.md index 19610a9a..3f40f302 100644 --- a/docs/docs/api/appkit/Interface.LakebasePoolConfig.md +++ b/docs/docs/api/appkit/Interface.LakebasePoolConfig.md @@ -26,12 +26,11 @@ optional endpoint: string; Endpoint resource path for OAuth token generation. -All segments are IDs assigned by Databricks (not names you create): -- project-id: UUID format (e.g., `a1b2c3d4-e5f6-4789-a012-b3c4d5e6f789`) -- branch-id: Identifier from Databricks (e.g., `main`, `dev`) -- endpoint-id: Identifier from Databricks (e.g., `primary`, `analytics`) - -Format: `projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id}` +Retrieve the value using the Databricks CLI: +``` +databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} +``` +Use the `name` field from the output. Required for OAuth authentication (unless password is provided) Can also be set via LAKEBASE_ENDPOINT environment variable @@ -39,7 +38,7 @@ Can also be set via LAKEBASE_ENDPOINT environment variable #### Example ```ts -"projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0" +"projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}" ``` *** diff --git a/packages/lakebase/README.md b/packages/lakebase/README.md index 4db37421..1d1d8162 100644 --- a/packages/lakebase/README.md +++ b/packages/lakebase/README.md @@ -31,11 +31,25 @@ Set the following environment variables: ```bash export PGHOST=your-lakebase-host.databricks.com export PGDATABASE=your_database_name -export LAKEBASE_ENDPOINT=projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} -export PGUSER=your-service-principal-id +export LAKEBASE_ENDPOINT=projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-broad-pine-y12n6gnv/endpoints/ep-summer-frost-y131l3vx +export PGUSER=your_user # optionally, defaults to DATABRICKS_CLIENT_ID export PGSSLMODE=require ``` +To find your `LAKEBASE_ENDPOINT`, run the Databricks CLI and use the `name` field from the output: + +```bash +databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} +``` + +You can obtain the Project ID and Branch ID from the Lakebase Autoscaling UI, like the "Branch Overview" page. (Project list -> Project dashboard -> Branch overview). When using the driver as a part of Databricks Apps, the `LAKEBASE_ENDPOINT` is automatically injected using `fromValue`: + +```yaml +env: + - name: LAKEBASE_ENDPOINT + valueFrom: database # Lakebase Autoscaling database resource name +``` + Then use the driver: ```typescript @@ -52,11 +66,11 @@ console.log(result.rows); import { createLakebasePool } from "@databricks/lakebase"; const pool = createLakebasePool({ - host: "your-lakebase-host.databricks.com", - database: "your_database_name", + host: "your-lakebase-host.databricks.com", // defaults to PGHOST environment variable + database: "your_database_name", // defaults to PGDATABASE environment variable endpoint: - "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id}", - user: "service-principal-id", // Optional, defaults to DATABRICKS_CLIENT_ID + "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-broad-pine-y12n6gnv/endpoints/ep-summer-frost-y131l3vx", // defaults to LAKEBASE_ENDPOINT environment variable + user: "user_id", // Optional, defaults to PGUSER or DATABRICKS_CLIENT_ID max: 10, // Connection pool size }); ``` @@ -66,10 +80,10 @@ const pool = createLakebasePool({ The driver supports Databricks authentication via: 1. **Default auth chain** (`.databrickscfg`, environment variables) -2. **Service principal** (`DATABRICKS_CLIENT_ID` + `DATABRICKS_CLIENT_SECRET`) -3. **OAuth tokens** (via Databricks SDK) +2. **OAuth tokens** (via Databricks SDK) +3. **Native Postgres password authentication** -See [Databricks authentication docs](https://docs.databricks.com/en/dev-tools/auth/index.html) for configuration. +See [Databricks authentication docs](https://docs.databricks.com/en/dev-tools/auth/index.html) or [Lakebase Autoscaling authentication docs](https://docs.databricks.com/aws/en/oltp/projects/authentication#overview) for more information. ## Configuration diff --git a/packages/lakebase/src/credentials.ts b/packages/lakebase/src/credentials.ts index 2e3c84bd..231b92a3 100644 --- a/packages/lakebase/src/credentials.ts +++ b/packages/lakebase/src/credentials.ts @@ -19,10 +19,10 @@ import type { * * @example * ```typescript - * // Format: projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} - * // Note: Use actual IDs from Databricks (project-id is a UUID) + * // Use the `name` field from the Databricks CLI output: + * // `databricks postgres list-endpoints projects/{project-id}/branches/{branch-id}` * const credential = await generateDatabaseCredential(workspaceClient, { - * endpoint: "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0" + * endpoint: "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}" * }); * * // Use credential.token as password @@ -35,9 +35,10 @@ import type { * * @example With UC table permissions * ```typescript - * // Format: projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} + * // Use the `name` field from the Databricks CLI output: + * // `databricks postgres list-endpoints projects/{project-id}/branches/{branch-id}` * const credential = await generateDatabaseCredential(workspaceClient, { - * endpoint: "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0", + * endpoint: "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}", * claims: [{ * permission_set: RequestedClaimsPermissionSet.READ_ONLY, * resources: [{ table_name: "catalog.schema.users" }] diff --git a/packages/lakebase/src/pool.ts b/packages/lakebase/src/pool.ts index a586a74b..1ca6c254 100644 --- a/packages/lakebase/src/pool.ts +++ b/packages/lakebase/src/pool.ts @@ -30,10 +30,10 @@ import type { LakebasePoolConfig } from "./types"; * * @example With explicit configuration * ```typescript - * // Format: projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id} - * // Note: Use actual IDs from Databricks (project-id is a UUID) + * // Use the `name` field from the Databricks CLI output: + * // `databricks postgres list-endpoints projects/{project-id}/branches/{branch-id}` * const pool = createLakebasePool({ - * endpoint: 'projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0', + * endpoint: 'projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}', * host: 'ep-abc.databricks.com', * database: 'databricks_postgres', * user: 'service-principal-id' diff --git a/packages/lakebase/src/types.ts b/packages/lakebase/src/types.ts index 0e930397..18e51e15 100644 --- a/packages/lakebase/src/types.ts +++ b/packages/lakebase/src/types.ts @@ -60,17 +60,16 @@ export interface LakebasePoolConfig extends PoolConfig { /** * Endpoint resource path for OAuth token generation. * - * All segments are IDs assigned by Databricks (not names you create): - * - project-id: UUID format (e.g., `a1b2c3d4-e5f6-4789-a012-b3c4d5e6f789`) - * - branch-id: Identifier from Databricks (e.g., `main`, `dev`) - * - endpoint-id: Identifier from Databricks (e.g., `primary`, `analytics`) - * - * Format: `projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id}` + * Retrieve the value using the Databricks CLI: + * ``` + * databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} + * ``` + * Use the `name` field from the output. * * Required for OAuth authentication (unless password is provided) * Can also be set via LAKEBASE_ENDPOINT environment variable * - * @example "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0" + * @example "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}" */ endpoint?: string; @@ -184,18 +183,13 @@ export interface RequestedClaims { */ export interface GenerateDatabaseCredentialRequest { /** - * Endpoint resource path with IDs assigned by Databricks. - * - * All segments are IDs from Databricks (not names you create): - * - project-id: UUID format (e.g., `a1b2c3d4-e5f6-4789-a012-b3c4d5e6f789`) - * - branch-id: Identifier from Databricks (e.g., `main`, `dev`) - * - endpoint-id: Identifier from Databricks (e.g., `primary`, `analytics`) - * - * Format: `projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-id}` - * - * **Important:** Copy from Databricks Lakebase UI - do not construct manually. + * Endpoint resource path. Retrieve using the Databricks CLI: + * ``` + * databricks postgres list-endpoints projects/{project-id}/branches/{branch-id} + * ``` + * Use the `name` field from the output. * - * @example "projects/6bef4151-4b5d-4147-b4d0-c2f4fd5b40db/branches/br-sparkling-tree-y17uj7fn/endpoints/ep-restless-pine-y1ldaht0" + * @example "projects/{project-id}/branches/{branch-id}/endpoints/{endpoint-identifier}" */ endpoint: string;