简体   繁体   中英

How to list folders and projects inside the folders in GCP

In my GCP organization which has following hierarchy Org--> folder--> folder--> folder--> projects--> Resources . I have a global view service account using which has necessary permission to list the projects and folders. I am making use of GCP JAVA client library but I see listing folders I need to make use of https://cloudresourcemanager.googleapis.com/v2/folders which is under v2 Cloud resource Manager API but for listing projects I need https://cloudresourcemanager.googleapis.com/v1/projects which is under v1 Cloud resource Manager API. Is there a way I can make use of GCP JAVA client library to list both folders and projects together??

As far as I can tell, there is no single method that would allow to list both folders and projects.
If you think that function should be available, you can create a feature request .

Alternatively, there is a bash script that utilizes gcloud commands for similar result:

#!/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]}

Your are asking for the most horrible API on Google Cloud. It's a bad and horrible API and your problem is the result of that... Anyway, I took several hours to try and I can propose you to use the Discovery API (so simple in python and very very few documented and hard to use in Java). Indeed, you can't use the autogenerated client library, you need to use the direct API call or the Discovery API

Firtly, add this dependency in your Maven definition

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

Then the Discovery API usage.

// 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());

Both works in the same code, in the same time. Not very readable. I recommend you to wrap that in classes that fit your requirements for a better readability/reusability.

You need to use a lot the API description to know and understand which methods exist and their parameters

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM