/** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for * license information. */ package com.microsoft.azure.management.compute.samples; import com.microsoft.azure.management.Azure; import com.microsoft.azure.management.compute.Disk; import com.microsoft.azure.management.compute.KnownLinuxVirtualMachineImage; import com.microsoft.azure.management.compute.KnownWindowsVirtualMachineImage; import com.microsoft.azure.management.compute.VirtualMachine; import com.microsoft.azure.management.compute.VirtualMachineSizeTypes; import com.microsoft.azure.management.network.Network; import com.microsoft.azure.management.resources.fluentcore.arm.Region; import com.microsoft.azure.management.resources.fluentcore.model.Creatable; import com.microsoft.azure.management.resources.fluentcore.model.Indexable; import com.microsoft.azure.management.samples.Utils; import com.microsoft.rest.LogLevel; import rx.Observable; import rx.functions.Func1; import java.io.File; import java.util.Date; import java.util.Map; import java.util.TreeMap; /** * Azure Compute sample for managing virtual machines - * - Create a virtual machine with managed OS Disk based on Windows OS image * - Once Network is created start creation of virtual machine based on Linux OS image in the same network * - Update both virtual machines in parallel * - for Linux based: * - add Tag * - for Windows based: * - add a data disk * - List virtual machines and print details * - Delete all virtual machines. */ public final class ManageVirtualMachineAsync { /** * Main function which runs the actual sample. * @param azure instance of the azure client * @return true if sample runs successfully */ public static boolean runSample(final Azure azure) { final Region region = Region.US_WEST_CENTRAL; final String windowsVMName = Utils.createRandomName("wVM"); final String linuxVMName = Utils.createRandomName("lVM"); final String rgName = Utils.createRandomName("rgCOMV"); final String userName = "tirekicker"; final String password = "12NewPA$$w0rd!"; final String windowsVmKey = "WindowsVM"; final String linuxVmKey = "LinuxVM"; try { //============================================================= // Create a Windows virtual machine // Prepare a creatable data disk for VM // final Date t1 = new Date(); final Creatable<Disk> dataDiskCreatable = azure.disks().define(Utils.createRandomName("dsk-")) .withRegion(region) .withExistingResourceGroup(rgName) .withData() .withSizeInGB(100); // Create a data disk to attach to VM // Observable<Indexable> dataDiskObservable = azure.disks().define(Utils.createRandomName("dsk-")) .withRegion(region) .withNewResourceGroup(rgName) .withData() .withSizeInGB(50) .createAsync(); final Map<String, VirtualMachine> createdVms = new TreeMap<>(); dataDiskObservable.flatMap(new Func1<Indexable, Observable<Indexable>>() { @Override public Observable<Indexable> call(Indexable createdResource) { if (createdResource instanceof Disk) { System.out.println("Creating a Windows VM"); return azure.virtualMachines().define(windowsVMName) .withRegion(region) .withNewResourceGroup(rgName) .withNewPrimaryNetwork("10.0.0.0/28") .withPrimaryPrivateIPAddressDynamic() .withoutPrimaryPublicIPAddress() .withPopularWindowsImage(KnownWindowsVirtualMachineImage.WINDOWS_SERVER_2012_R2_DATACENTER) .withAdminUsername(userName) .withAdminPassword(password) .withNewDataDisk(10) .withNewDataDisk(dataDiskCreatable) .withExistingDataDisk((Disk) createdResource) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .createAsync(); } return Observable.just(createdResource); } }).flatMap(new Func1<Indexable, Observable<Indexable>>() { @Override public Observable<Indexable> call(Indexable createdResource) { if (createdResource instanceof Network) { // Once Network object is created we can start creation of Linux VM in the same network Network network = (Network) createdResource; System.out.println("Created Network"); Utils.print(network); System.out.println("Creating a Linux VM in the same network"); return azure.virtualMachines().define(linuxVMName) .withRegion(region) .withExistingResourceGroup(rgName) .withExistingPrimaryNetwork(network) .withSubnet("subnet1") // Referencing the default subnet name when no name specified at creation .withPrimaryPrivateIPAddressDynamic() .withoutPrimaryPublicIPAddress() .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_16_04_LTS) .withRootUsername(userName) .withRootPassword(password) .withSize(VirtualMachineSizeTypes.STANDARD_D3_V2) .createAsync(); } return Observable.just(createdResource); } }).map(new Func1<Indexable, Indexable>() { @Override public Indexable call(Indexable createdResource) { if (createdResource instanceof VirtualMachine) { Date t2 = new Date(); VirtualMachine virtualMachine = (VirtualMachine) createdResource; if (isWindowsVM(virtualMachine)) { createdVms.put(windowsVmKey, virtualMachine); System.out.println("Created Windows VM: " + virtualMachine.id()); } else { createdVms.put(linuxVmKey, virtualMachine); System.out.println("Created a Linux VM (in the same virtual network): " + virtualMachine.id()); } System.out.println("Virtual machine creation took " + ((t2.getTime() - t1.getTime()) / 1000) + " seconds"); // Print virtual machine details Utils.print(virtualMachine); } return createdResource; } }).toBlocking().subscribe(); final VirtualMachine windowsVM = createdVms.get(windowsVmKey); final VirtualMachine linuxVM = createdVms.get(linuxVmKey); //============================================================= // Update virtual machines // - Tag the virtual machine on Linux VM Observable<VirtualMachine> updateLinuxVMChain = linuxVM.update() .withTag("who-rocks-on-linux", "java") .withTag("where", "on azure") .applyAsync() .map(new Func1<VirtualMachine, VirtualMachine>() { @Override public VirtualMachine call(VirtualMachine virtualMachine) { System.out.println("Tagged Linux VM: " + virtualMachine.id()); return virtualMachine; } }); // - Add a data disk on Windows VM. Observable<VirtualMachine> updateWindowsVMChain = windowsVM.update() .withNewDataDisk(200) .applyAsync(); Observable.merge(updateLinuxVMChain, updateWindowsVMChain) .toBlocking().subscribe(); //============================================================= // List virtual machines and print details azure.virtualMachines().listByResourceGroupAsync(rgName) .map(new Func1<VirtualMachine, VirtualMachine>() { @Override public VirtualMachine call(VirtualMachine virtualMachine) { System.out.println("Retrieved details for VM: " + virtualMachine.id()); Utils.print(virtualMachine); return virtualMachine; } }).toBlocking().subscribe(); //============================================================= // Delete the virtual machines in parallel Observable.merge( azure.virtualMachines().deleteByIdAsync(windowsVM.id()).toObservable(), azure.virtualMachines().deleteByIdAsync(linuxVM.id()).toObservable()) .toBlocking().subscribe(); return true; } catch (Exception f) { System.out.println(f.getMessage()); f.printStackTrace(); } finally { try { System.out.println("Deleting Resource Group: " + rgName); azure.resourceGroups().deleteByNameAsync(rgName) .await(); System.out.println("Deleted Resource Group: " + rgName); } catch (NullPointerException npe) { System.out.println("Did not create any resources in Azure. No clean up is necessary"); } catch (Exception g) { g.printStackTrace(); } } return false; } private static boolean isWindowsVM(VirtualMachine vm) { if (vm != null && vm.osProfile() != null && vm.osProfile().windowsConfiguration() != null) { return true; } return false; } /** * Main entry point. * @param args the parameters */ public static void main(String[] args) { try { //============================================================= // Authenticate final File credFile = new File(System.getenv("AZURE_AUTH_LOCATION")); Azure azure = Azure.configure() .withLogLevel(LogLevel.BASIC) .authenticate(credFile) .withDefaultSubscription(); // Print selected subscription System.out.println("Selected subscription: " + azure.subscriptionId()); runSample(azure); } catch (Exception e) { System.out.println(e.getMessage()); e.printStackTrace(); } } private ManageVirtualMachineAsync() { } }