0

在我的 GCP 组织中,它具有以下层次结构Org--> folder--> folder--> folder--> projects--> Resources。我有一个全局视图服务帐户,该帐户具有列出项目和文件夹的必要权限。我正在使用 GCP JAVA 客户端库,但我看到列出了我需要使用的文件夹,https://cloudresourcemanager.googleapis.com/v2/folders这些文件夹位于 v2 Cloud 资源管理器 API 下,但列出我需要的项目https://cloudresourcemanager.googleapis.com/v1/projects位于 v1 Cloud 资源管理器 API 下。有没有办法可以利用 GCP JAVA 客户端库同时列出文件夹和项目?

4

2 回答 2

1

您要求 Google Cloud 上最可怕的 API。这是一个糟糕而可怕的 API,您的问题就是由此造成的......无论如何,我花了几个小时尝试,我可以建议您使用 Discovery API(在 python 中非常简单,很少有文档记录且难以使用爪哇)。确实,您不能使用自动生成的客户端库,您需要使用直接 API 调用或Discovery API

首先,在您的 Maven 定义中添加此依赖项

        <dependency>
            <groupId>com.google.apis</groupId>
            <artifactId>google-api-services-discovery</artifactId>
            <version>v1-rev20190129-1.31.0</version>
        </dependency>

然后是 Discovery API 的使用。

// Build the discovery API object
        HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
        JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
        Discovery discovery = (new Discovery.Builder(httpTransport,jsonFactory,null)).build();

// Prepare your credential for the calls
        GoogleCredentials credential = GoogleCredentials.getApplicationDefault();
        HttpRequestFactory requestFactory = httpTransport.createRequestFactory(new HttpCredentialsAdapter(credential));

// Discover the API V1 of resource manager
        RestDescription apiV1 = discovery.apis().getRest("cloudresourcemanager", "v1").execute();

// Discover the API V2 of resource manager
        RestDescription apiV2 = discovery.apis().getRest("cloudresourcemanager", "v2").execute();

//Get a Method in the v1, here list project
        RestMethod methodListProject = apiV1.getResources().get("projects").getMethods().get("list");

//Get a Method in the v2, here list folders
        RestMethod methodListFolder = apiV2.getResources().get("folders").getMethods().get("list");

/////////////////////// V1 call /////////////////////

//Create the URL to call, with no query parameter here
        GenericUrl urlProjectList = new GenericUrl(UriTemplate.expand(apiV1.getBaseUrl() + methodListProject.getPath(), null, true));
        System.out.println(urlProjectList);

//Prepare the request
        HttpRequest requestProjectList = requestFactory.buildRequest(methodListProject.getHttpMethod(), urlProjectList, null);

//Execute and print the result
        System.out.println(requestProjectList.execute().parseAsString());

/////////////////////// V2 call /////////////////////

//Prepare the parameter for the call    
        JsonSchema param = new JsonSchema();
        param.set(
                "parent", String.format("organizations/%s", "<OrganisationID>"));


//Create the URL to call, with the query parameter
        GenericUrl urlFolderList = new GenericUrl(UriTemplate.expand(apiV1.getBaseUrl() + methodListFolder.getPath(), param, true));
        System.out.println(urlFolderList);

//Prepare the request
        HttpRequest requestFolderList = requestFactory.buildRequest(methodListFolder.getHttpMethod(), urlFolderList, null);

//Execute and print the result
        System.out.println(requestFolderList.execute().parseAsString());

两者都在相同的代码中同时工作。不太可读。我建议您将其包装在符合您要求的类中,以获得更好的可读性/可重用性。

您需要大量使用API 描述来了解和理解存在哪些方法及其参数

于 2021-03-19T15:40:22.020 回答
1

据我所知,没有一种方法可以同时列出文件夹和项目。
如果您认为该功能应该可用,您可以创建一个功能请求

或者,有一个bash 脚本利用 gcloud 命令获得类似结果:

#!/usr/bin/env bash

: "${ORGANIZATION:?Need to export ORGANIZATION and it must be non-empty}"

# gcloud format
FORMAT="csv[no-heading](name,displayName.encode(base64))"

# Enumerates Folders recursively
folders()
{
  LINES=("$@")
  for LINE in ${LINES[@]}
  do
    # Parses lines of the form folder,name
    VALUES=(${LINE//,/ })
    FOLDER=${VALUES[0]}
    # Decodes the encoded name
    NAME=$(echo ${VALUES[1]} | base64 --decode)
    echo "Folder: ${FOLDER} (${NAME})"
    folders $(gcloud resource-manager folders list \
      --folder=${FOLDER} \
      --format="${FORMAT}")
  done
}

# Start at the Org
echo "Org: ${ORGANIZATION}"
LINES=$(gcloud resource-manager folders list \
  --organization=${ORGANIZATION} \
  --format="${FORMAT}")

# Descend
folders ${LINES[0]}
于 2021-03-19T15:17:15.903 回答