在我的 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 客户端库同时列出文件夹和项目?
问问题
821 次
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 回答