问题描述 投票:0回答:1

1-服务帐户创建:我创建了一个服务帐户,并分配了“云任务队列admin”角色(角色/cloudtasks.queueadmin),其中包括cloudtasks.queues.queues.queues.create允许。
2-客户端配置:我在代码中配置了云任务客户端,如下所示:

const { CloudTasksClient } = require('@google-cloud/tasks'); const clientCloudTasks = new CloudTasksClient({ keyFilename: "./serviceAccountKey.json", });

3-队列创建尝试:我尝试使用以下代码创建一个队列: const queuePath = clientCloudTasks.queuePath('my-project-id', 'europe-central2', 'my-queue-id'); const queue = { name: queuePath, rateLimits: { maxDispatchesPerSecond: 1, }, }; const request = { parent: clientCloudTasks.locationPath('my-project-id', 'europe-central2'), queue: queue, }; await clientCloudTasks.createQueue(request);

行为详细信息:

I验证了“云任务队列admin”角色包括
cloudtasks.queues.qureate许可

服务帐户已正确配置,JSON密钥文件为 在代码中正确引用。

指定的项目和位置存在并且正确 引用

问题:

尽管进行了配置,但我为什么会收到此权限错误?
    提前感谢您的帮助!
  • 能够提供最小可重复的例子很有用。
  • 这帮助他人准确了解所做的事情,并可能繁殖(!)您的经验。
  • 重要的是(对于stackoverflow),它为他人提供了更多有用的内容。
  • 要做到这一点,有必要准确记录您的工作(不描述您的工作)。
元,在回答您的问题之后,我重新创建了您的榜样(在Golang,因为我不是Node.js开发人员)。

BILLING="..." Q=79415361 # Required by code export PROJECT="dazwilkin-$(date +%y%m%d)-${Q}" export LOCATION="europe-central2" ACCOUNT="tester" EMAIL=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com ROLE="roles/cloudtasks.queueAdmin" gcloud projects create ${PROJECT} gcloud billing projects link ${PROJECT} \ --billing-account=${BILLING} gcloud iam service-accounts create ${ACCOUNT} \ --project=${PROJECT} gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \ --iam-account=${EMAIL} \ --project=${PROJECT} gcloud services enable cloudtasks.googleapis.com \ --project=${PROJECT} gcloud projects add-iam-policy-binding ${PROJECT} \ --member=serviceAccount:${EMAIL} \ --role=${ROLE} export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json

go.mod

module github.com/DazWilkin/stackoverflow/79415361 go 1.23.1 require ( cloud.google.com/go/cloudtasks v1.13.3 )

google-cloud-platform google-cloud-functions google-iam google-cloud-tasks
1个回答
0
投票
main.go

package main import ( "context" "fmt" "log/slog" "os" "time" cloudtasks "cloud.google.com/go/cloudtasks/apiv2" "cloud.google.com/go/cloudtasks/apiv2/cloudtaskspb" "google.golang.org/api/option" ) func main() { PROJECT := os.Getenv("PROJECT") if PROJECT == "" { panic("PROJECT is required") } LOCATION := os.Getenv("LOCATION") if LOCATION == "" { panic("LOCATION is required") } ctx := context.Background() opts := []option.ClientOption{} client, err := cloudtasks.NewClient(ctx, opts...) if err != nil { panic(err) } parent := fmt.Sprintf("projects/%s/locations/%s", PROJECT, LOCATION, ) // Generate a predictable Queue ID for testing // Cannot reuse the same Queue ID name := fmt.Sprintf("%s/queues/q-%d", parent, time.Now().Unix(), ) slog.Info("Output", "parent", parent, "name", name, ) // Create the Queue { rqst := &cloudtaskspb.CreateQueueRequest{ Parent: parent, Queue: &cloudtaskspb.Queue{ Name: name, RateLimits: &cloudtaskspb.RateLimits{ MaxDispatchesPerSecond: 1, }, }, } resp, err := client.CreateQueue(ctx, rqst) if err != nil { panic(err) } slog.Info("Output", "resp", resp) } time.Sleep(15 * time.Second) // Delete the Queue { rqst := &cloudtaskspb.DeleteQueueRequest{ Name: name, } if err := client.DeleteQueue(ctx, rqst); err != nil { panic(err) } } }

thin:

go run .

Yields:

2025/02/06 08:51:18 INFO Output parent=projects/dazwilkin-250206-79415361/locations/europe-central2 name=projects/dazwilkin-250206-79415361/locations/europe-central2/queues/q-1738860678 2025/02/06 08:51:20 INFO Output resp="name:\"projects/dazwilkin-250206-79415361/locations/europe-central2/queues/q-1738860678\" rate_limits:{max_dispatches_per_second:1 max_burst_size:10 max_concurrent_dispatches:1000} retry_config:{max_attempts:100 min_backoff:{nanos:100000000} max_backoff:{seconds:3600} max_doublings:16} state:RUNNING"
尽管GO代码没有列出队列,但创建和随后的删除之间没有恐慌就足够证据|证据|证据。
today,我想通过在node.js

中编写同等代码来帮助您有所帮助

package.json

{
  "name": "79415361",
  "version": "0.0.1",
  "main": "index.js",
  "type": "commonjs",
  "dependencies": {
    "@google-cloud/tasks": "^5.5.2"
  }
}

index.js

const { CloudTasksClient } = require('@google-cloud/tasks');

const PROJECT = process.env.PROJECT;

if (PROJECT === undefined) {
  throw new Error("PROJECT is required");
}

const LOCATION = process.env.LOCATION;

if (LOCATION === undefined) {
  throw new Error("LOCATION is undefined");
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function main() {
  // Use Application Default Credentials
  const client = new CloudTasksClient();

  const parent =  client.locationPath(PROJECT, LOCATION);
  const name = client.queuePath(PROJECT, LOCATION, `q-${Math.floor(Date.now()/1000)}`);

  const queue = {
    name: name,
    rateLimits: {
      maxDispatchesPerSecond: 1,
    },
  };

  // Create the Queue
  {
    const rqst = {
      parent: parent,
      queue: queue,
    };

    const resp = await client.createQueue(rqst);
    console.log(resp);
  }

  // List Queues
  {
    const rqst = {
      parent: parent,
    };

    const resp = await client.listQueues(rqst);
    console.log(resp);
  }

  await sleep(15000);

  {
    const rqst = {
      name: name,
    };

    const resp = await client.deleteQueue(rqst);
    console.log(resp);
  }
}

main();

和:
node index.js

Yields:
[
  {
    name: 'projects/dazwilkin-250206-79415361/locations/europe-central2/queues/q-1738862467',
    appEngineRoutingOverride: null,
    rateLimits: {
      maxDispatchesPerSecond: 1,
      maxBurstSize: 10,
      maxConcurrentDispatches: 1000
    },
    retryConfig: {
      maxAttempts: 100,
      maxRetryDuration: null,
      minBackoff: [Object],
      maxBackoff: [Object],
      maxDoublings: 16
    },
    state: 'RUNNING',
    purgeTime: null,
    stackdriverLoggingConfig: null
  },
  null,
  null
]
[
  [
    {
      name: 'projects/dazwilkin-250206-79415361/locations/europe-central2/queues/q-1738862467',
      appEngineRoutingOverride: null,
      rateLimits: [Object],
      retryConfig: [Object],
      state: 'RUNNING',
      purgeTime: null,
      stackdriverLoggingConfig: null
    }
  ],
  null,
  null
]
[ {}, null, null ]

node.js代码创建,列表然后删除队列。 我天真的JavaScript的apologies.

希望这有帮助!


最新问题
© www.soinside.com 2019 - 2025. All rights reserved.