Get Google Cloud Project Number using its Id

Viewed 13974

I have Google Cloud Service account and projectId and want to get projectNumber programmatically from Java.

enter image description here

How can I get it?

Basically I have Service Account and want to use it for granting role "roles/storage.legacyBucketWriter" for the account "project-XXXXXXX@storage-transfer-service.iam.gserviceaccount.com" in the Google Cloud Storage Bucket.

8 Answers

Not sure why they don't expose it directly, but you can do this (assuming your current configuration project corresponds to the desired project number):

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

I think GCP did not provide an API to map a project ID to a project number. But they did provide a project list API, after you get the list of the projects. You can map the project number by yourself.

There is an API now.

The jar version of the cloudresourcemanager java library supports it directly, as in the example here https://cloud.google.com/resource-manager/reference/rest/v1/projects/get

With maven dependencies, you can do

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 (adapted from the example by 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 will be something like {"projectNumber": "123456", ...}

Although this question is for Java, for those who might find it useful, here is a program to obtain a Google Project number from its ID in Go as well:

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)
}

You can run it like so:

> go run main.go --projectID="my-project"
Project number for project my-project: 123456789817

(Note that this example uses Google Application Default Credentials (cf. https://godoc.org/google.golang.org/api/cloudresourcemanager/v1#hdr-Creating_a_client)).

You can just use gcloud projects describe <<project_id>> (documentation)

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

My answer doesn't do anything in Java but should work in many environments, i.e. bash or zsh, using tools most have access to during development or within containerized environments.

Assuming you're using some type of build process, you could trivially:

  1. throw the following command into a docker container,
  2. output the result (the project number) in a build step, and
  3. store that in an environment variable for use in additional steps.

Using gcloud, grep , and awk

This assumes you have the string project name set in the PROJECT_NAME environment variable.

This is a super simple solution using the Google Cloud SDK and the commonly available CLI tools grep and awk:

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

Note: I suspect very big accounts with many projects may not want to query the entire list each time an individual project number is required. For those cases @erkolson's answer is likely the best solution.

there are a list of api's that can provide it, from the command line would be:

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

it is possible to get also the project id :

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

This gcloud command will return the project number:

gcloud projects describe $PROJECT_ID --format="value(projectNumber)"

You can then use this in a command to grant access such as:

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
Related