/* * Copyright 2015 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.gson.GsonFactory; import com.google.api.services.compute.Compute; import com.google.api.services.compute.ComputeScopes; import com.google.api.services.compute.model.AccessConfig; import com.google.api.services.compute.model.AttachedDisk; import com.google.api.services.compute.model.AttachedDiskInitializeParams; import com.google.api.services.compute.model.Instance; import com.google.api.services.compute.model.InstanceList; import com.google.api.services.compute.model.Metadata; import com.google.api.services.compute.model.NetworkInterface; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.ServiceAccount; import com.google.auth.http.HttpCredentialsAdapter; import com.google.auth.oauth2.GoogleCredentials; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Command-line sample to demo listing Google Compute Engine instances using Java and the Google * Compute Engine API. * * @author Jonathan Simon */ public class ComputeEngineSample { /** * Be sure to specify the name of your application. If the application name is {@code null} or * blank, the application will log a warning. Suggested format is "MyCompany-ProductName/1.0". */ private static final String APPLICATION_NAME = ""; /** Set PROJECT_ID to your Project ID from the Overview pane in the Developers console. */ private static final String PROJECT_ID = "YOUR_PROJECT_ID"; /** Set Compute Engine zone. */ private static final String ZONE_NAME = "us-central1-f"; /** Set the name of the sample VM instance to be created. */ private static final String SAMPLE_INSTANCE_NAME = "my-sample-instance"; /** Set the path of the OS image for the sample VM instance to be created. */ private static final String SOURCE_IMAGE_PREFIX = "https://www.googleapis.com/compute/v1/projects/"; private static final String SOURCE_IMAGE_PATH = "ubuntu-os-cloud/global/images/ubuntu-2004-focal-v20200529"; /** Set the Network configuration values of the sample VM instance to be created. */ private static final String NETWORK_INTERFACE_CONFIG = "ONE_TO_ONE_NAT"; private static final String NETWORK_ACCESS_CONFIG = "External NAT"; /** Set the time out limit for operation calls to the Compute Engine API. */ private static final long OPERATION_TIMEOUT_MILLIS = 60 * 1000; /** Global instance of the HTTP transport. */ private static HttpTransport httpTransport; /** Global instance of the JSON factory. */ private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance(); public static void main(String[] args) { try { httpTransport = GoogleNetHttpTransport.newTrustedTransport(); // Authenticate using Google Application Default Credentials. GoogleCredentials credential = GoogleCredentials.getApplicationDefault(); if (credential.createScopedRequired()) { List scopes = new ArrayList<>(); // Set Google Cloud Storage scope to Full Control. scopes.add(ComputeScopes.DEVSTORAGE_FULL_CONTROL); // Set Google Compute Engine scope to Read-write. scopes.add(ComputeScopes.COMPUTE); credential = credential.createScoped(scopes); } HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credential); // Create Compute Engine object for listing instances. Compute compute = new Compute.Builder(httpTransport, JSON_FACTORY, requestInitializer) .setApplicationName(APPLICATION_NAME) .build(); // List out instances, looking for the one created by this sample app. boolean foundOurInstance = printInstances(compute); Operation op; if (foundOurInstance) { op = deleteInstance(compute, SAMPLE_INSTANCE_NAME); } else { op = startInstance(compute, SAMPLE_INSTANCE_NAME); } // Call Compute Engine API operation and poll for operation completion status System.out.println("Waiting for operation completion..."); Operation.Error error = blockUntilComplete(compute, op, OPERATION_TIMEOUT_MILLIS); if (error == null) { System.out.println("Success!"); } else { System.out.println(error.toPrettyString()); } } catch (IOException e) { System.err.println(e.getMessage()); } catch (Throwable t) { t.printStackTrace(); } System.exit(1); } /** * Print available machine instances. * * @param compute The main API access point * @return {@code true} if the instance created by this sample app is in the list */ public static boolean printInstances(Compute compute) throws IOException { System.out.println("================== Listing Compute Engine Instances =================="); Compute.Instances.List instances = compute.instances().list(PROJECT_ID, ZONE_NAME); InstanceList list = instances.execute(); boolean found = false; if (list.getItems() == null) { System.out.println( "No instances found. Sign in to the Google Developers Console and create " + "an instance at: https://console.developers.google.com/"); } else { for (Instance instance : list.getItems()) { System.out.println(instance.toPrettyString()); if (instance.getName().equals(SAMPLE_INSTANCE_NAME)) { found = true; } } } return found; } // [START compute_create_instance] public static Operation startInstance(Compute compute, String instanceName) throws IOException { System.out.println("================== Starting New Instance =================="); // Create VM Instance object with the required properties. Instance instance = new Instance(); instance.setName(instanceName); instance.setMachineType( String.format( "https://www.googleapis.com/compute/v1/projects/%s/zones/%s/machineTypes/e2-standard-1", PROJECT_ID, ZONE_NAME)); // Add Network Interface to be used by VM Instance. NetworkInterface ifc = new NetworkInterface(); ifc.setNetwork( String.format( "https://www.googleapis.com/compute/v1/projects/%s/global/networks/default", PROJECT_ID)); List configs = new ArrayList<>(); AccessConfig config = new AccessConfig(); config.setType(NETWORK_INTERFACE_CONFIG); config.setName(NETWORK_ACCESS_CONFIG); configs.add(config); ifc.setAccessConfigs(configs); instance.setNetworkInterfaces(Collections.singletonList(ifc)); // Add attached Persistent Disk to be used by VM Instance. AttachedDisk disk = new AttachedDisk(); disk.setBoot(true); disk.setAutoDelete(true); disk.setType("PERSISTENT"); AttachedDiskInitializeParams params = new AttachedDiskInitializeParams(); // Assign the Persistent Disk the same name as the VM Instance. params.setDiskName(instanceName); // Specify the source operating system machine image to be used by the VM Instance. params.setSourceImage(SOURCE_IMAGE_PREFIX + SOURCE_IMAGE_PATH); // Specify the disk type as Standard Persistent Disk params.setDiskType( String.format( "https://www.googleapis.com/compute/v1/projects/%s/zones/%s/diskTypes/pd-standard", PROJECT_ID, ZONE_NAME)); disk.setInitializeParams(params); instance.setDisks(Collections.singletonList(disk)); // Initialize the service account to be used by the VM Instance and set the API access scopes. ServiceAccount account = new ServiceAccount(); account.setEmail("default"); List scopes = new ArrayList<>(); scopes.add("https://www.googleapis.com/auth/devstorage.full_control"); scopes.add("https://www.googleapis.com/auth/compute"); account.setScopes(scopes); instance.setServiceAccounts(Collections.singletonList(account)); // Optional - Add a startup script to be used by the VM Instance. Metadata meta = new Metadata(); Metadata.Items item = new Metadata.Items(); item.setKey("startup-script-url"); // If you put a script called "vm-startup.sh" in this Google Cloud Storage // bucket, it will execute on VM startup. This assumes you've created a // bucket named the same as your PROJECT_ID. // For info on creating buckets see: // https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets item.setValue(String.format("gs://%s/vm-startup.sh", PROJECT_ID)); meta.setItems(Collections.singletonList(item)); instance.setMetadata(meta); System.out.println(instance.toPrettyString()); Compute.Instances.Insert insert = compute.instances().insert(PROJECT_ID, ZONE_NAME, instance); return insert.execute(); } // [END compute_create_instance] private static Operation deleteInstance(Compute compute, String instanceName) throws Exception { System.out.println( "================== Deleting Instance " + instanceName + " =================="); Compute.Instances.Delete delete = compute.instances().delete(PROJECT_ID, ZONE_NAME, instanceName); return delete.execute(); } public static String getLastWordFromUrl(String url) { if (url != null) { String[] bits = url.split("/"); url = bits[bits.length - 1]; } return url; } // [START compute_wait_for_operation] /** * Wait until {@code operation} is completed. * * @param compute the {@code Compute} object * @param operation the operation returned by the original request * @param timeout the timeout, in millis * @return the error, if any, else {@code null} if there was no error * @throws InterruptedException if we timed out waiting for the operation to complete * @throws IOException if we had trouble connecting */ public static Operation.Error blockUntilComplete( Compute compute, Operation operation, long timeout) throws Exception { long start = System.currentTimeMillis(); final long pollInterval = 5 * 1000; String zone = getLastWordFromUrl(operation.getZone()); // null for global/regional operations String region = getLastWordFromUrl(operation.getRegion()); String status = operation.getStatus(); String opId = operation.getName(); while (operation != null && !status.equals("DONE")) { Thread.sleep(pollInterval); long elapsed = System.currentTimeMillis() - start; if (elapsed >= timeout) { throw new InterruptedException("Timed out waiting for operation to complete"); } System.out.println("waiting..."); if (zone != null) { Compute.ZoneOperations.Get get = compute.zoneOperations().get(PROJECT_ID, zone, opId); operation = get.execute(); } else if (region != null) { Compute.RegionOperations.Get get = compute.regionOperations().get(PROJECT_ID, region, opId); operation = get.execute(); } else { Compute.GlobalOperations.Get get = compute.globalOperations().get(PROJECT_ID, opId); operation = get.execute(); } if (operation != null) { status = operation.getStatus(); } } return operation == null ? null : operation.getError(); } // [END compute_wait_for_operation] }