I am looking to automate the provisioning of google cloud resources using Deployment Manager. Only I want to use the JAVA API library instead of gcloud.
Specifically need to provision the following components using DeploymentManager.
- Cloud SQL – MSSQL
- Cloud Run Service
- VPC Network with the Connector to be used to connect Cloud Run to the Cloud SQL.
I think com.google.api.services.deploymentmanager.DeploymentManager
is the starting point but I am not very sure.
This is what I have so far
Builder builder = new Builder( com.google.api.client.googleapis.javanet.GoogleNetHttpTransport.newTrustedTransport(), new com.google.api.client.json.gson.GsonFactory(), null); builder.setApplicationName("spatial-cat-319209"); builder.setDeploymentManagerRequestInitializer(new DeploymentManagerRequestInitializer()); DeploymentManager deploymentManager = builder.build(); deploymentManager.deployments().list("spatial-cat-319209").entrySet().stream().forEach(entry -> { System.out.println(entry.getKey() + " = " + entry.getValue()); }); System.out.println(System.getProperty("GOOGLE_APPLICATION_CREDENTIALS")); System.out.println(System.getenv("GOOGLE_APPLICATION_CREDENTIALS")); deploymentManager.deployments().list("spatial-cat-319209").execute();
I get the following error in the last line:
Exception in thread "main" com.google.api.client.googleapis.json.GoogleJsonResponseException: 401 Unauthorized GET https://deploymentmanager.googleapis.com/deploymentmanager/v2/projects/spatial-cat-319209/global/deployments { "code": 401, "errors": [ { "domain": "global", "location": "Authorization", "locationType": "header", "message": "Login Required.", "reason": "required" } ], "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "status": "UNAUTHENTICATED" } at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:146) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:118) at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:37) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:428) at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1111) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:514) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:455) at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:565)
I do have the environment variable GOOGLE_APPLICATION_CREDENTIALS pointing to a file that contains the service account key (generated using gcloud auth application-default login
command)
Any insights would be very helpful.
Advertisement
Answer
Okay, it looks like I have got it working with the code below.
I have demonstrated how to use gcloud command using processbuilder as well as the DeploymentManager API. I had to use GoogleCredentials to read the service-account-key-file and pass that to the HttpCredentialsAdapter.
It was very hard to locate but this guide came in handy. Posting a link as reference for someone who stumbles by later.
Let me know if this can be done in a better way.
GoogleCredentials googleCredentials = GoogleCredentials .fromStream(new FileInputStream(System.getenv("GOOGLE_APPLICATION_CREDENTIALS"))); HttpRequestInitializer httpRequestInitializer = new HttpCredentialsAdapter(googleCredentials); Builder builder = new Builder( com.google.api.client.googleapis.javanet.GoogleNetHttpTransport.newTrustedTransport(), com.google.api.client.json.gson.GsonFactory.getDefaultInstance(), httpRequestInitializer); builder.setApplicationName("spatial-cat-319209"); builder.setDeploymentManagerRequestInitializer(new DeploymentManagerRequestInitializer()); DeploymentManager deploymentManager = builder.build(); deploymentManager.deployments().list("spatial-cat-319209").entrySet().stream().forEach(entry -> { System.out.println(entry.getKey() + " = " + entry.getValue()); }); System.out.println(System.getProperty("GOOGLE_APPLICATION_CREDENTIALS")); System.out.println(System.getenv("GOOGLE_APPLICATION_CREDENTIALS")); System.out.println("Listing deployments in project using gcloud command ..."); // Runtime.getRuntime().exec("gcloud deployment-manager deployments list"); ProcessBuilder processBuilder = new ProcessBuilder(); Process process = processBuilder.command("powershell", "gcloud", "deployment-manager", "deployments", "list") .start(); InputStreamReader isr = new InputStreamReader(process.getInputStream()); BufferedReader rdr = new BufferedReader(isr); String line = ""; while ((line = rdr.readLine()) != null) { System.out.println(line); } isr = new InputStreamReader(process.getErrorStream()); rdr = new BufferedReader(isr); while ((line = rdr.readLine()) != null) { System.out.println(line); } int rc = process.waitFor(); // Wait for the process to complete System.out.println("Return Code = " + rc); System.out.println("Listing deployments in project using DeploymentManager API..."); DeploymentsListResponse deploymentsListResponse = deploymentManager.deployments().list("spatial-cat-319209") .execute(); System.out.println("Number of deployments = " + deploymentsListResponse.size()); deploymentsListResponse.forEach((depl, a) -> System.out.println(depl + " - " + a)); System.out.println("Done");