Reputation: 55
I am attempting to create some GCP VMs using the API client libraries for Java, but the examples that I have seen seem to be old. I started with this https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/compute/cmdline/src/main/java/ComputeEngineSample.java but it looks like the GoogleCredential
class is deprecated.
After some research I came up with this code
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
if (credentials.createScopedRequired()) {
List<String> scopes = new ArrayList<>();
scopes.add(ComputeScopes.DEVSTORAGE_FULL_CONTROL);
scopes.add(ComputeScopes.DEVSTORAGE_READ_WRITE);
credentials = credentials.createScoped(scopes);
}
Compute compute = new Compute.Builder(httpTransport, jsonFactory, null)
.setApplicationName("et").build();
Compute.Instances.List instancesList = compute.instances().list("<GCP-PROJECT>", "us-central1-a");
InstanceList executedOperation = instancesList.execute();
Next, I set the GOOGLE_APPLICATION_CREDENTIALS
environment variable to the path of my service account json file and ran my code, but it fails with a 401 Unauthorized
error. The partial message is this
"message" : "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential.
The examples that I see are for other Google products like Storage, Pubsub etc, but I cant find any relevant example on how to use my credentials to invoke some operations on a Compute
service. Any help would be appreciated.
Upvotes: 0
Views: 4507
Reputation: 40091
I took the Google sample and it works for me.
I abbreviated it to only enumerate instances.
PROJECT=
ZONE=
INSTANCE=
ACCOUNT=
gcloud projects create ${PROJECT}
gcloud alpha billing projects link ${PROJECT} \
--billing-account=${BILLING}
gcloud services enable compute.googleapis.com \
--project=${PROJECT}
# Create an instance to enumerate
gcloud compute instances create instance-1 \
--project=${PROJECT} \
--zone=${ZONE} \
--machine-type=f1-micro \
--image-family=debian-10 \
--image-project=debian-cloud \
--preemptible
gcloud iam service-accounts create ${ACCOUNT} \
--project=${PROJECT}
gcloud iam service-accounts keys create ./${ACCOUNT}.json \
--iam-account=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com \
--project=${PROJECT}
# Overly broad permissions but...
gcloud projects add-iam-policy-binding ${PROJECT} \
--member=serviceAccount:${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com \
--role=roles/compute.admin
export GOOGLE_APPLICATION_CREDENTIALS=./${ACCOUNT}.json
mvn exec:java -Dexec.mainClass="com.dazwilkin.gce.App"
yields (edited for clarity):
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< com.dazwilkin.gce:gce >------------------------
[INFO] Building gce 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec-maven-plugin:1.6.0:java (default-cli) @ gce ---
Hello Freddie!
================== Listing Compute Engine Instances ==================
{
"id" : "6020825766320745087",
"kind" : "compute#instance",
"name" : "instance-1",
}
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.088 s
[INFO] Finished at: 2020-05-13T17:54:51-07:00
[INFO] ------------------------------------------------------------------------
and pom.xml
:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.dazwilkin.gce</groupId>
<artifactId>gce</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>gce</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.30.9</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-compute</artifactId>
<version>v1-rev235-1.25.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
google-auth-library
From the google-auth-library
docs:
import com.google.auth.Credentials;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.api.client.http.HttpRequestInitializer;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class App
{
public static void main(String[] args )
{
GoogleCredentials credentials = GoogleCredentials.getApplicationDefault();
...
HttpRequestInitializer requestInitializer =
new HttpCredentialsAdapter(credentials);
Compute compute =
new Compute.Builder(httpTransport, JSON_FACTORY, requestInitializer)
.setApplicationName(APPLICATION_NAME)
.build();
...
}
with pom.xml
:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.dazwilkin.gce</groupId>
<artifactId>gce</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>gce</name>
<url>http://maven.apache.org</url>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.9</source>
<target>1.9</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.30.9</version>
</dependency>
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-compute</artifactId>
<version>v1-rev235-1.25.0</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-credentials</artifactId>
<version>0.20.0</version>
</dependency>
<dependency>
<groupId>com.google.auth</groupId>
<artifactId>google-auth-library-oauth2-http</artifactId>
<version>0.20.0</version>
</dependency>
</dependencies>
</project>
Upvotes: 4