Google Cloud Spanner 请求在另一个项目上启用

Google Cloud Spanner requests enabling on a different project

这是我的代码:

// vim:ft=javascript:

const {Spanner} = require('@google-cloud/spanner');
const spanner = new Spanner({projectId: 'gcp-in-action-317405'});

const instance = spanner.instance('test-instance');
const database = instance.database('test-database');
const employees = database.table('employees');

employees.insert([
  {employee_id: 1, name: 'Steve Jobs', start_date: '1976-04-01'},
  {employee_id: 2, name: 'Bill Gates', start_date: '1975-04-04'},
  {employee_id: 3, name: 'Larry Page', start_date: '1976-04-01'}
]).then((date) => {
  console.log('Saved data!', data);
});

代码 运行s 然后退出并出现以下错误:

(node:24310) UnhandledPromiseRejectionWarning: Error: 7 PERMISSION_DENIED: Cloud Spanner API has not been used in project 84555343487 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/spanner.googleapis.com/overview?project=84555343487 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
    at Object.callErrorFromStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
    at listener.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:80:35)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/grpc-gcp/build/src/index.js:73:29)
    at InterceptingListenerImpl.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:75:23)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
    at process.nextTick (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78)
    at process._tickCallback (internal/process/next_tick.js:61:11)
(node:24310) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:24310) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
(node:24310) UnhandledPromiseRejectionWarning: Error: 7 PERMISSION_DENIED: Cloud Spanner API has not been used in project 84555343487 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/spanner.googleapis.com/overview?project=84555343487 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.
    at Object.callErrorFromStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call.js:31:26)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client.js:179:52)
    at listener.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:80:35)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/grpc-gcp/build/src/index.js:73:29)
    at InterceptingListenerImpl.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:75:23)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:336:141)
    at Object.onReceiveStatus (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:299:181)
    at process.nextTick (/usr/local/lib/node_modules/@google-cloud/spanner/node_modules/@grpc/grpc-js/build/src/call-stream.js:145:78)
    at process._tickCallback (internal/process/next_tick.js:61:11)
(node:24310) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)

有关更多上下文,这里是 gcloud projects list 的输出:

PROJECT_ID                  NAME           PROJECT_NUMBER
gcp-in-action-317405        GCP in Action  827217411854
qibla-finder-1507320565537  Qibla Finder   84555343487

显然我想与“GCP in Action”(827217411854) 进行交互,但 Google Cloud 认为我正在与“Qibla Finder”(84555343487) 打交道,我已经有好几年没有开发它了年。在有人问之前,我已经确定 运行 gcloud config set project gcp-in-action-317405。如何将 Spanner 指向正确的方向?

您似乎正在使用应用程序默认凭据 (GOOGLE_APPLICATION_CREDENTIALS=/path/to/some.key) 来验证您的代码。

我怀疑您正在使用的密钥属于 qibla-finder-1507320565537 拥有的服务帐户,并且当您的代码进行调用时,正在检查拥有项目的 API (并且未在其中启用)。

您可能想在 gcp-in-action-317405 中创建一个新的服务帐户,为其赋予 Spanner 等适当的角色,并使用它验证您的代码。

NOTE You may grant the existing Service Account access to Spanner in a different project but you'll still then need to enable the API in qibla-finder-1507320565537

更新:如何创建服务帐户

使用 gcloud 您可以创建一个服务帐户,授予它合适的角色,创建一个密钥并导出密钥:

PROJECT=gcp-in-action-317405
ACCOUNT=spanner-user

EMAIL=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com

# Create Service Account
gcloud iam service-accounts create ${ACCOUNT} \
--display-name="Spanner User" \
--description="Used by code to interact with Spanner" \
--project=${PROJECT}

# Grant Service Account Database User role
# https://cloud.google.com/spanner/docs/iam#roles
gcloud projects add-iam-policy-binding ${PROJECT} \
--member=serviceAccount:${EMAIL} \
--role=roles/spanner.databaseUser

# Generate a key for this Service Account
gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
--iam-account=${EMAIL} \
--project=${PROJECT}

# Use Application Default Credentials
export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json

# Run your code