使用Google Cloud项目ID获取其项目编号

23

我拥有Google云服务账户和项目ID,并希望从Java程序中以编程方式获取项目编号。

输入图片描述

我该如何获取它?

基本上,我拥有服务账户,并希望将其用于为Google云存储桶中的“project-XXXXXXX@storage-transfer-service.iam.gserviceaccount.com”账户授予“roles/storage.legacyBucketWriter”角色。

9个回答

37

不确定为什么他们不直接公开,但您可以这样做(假设您当前的配置项目对应所需的项目编号):

gcloud projects list \
--filter="$(gcloud config get-value project)" \
--format="value(PROJECT_NUMBER)"

我必须从Java编程解决这个问题。无论如何,我已经解决了这个问题,请参见我的上面的评论。 - Dmitry Gorkovets
3
我知道OP想要一个Java API,但是...如果其他搜索者在这里寻找使用gcloud将project_id映射到项目编号的方法,那么这不是最好的方法(至少在2020年10月不是)。请尝试使用以下命令:gcloud projects describe $PROJECT_ID --format="value(projectNumber)"。请参考文档:https://cloud.google.com/sdk/gcloud/reference/projects/describe - Cheeso

8
这个gcloud命令将返回项目编号:
gcloud projects describe $PROJECT_ID --format="value(projectNumber)"

您可以在命令中使用此内容授予访问权限,例如:
gcloud projects add-iam-policy-binding $PROJECT_ID  --member=serviceAccount:$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@@storage-transfer-service.iam.gserviceaccount.com --role=roles/storage.legacyBucketWriter

5

我认为GCP没有提供将项目ID映射到项目编号的API。但是,他们提供了项目列表API,在获取项目列表后,你可以自己映射项目编号。


是的,我已经看过这个页面,但是在Java API中找不到如何实现它。 - Dmitry Gorkovets
@DmitryGorkovets,您能否更明确地说明为什么您无法在Java API中找到如何做到这一点的方法?不知道如何使用Java API调用吗? - Lee
谢谢!我从https://cloud.google.com/resource-manager/reference/rest/v1/projects/list获取了Java示例。请注意,它在“v1”版本中可访问。“v2”版本在CloudResourceManager中没有此功能。 - Dmitry Gorkovets

2
尽管这个问题是关于Java的,但对于那些可能会发现它有用的人,这里也提供了一个程序来在Go中通过其ID获取Google项目编号:
package main

import (
    "context"
    "flag"
    "fmt"
    "log"

    "google.golang.org/api/cloudresourcemanager/v1"
)

var projectID string

func main() {
    flag.StringVar(&projectID, "projectID", "", "Google Cloud Project ID")
    flag.Parse()

    cloudresourcemanagerService, err := cloudresourcemanager.NewService(context.Background())
    if err != nil {
        log.Fatalf("NewService: %v", err)
    }

    project, err := cloudresourcemanagerService.Projects.Get(projectID).Do()
    if err != nil {
        log.Fatalf("Get project: %v", err)
    }

    fmt.Printf("Project number for project %s: %d\n", projectID, project.ProjectNumber)
}

您可以这样运行它:
> go run main.go --projectID="my-project"
Project number for project my-project: 123456789817

请注意,此示例使用Google应用程序默认凭据(参见https://godoc.org/google.golang.org/api/cloudresourcemanager/v1#hdr-Creating_a_client)。


我们能否获取项目名称而不是编号,而且可以用Python代替Java吗? - lisa_rao007

2
现在有一个API。
cloudresourcemanager java库的jar版本直接支持它,例如这里的示例。
使用maven依赖,你可以这样做: pom.xml
<!-- https://mvnrepository.com/artifact/com.google.apis/google-api-services-cloudresourcemanager -->
<dependency>
    <groupId>com.google.apis</groupId>
    <artifactId>google-api-services-cloudresourcemanager</artifactId>
    <version>v2-rev20200617-1.30.9</version>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.7</version>
</dependency>

CloudResourceManagerExample.java(根据Google示例进行调整)

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.cloudresourcemanager.CloudResourceManager;
import com.google.api.services.cloudresourcemanager.model.Project;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;

import org.apache.commons.io.IOUtils
import com.google.api.client.http.GenericUrl;
import java.nio.charset.StandardCharsets;

public class CloudResourceManagerExample {
  public static void main(String args[]) throws IOException, GeneralSecurityException {
    // The Project ID (for example, `my-project-123`).
    // Required.
    String projectId = "my-project-id"; // TODO: Update placeholder value.

    CloudResourceManager cloudResourceManagerService = createCloudResourceManagerService();

    String response = IOUtils.toString(cloudResourceManagerService.getRequestFactory().buildGetRequest(new GenericUrl("https://cloudresourcemanager.googleapis.com/v1/projects/" + projectId)).execute().getContent(), StandardCharsets.UTF_8);

    // TODO: Change code below to process the `response` object:
    System.out.println(response);
  }

  public static CloudResourceManager createCloudResourceManagerService()
      throws IOException, GeneralSecurityException {
    HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();

    GoogleCredential credential = GoogleCredential.getApplicationDefault();
    if (credential.createScopedRequired()) {
      credential =
          credential.createScoped(Arrays.asList("https://www.googleapis.com/auth/cloud-platform"));
    }

    return new CloudResourceManager.Builder(httpTransport, jsonFactory, credential)
        .setApplicationName("Google-CloudResourceManagerSample/0.1")
        .build();
  }
}

response 的返回结果会像这样:{"projectNumber": "123456", ...}

在 Python 中,你可以这样做:

# python3 -m pip install google.auth google-api-python-client
# from https://github.com/GoogleCloudPlatform/python-docs-samples/blob/main/iam/api-client/quickstart.py
import google.auth
import googleapiclient.discovery
def initialize_service():
    """Initializes a Cloud Resource Manager service."""

    credentials, _ = google.auth.default(
        scopes=["https://www.googleapis.com/auth/cloud-platform"]
    )
    crm_service = googleapiclient.discovery.build(
        "cloudresourcemanager", "v1", credentials=credentials
    )
    return crm_service

crm_service = initialize_service()
project = r.get(projectId=MY_PROJECT_ID).execute()

我们能否使用项目名称而不是数字,而且可以用Python代替Java吗? - lisa_rao007
@user3713336,是的,我在我的回答末尾添加了一个Python示例。名称将为project['name'] - Gavin Haynes
它给出了完整的名字-如果我只想要显示名称呢。我只想打印显示名称。 - lisa_rao007
什么?这就是所有的信息了吗?project['name'] 是显示名称,不是名称。你还想要什么? - Gavin Haynes
有人能帮我解决这个问题吗 - https://devops.stackexchange.com/questions/16829/how-can-i-force-an-immediate-run-of-a-job-trigger - lisa_rao007

1

您可以直接使用 gcloud projects describe <<project_id>> 命令(文档

$ gcloud projects describe XXX
createTime: ...
lifecycleState: ...
name: ...
parent:
  id: ...
  type: ...
projectId: XXX
projectNumber: 'YYY'

0

有一系列的API可以提供它,从命令行可以这样:

gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_NUMBER)"

可以获取项目ID:

gcloud projects list --filter="$(gcloud config get-value project)" --format="value(PROJECT_ID)"

0

我的答案在Java中没有任何作用,但应该适用于许多环境,例如使用大多数人在开发过程中或容器化环境中可以访问的工具,如bashzsh

假设您正在使用某种构建过程,您可以轻松地执行以下操作:

  1. 将以下命令放入docker容器中,
  2. 在构建步骤中输出结果(项目编号),并
  3. 将其存储在环境变量中以供其他步骤使用。

使用gcloudgrepawk

这假定您已经在PROJECT_NAME环境变量中设置了字符串项目名称。

这是一个超级简单的解决方案,使用Google Cloud SDK和常用的CLI工具grepawk

gcloud projects list | grep '${PROJECT_NAME} ' | awk '{print $3}'

注意:我怀疑那些有许多项目的大型账户可能不想每次需要一个单独的项目编号时都查询整个列表。对于这些情况,@erkolson's answer 可能是最佳解决方案。

0
请确保安装以下软件包:
pip install google-cloud-resource-manager

源代码:
from google.cloud import resourcemanager_v3

def get_project_number(project_id):
    client = resourcemanager_v3.ProjectsClient()
    project = client.get_project(name=f"projects/{project_id}").name
    return project.split('/')[-1]

project_id = 'myprojectid'
project_number = get_project_number(project_id)
print(f"The project number for project {project_id} is: {project_number}")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接