com.azure.resourcemanager.compute.implementation.VirtualMachineImpl Maven / Gradle / Ivy
Show all versions of azure-resourcemanager-compute Show documentation
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package com.azure.resourcemanager.compute.implementation;
import com.azure.core.http.rest.PagedIterable;
import com.azure.core.management.AzureEnvironment;
import com.azure.core.management.SubResource;
import com.azure.core.management.provider.IdentifierProvider;
import com.azure.core.management.serializer.SerializerFactory;
import com.azure.core.util.Context;
import com.azure.core.util.CoreUtils;
import com.azure.core.util.logging.ClientLogger;
import com.azure.core.util.serializer.SerializerAdapter;
import com.azure.core.util.serializer.SerializerEncoding;
import com.azure.resourcemanager.authorization.AuthorizationManager;
import com.azure.resourcemanager.authorization.models.BuiltInRole;
import com.azure.resourcemanager.authorization.utils.RoleAssignmentHelper;
import com.azure.resourcemanager.compute.ComputeManager;
import com.azure.resourcemanager.compute.fluent.models.ProximityPlacementGroupInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineCaptureResultInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineInner;
import com.azure.resourcemanager.compute.fluent.models.VirtualMachineUpdateInner;
import com.azure.resourcemanager.compute.models.AdditionalCapabilities;
import com.azure.resourcemanager.compute.models.AvailabilitySet;
import com.azure.resourcemanager.compute.models.AvailabilitySetSkuTypes;
import com.azure.resourcemanager.compute.models.BillingProfile;
import com.azure.resourcemanager.compute.models.BootDiagnostics;
import com.azure.resourcemanager.compute.models.CachingTypes;
import com.azure.resourcemanager.compute.models.DataDisk;
import com.azure.resourcemanager.compute.models.DeleteOptions;
import com.azure.resourcemanager.compute.models.DiagnosticsProfile;
import com.azure.resourcemanager.compute.models.DiffDiskOptions;
import com.azure.resourcemanager.compute.models.DiffDiskPlacement;
import com.azure.resourcemanager.compute.models.DiffDiskSettings;
import com.azure.resourcemanager.compute.models.Disk;
import com.azure.resourcemanager.compute.models.DiskCreateOptionTypes;
import com.azure.resourcemanager.compute.models.DiskDeleteOptionTypes;
import com.azure.resourcemanager.compute.models.DiskEncryptionSetParameters;
import com.azure.resourcemanager.compute.models.DiskEncryptionSettings;
import com.azure.resourcemanager.compute.models.HardwareProfile;
import com.azure.resourcemanager.compute.models.ImageReference;
import com.azure.resourcemanager.compute.models.InstanceViewTypes;
import com.azure.resourcemanager.compute.models.KnownLinuxVirtualMachineImage;
import com.azure.resourcemanager.compute.models.KnownWindowsVirtualMachineImage;
import com.azure.resourcemanager.compute.models.LinuxConfiguration;
import com.azure.resourcemanager.compute.models.ManagedDiskParameters;
import com.azure.resourcemanager.compute.models.NetworkInterfaceReference;
import com.azure.resourcemanager.compute.models.OSDisk;
import com.azure.resourcemanager.compute.models.OSProfile;
import com.azure.resourcemanager.compute.models.OperatingSystemTypes;
import com.azure.resourcemanager.compute.models.Plan;
import com.azure.resourcemanager.compute.models.PowerState;
import com.azure.resourcemanager.compute.models.ProximityPlacementGroup;
import com.azure.resourcemanager.compute.models.ProximityPlacementGroupType;
import com.azure.resourcemanager.compute.models.PurchasePlan;
import com.azure.resourcemanager.compute.models.ResourceIdentityType;
import com.azure.resourcemanager.compute.models.RunCommandInput;
import com.azure.resourcemanager.compute.models.RunCommandInputParameter;
import com.azure.resourcemanager.compute.models.RunCommandResult;
import com.azure.resourcemanager.compute.models.SecurityProfile;
import com.azure.resourcemanager.compute.models.SecurityTypes;
import com.azure.resourcemanager.compute.models.SshConfiguration;
import com.azure.resourcemanager.compute.models.SshPublicKey;
import com.azure.resourcemanager.compute.models.StorageAccountTypes;
import com.azure.resourcemanager.compute.models.StorageProfile;
import com.azure.resourcemanager.compute.models.UefiSettings;
import com.azure.resourcemanager.compute.models.VirtualHardDisk;
import com.azure.resourcemanager.compute.models.VirtualMachine;
import com.azure.resourcemanager.compute.models.VirtualMachineCaptureParameters;
import com.azure.resourcemanager.compute.models.VirtualMachineCustomImage;
import com.azure.resourcemanager.compute.models.VirtualMachineDataDisk;
import com.azure.resourcemanager.compute.models.VirtualMachineDiskOptions;
import com.azure.resourcemanager.compute.models.VirtualMachineEncryption;
import com.azure.resourcemanager.compute.models.VirtualMachineEvictionPolicyTypes;
import com.azure.resourcemanager.compute.models.VirtualMachineExtension;
import com.azure.resourcemanager.compute.models.VirtualMachineIdentity;
import com.azure.resourcemanager.compute.models.VirtualMachineInstanceView;
import com.azure.resourcemanager.compute.models.VirtualMachinePriorityTypes;
import com.azure.resourcemanager.compute.models.VirtualMachineScaleSet;
import com.azure.resourcemanager.compute.models.VirtualMachineSize;
import com.azure.resourcemanager.compute.models.VirtualMachineSizeTypes;
import com.azure.resourcemanager.compute.models.VirtualMachineUnmanagedDataDisk;
import com.azure.resourcemanager.compute.models.WinRMConfiguration;
import com.azure.resourcemanager.compute.models.WinRMListener;
import com.azure.resourcemanager.compute.models.WindowsConfiguration;
import com.azure.resourcemanager.msi.models.Identity;
import com.azure.resourcemanager.network.NetworkManager;
import com.azure.resourcemanager.network.models.Network;
import com.azure.resourcemanager.network.models.NetworkInterface;
import com.azure.resourcemanager.network.models.PublicIPSkuType;
import com.azure.resourcemanager.network.models.PublicIpAddress;
import com.azure.resourcemanager.resources.fluentcore.arm.AvailabilityZoneId;
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceId;
import com.azure.resourcemanager.resources.fluentcore.arm.ResourceUtils;
import com.azure.resourcemanager.resources.fluentcore.arm.models.implementation.GroupableResourceImpl;
import com.azure.resourcemanager.resources.fluentcore.model.Accepted;
import com.azure.resourcemanager.resources.fluentcore.model.Creatable;
import com.azure.resourcemanager.resources.fluentcore.model.Indexable;
import com.azure.resourcemanager.resources.fluentcore.model.implementation.AcceptedImpl;
import com.azure.resourcemanager.resources.fluentcore.utils.PagedConverter;
import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils;
import com.azure.resourcemanager.storage.StorageManager;
import com.azure.resourcemanager.storage.models.StorageAccount;
import reactor.core.Exceptions;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
/** The implementation for VirtualMachine and its create and update interfaces. */
class VirtualMachineImpl
extends GroupableResourceImpl
implements VirtualMachine,
VirtualMachine.DefinitionManagedOrUnmanaged,
VirtualMachine.DefinitionManaged,
VirtualMachine.DefinitionUnmanaged,
VirtualMachine.Update,
VirtualMachine.DefinitionStages.WithSystemAssignedIdentityBasedAccessOrCreate,
VirtualMachine.UpdateStages.WithSystemAssignedIdentityBasedAccessOrUpdate {
private final ClientLogger logger = new ClientLogger(VirtualMachineImpl.class);
// Clients
private final StorageManager storageManager;
private final NetworkManager networkManager;
private final AuthorizationManager authorizationManager;
// the name of the virtual machine
private final String vmName;
// used to generate unique name for any dependency resources
private final IdentifierProvider namer;
// unique key of a creatable storage account to be used for virtual machine child resources that
// requires storage [OS disk, data disk, boot diagnostics etc..]
private String creatableStorageAccountKey;
// unique key of a creatable availability set that this virtual machine to put
private String creatableAvailabilitySetKey;
// unique key of a creatable network interface that needs to be used as virtual machine's primary network interface
private String creatablePrimaryNetworkInterfaceKey;
// unique key of a creatable network interfaces that needs to be used as virtual machine's secondary network
// interface
private List creatableSecondaryNetworkInterfaceKeys;
// reference to an existing storage account to be used for virtual machine child resources that
// requires storage [OS disk, data disk, boot diagnostics etc..]
private StorageAccount existingStorageAccountToAssociate;
// reference to an existing availability set that this virtual machine to put
private AvailabilitySet existingAvailabilitySetToAssociate;
// reference to an existing network interface that needs to be used as virtual machine's primary network interface
private NetworkInterface existingPrimaryNetworkInterfaceToAssociate;
// reference to a list of existing network interfaces that needs to be used as virtual machine's secondary network
// interface
private List existingSecondaryNetworkInterfacesToAssociate;
private VirtualMachineInstanceView virtualMachineInstanceView;
private boolean isMarketplaceLinuxImage;
// Intermediate state of network interface definition to which private IP can be associated
private NetworkInterface.DefinitionStages.WithPrimaryPrivateIP nicDefinitionWithPrivateIp;
// Intermediate state of network interface definition to which subnet can be associated
private NetworkInterface.DefinitionStages.WithPrimaryNetworkSubnet nicDefinitionWithSubnet;
// Intermediate state of network interface definition to which public IP can be associated
private NetworkInterface.DefinitionStages.WithCreate nicDefinitionWithCreate;
// The entry point to manage extensions associated with the virtual machine
private VirtualMachineExtensionsImpl virtualMachineExtensions;
// Flag indicates native disk is selected for OS and Data disks
private boolean isUnmanagedDiskSelected;
// Error messages
// The native data disks associated with the virtual machine
private List unmanagedDataDisks;
// To track the managed data disks
private final ManagedDataDiskCollection managedDataDisks;
// To manage boot diagnostics specific operations
private final BootDiagnosticsHandler bootDiagnosticsHandler;
// Utility to setup MSI for the virtual machine
private VirtualMachineMsiHandler virtualMachineMsiHandler;
// Reference to the PublicIp creatable that is implicitly created
private PublicIpAddress.DefinitionStages.WithCreate implicitPipCreatable;
// Name of the new proximity placement group
private String newProximityPlacementGroupName;
// Type fo the new proximity placement group
private ProximityPlacementGroupType newProximityPlacementGroupType;
// To manage OS profile
private boolean removeOsProfile;
// delete option for primary network interface
private DeleteOptions primaryNetworkInterfaceDeleteOptions;
// delete options for secondary network interface
private final Map secondaryNetworkInterfaceDeleteOptions = new HashMap<>();
// Snapshot of the updateParameter when update() is called, used to compare whether there is modification to VM during updateResourceAsync
private VirtualMachineUpdateInner updateParameterSnapshotOnUpdate;
private static final SerializerAdapter SERIALIZER_ADAPTER =
SerializerFactory.createDefaultManagementSerializerAdapter();
VirtualMachineImpl(
String name,
VirtualMachineInner innerModel,
final ComputeManager computeManager,
final StorageManager storageManager,
final NetworkManager networkManager,
final AuthorizationManager authorizationManager) {
super(name, innerModel, computeManager);
this.storageManager = storageManager;
this.networkManager = networkManager;
this.authorizationManager = authorizationManager;
this.vmName = name;
this.isMarketplaceLinuxImage = false;
this.namer = this.manager().resourceManager().internalContext().createIdentifierProvider(this.vmName);
this.creatableSecondaryNetworkInterfaceKeys = new ArrayList<>();
this.existingSecondaryNetworkInterfacesToAssociate = new ArrayList<>();
this.virtualMachineExtensions =
new VirtualMachineExtensionsImpl(computeManager.serviceClient().getVirtualMachineExtensions(), this);
this.managedDataDisks = new ManagedDataDiskCollection(this);
initializeDataDisks();
this.bootDiagnosticsHandler = new BootDiagnosticsHandler(this);
this.virtualMachineMsiHandler = new VirtualMachineMsiHandler(authorizationManager, this);
this.newProximityPlacementGroupName = null;
this.newProximityPlacementGroupType = null;
}
// Verbs
@Override
public VirtualMachineImpl update() {
updateParameterSnapshotOnUpdate = this.deepCopyInnerToUpdateParameter();
return super.update();
}
@Override
public Mono refreshAsync() {
return super
.refreshAsync()
.map(
virtualMachine -> {
reset(virtualMachine.innerModel());
virtualMachineExtensions.refresh();
return virtualMachine;
});
}
@Override
protected Mono getInnerAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.getByResourceGroupAsync(this.resourceGroupName(), this.name());
}
@Override
public void deallocate() {
this.deallocateAsync().block();
}
@Override
public Mono deallocateAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.deallocateAsync(this.resourceGroupName(), this.name())
// Refresh after deallocate to ensure the inner is updatable (due to a change in behavior in Managed Disks)
.map(aVoid -> this.refreshAsync())
.then();
}
@Override
public void deallocate(boolean hibernate) {
this.deallocateAsync(hibernate).block();
}
@Override
public Mono deallocateAsync(boolean hibernate) {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.deallocateAsync(this.resourceGroupName(), this.name(), hibernate)
// Refresh after deallocate to ensure the inner is updatable (due to a change in behavior in Managed Disks)
.map(aVoid -> this.refreshAsync())
.then();
}
@Override
public void generalize() {
this.generalizeAsync().block();
}
@Override
public Mono generalizeAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.generalizeAsync(this.resourceGroupName(), this.name());
}
@Override
public void powerOff() {
this.powerOffAsync().block();
}
@Override
public Mono powerOffAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.powerOffAsync(this.resourceGroupName(), this.name(), null);
}
@Override
public void powerOff(boolean skipShutdown) {
this.powerOffAsync(skipShutdown).block();
}
@Override
public Mono powerOffAsync(boolean skipShutdown) {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.powerOffAsync(this.resourceGroupName(), this.name(), skipShutdown);
}
@Override
public void restart() {
this.restartAsync().block();
}
@Override
public Mono restartAsync() {
return this.manager().serviceClient().getVirtualMachines().restartAsync(this.resourceGroupName(), this.name());
}
@Override
public void start() {
this.startAsync().block();
}
@Override
public Mono startAsync() {
return this.manager().serviceClient().getVirtualMachines().startAsync(this.resourceGroupName(), this.name());
}
@Override
public void redeploy() {
this.redeployAsync().block();
}
@Override
public Mono redeployAsync() {
return this.manager().serviceClient().getVirtualMachines().redeployAsync(this.resourceGroupName(), this.name());
}
@Override
public void simulateEviction() {
this.simulateEvictionAsync().block();
}
@Override
public Mono simulateEvictionAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.simulateEvictionAsync(this.resourceGroupName(), this.name());
}
@Override
public void convertToManaged() {
this
.manager()
.serviceClient()
.getVirtualMachines()
.convertToManagedDisks(this.resourceGroupName(), this.name());
this.refresh();
}
@Override
public Mono convertToManagedAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.convertToManagedDisksAsync(this.resourceGroupName(), this.name())
.flatMap(aVoid -> refreshAsync())
.then();
}
@Override
public VirtualMachineEncryption diskEncryption() {
return new VirtualMachineEncryptionImpl(this);
}
@Override
public PagedIterable availableSizes() {
return PagedConverter.mapPage(this
.manager()
.serviceClient()
.getVirtualMachines()
.listAvailableSizes(this.resourceGroupName(), this.name()),
VirtualMachineSizeImpl::new);
}
@Override
public String capture(String containerName, String vhdPrefix, boolean overwriteVhd) {
return this.captureAsync(containerName, vhdPrefix, overwriteVhd).block();
}
@Override
public Mono captureAsync(String containerName, String vhdPrefix, boolean overwriteVhd) {
VirtualMachineCaptureParameters parameters = new VirtualMachineCaptureParameters();
parameters.withDestinationContainerName(containerName);
parameters.withOverwriteVhds(overwriteVhd);
parameters.withVhdPrefix(vhdPrefix);
return this
.manager()
.serviceClient()
.getVirtualMachines()
.captureAsync(this.resourceGroupName(), this.name(), parameters)
.map(captureResult -> serializeCaptureResult(captureResult, logger));
}
@Override
public VirtualMachineInstanceView refreshInstanceView() {
return refreshInstanceViewAsync().block();
}
@Override
public Mono refreshInstanceViewAsync() {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.getByResourceGroupWithResponseAsync(
this.resourceGroupName(), this.name(), InstanceViewTypes.INSTANCE_VIEW)
.map(
inner -> {
virtualMachineInstanceView = new VirtualMachineInstanceViewImpl(inner.getValue().instanceView());
return virtualMachineInstanceView;
})
.switchIfEmpty(
Mono
.defer(
() -> {
virtualMachineInstanceView = null;
return Mono.empty();
}));
}
@Override
public RunCommandResult runPowerShellScript(
List scriptLines, List scriptParameters) {
return this
.manager()
.virtualMachines()
.runPowerShellScript(this.resourceGroupName(), this.name(), scriptLines, scriptParameters);
}
@Override
public Mono runPowerShellScriptAsync(
List scriptLines, List scriptParameters) {
return this
.manager()
.virtualMachines()
.runPowerShellScriptAsync(this.resourceGroupName(), this.name(), scriptLines, scriptParameters);
}
@Override
public RunCommandResult runShellScript(List scriptLines, List scriptParameters) {
return this
.manager()
.virtualMachines()
.runShellScript(this.resourceGroupName(), this.name(), scriptLines, scriptParameters);
}
@Override
public Mono runShellScriptAsync(
List scriptLines, List scriptParameters) {
return this
.manager()
.virtualMachines()
.runShellScriptAsync(this.resourceGroupName(), this.name(), scriptLines, scriptParameters);
}
@Override
public RunCommandResult runCommand(RunCommandInput inputCommand) {
return this.manager().virtualMachines().runCommand(this.resourceGroupName(), this.name(), inputCommand);
}
@Override
public Mono runCommandAsync(RunCommandInput inputCommand) {
return this.manager().virtualMachines().runCommandAsync(this.resourceGroupName(), this.name(), inputCommand);
}
// SETTERS
// Fluent methods for defining virtual network association for the new primary network interface
@Override
public VirtualMachineImpl withNewPrimaryNetwork(Creatable creatable) {
this.nicDefinitionWithPrivateIp =
this.preparePrimaryNetworkInterface(this.namer.getRandomName("nic", 20)).withNewPrimaryNetwork(creatable);
return this;
}
@Override
public VirtualMachineImpl withNewPrimaryNetwork(String addressSpace) {
this.nicDefinitionWithPrivateIp =
this
.preparePrimaryNetworkInterface(this.namer.getRandomName("nic", 20))
.withNewPrimaryNetwork(addressSpace);
return this;
}
@Override
public VirtualMachineImpl withExistingPrimaryNetwork(Network network) {
this.nicDefinitionWithSubnet =
this
.preparePrimaryNetworkInterface(this.namer.getRandomName("nic", 20))
.withExistingPrimaryNetwork(network);
return this;
}
@Override
public VirtualMachineImpl withSubnet(String name) {
this.nicDefinitionWithPrivateIp = this.nicDefinitionWithSubnet.withSubnet(name);
return this;
}
// Fluent methods for defining private IP association for the new primary network interface
@Override
public VirtualMachineImpl withPrimaryPrivateIPAddressDynamic() {
this.nicDefinitionWithCreate = this.nicDefinitionWithPrivateIp.withPrimaryPrivateIPAddressDynamic();
return this;
}
@Override
public VirtualMachineImpl withPrimaryPrivateIPAddressStatic(String staticPrivateIPAddress) {
this.nicDefinitionWithCreate =
this.nicDefinitionWithPrivateIp.withPrimaryPrivateIPAddressStatic(staticPrivateIPAddress);
return this;
}
// Fluent methods for defining public IP association for the new primary network interface
@Override
public VirtualMachineImpl withNewPrimaryPublicIPAddress(Creatable creatable) {
Creatable nicCreatable =
this.nicDefinitionWithCreate.withNewPrimaryPublicIPAddress(creatable);
this.creatablePrimaryNetworkInterfaceKey = this.addDependency(nicCreatable);
return this;
}
@Override
public VirtualMachineImpl withNewPrimaryPublicIPAddress(String leafDnsLabel) {
return withNewPrimaryPublicIPAddress(leafDnsLabel, null);
}
// @Override
public VirtualMachineImpl withNewPrimaryPublicIPAddress(String leafDnsLabel, DeleteOptions deleteOptions) {
PublicIpAddress.DefinitionStages.WithGroup definitionWithGroup =
this
.networkManager
.publicIpAddresses()
.define(this.namer.getRandomName("pip", 15))
.withRegion(this.regionName());
PublicIpAddress.DefinitionStages.WithCreate definitionAfterGroup;
if (this.creatableGroup != null) {
definitionAfterGroup = definitionWithGroup.withNewResourceGroup(this.creatableGroup);
} else {
definitionAfterGroup = definitionWithGroup.withExistingResourceGroup(this.resourceGroupName());
}
this.implicitPipCreatable = definitionAfterGroup.withLeafDomainLabel(leafDnsLabel);
// if (deleteOptions != null) {
// this.implicitPipCreatable = this.implicitPipCreatable.withDeleteOptions(
// com.azure.resourcemanager.network.models.DeleteOptions.fromString(deleteOptions.toString()));
// }
// Create NIC with creatable PIP
Creatable nicCreatable =
this.nicDefinitionWithCreate.withNewPrimaryPublicIPAddress(this.implicitPipCreatable);
this.creatablePrimaryNetworkInterfaceKey = this.addDependency(nicCreatable);
return this;
}
@Override
public VirtualMachineImpl withExistingPrimaryPublicIPAddress(PublicIpAddress publicIPAddress) {
Creatable nicCreatable =
this.nicDefinitionWithCreate.withExistingPrimaryPublicIPAddress(publicIPAddress);
this.creatablePrimaryNetworkInterfaceKey = this.addDependency(nicCreatable);
return this;
}
@Override
public VirtualMachineImpl withoutPrimaryPublicIPAddress() {
Creatable nicCreatable = this.nicDefinitionWithCreate;
this.creatablePrimaryNetworkInterfaceKey = this.addDependency(nicCreatable);
return this;
}
// Virtual machine primary network interface specific fluent methods
//
@Override
public VirtualMachineImpl withNewPrimaryNetworkInterface(Creatable creatable) {
this.creatablePrimaryNetworkInterfaceKey = this.addDependency(creatable);
return this;
}
public VirtualMachineImpl withNewPrimaryNetworkInterface(String name, String publicDnsNameLabel) {
Creatable definitionCreatable =
prepareNetworkInterface(name).withNewPrimaryPublicIPAddress(publicDnsNameLabel);
return withNewPrimaryNetworkInterface(definitionCreatable);
}
@Override
public VirtualMachineImpl withExistingPrimaryNetworkInterface(NetworkInterface networkInterface) {
this.existingPrimaryNetworkInterfaceToAssociate = networkInterface;
return this;
}
// Virtual machine image specific fluent methods
//
@Override
public VirtualMachineImpl withStoredWindowsImage(String imageUrl) {
VirtualHardDisk userImageVhd = new VirtualHardDisk();
userImageVhd.withUri(imageUrl);
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
this.innerModel().storageProfile().osDisk().withImage(userImageVhd);
// For platform image osType will be null, azure will pick it from the image metadata.
this.innerModel().storageProfile().osDisk().withOsType(OperatingSystemTypes.WINDOWS);
this.innerModel().osProfile().withWindowsConfiguration(new WindowsConfiguration());
// sets defaults for "Stored(User)Image" or "VM(Platform)Image"
this.innerModel().osProfile().windowsConfiguration().withProvisionVMAgent(true);
this.innerModel().osProfile().windowsConfiguration().withEnableAutomaticUpdates(true);
return this;
}
@Override
public VirtualMachineImpl withStoredLinuxImage(String imageUrl) {
VirtualHardDisk userImageVhd = new VirtualHardDisk();
userImageVhd.withUri(imageUrl);
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
this.innerModel().storageProfile().osDisk().withImage(userImageVhd);
// For platform | custom image osType will be null, azure will pick it from the image metadata.
// But for stored image, osType needs to be specified explicitly
this.innerModel().storageProfile().osDisk().withOsType(OperatingSystemTypes.LINUX);
this.innerModel().osProfile().withLinuxConfiguration(new LinuxConfiguration());
return this;
}
@Override
public VirtualMachineImpl withPopularWindowsImage(KnownWindowsVirtualMachineImage knownImage) {
return withSpecificWindowsImageVersion(knownImage.imageReference());
}
@Override
public VirtualMachineImpl withPopularLinuxImage(KnownLinuxVirtualMachineImage knownImage) {
return withSpecificLinuxImageVersion(knownImage.imageReference());
}
@Override
public VirtualMachineImpl withSpecificWindowsImageVersion(ImageReference imageReference) {
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
this.innerModel().storageProfile().withImageReference(imageReference);
this.innerModel().osProfile().withWindowsConfiguration(new WindowsConfiguration());
// sets defaults for "Stored(User)Image" or "VM(Platform)Image"
this.innerModel().osProfile().windowsConfiguration().withProvisionVMAgent(true);
this.innerModel().osProfile().windowsConfiguration().withEnableAutomaticUpdates(true);
return this;
}
@Override
public VirtualMachineImpl withSpecificLinuxImageVersion(ImageReference imageReference) {
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
this.innerModel().storageProfile().withImageReference(imageReference);
this.innerModel().osProfile().withLinuxConfiguration(new LinuxConfiguration());
this.isMarketplaceLinuxImage = true;
return this;
}
@Override
public VirtualMachineImpl withLatestWindowsImage(String publisher, String offer, String sku) {
ImageReference imageReference = new ImageReference();
imageReference.withPublisher(publisher);
imageReference.withOffer(offer);
imageReference.withSku(sku);
imageReference.withVersion("latest");
return withSpecificWindowsImageVersion(imageReference);
}
@Override
public VirtualMachineImpl withLatestLinuxImage(String publisher, String offer, String sku) {
ImageReference imageReference = new ImageReference();
imageReference.withPublisher(publisher);
imageReference.withOffer(offer);
imageReference.withSku(sku);
imageReference.withVersion("latest");
return withSpecificLinuxImageVersion(imageReference);
}
@Override
public VirtualMachineImpl withGeneralizedWindowsCustomImage(String customImageId) {
ImageReference imageReferenceInner = new ImageReference();
imageReferenceInner.withId(customImageId);
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
this.innerModel().storageProfile().withImageReference(imageReferenceInner);
this.innerModel().osProfile().withWindowsConfiguration(new WindowsConfiguration());
// sets defaults for "Stored(User)Image", "VM(Platform | Custom | Gallery)Image"
this.innerModel().osProfile().windowsConfiguration().withProvisionVMAgent(true);
this.innerModel().osProfile().windowsConfiguration().withEnableAutomaticUpdates(true);
return this;
}
@Override
public VirtualMachineImpl withSpecializedWindowsCustomImage(String customImageId) {
this.withGeneralizedWindowsCustomImage(customImageId);
this.removeOsProfile = true;
return this;
}
@Override
public VirtualMachineImpl withGeneralizedWindowsGalleryImageVersion(String galleryImageVersionId) {
return this.withGeneralizedWindowsCustomImage(galleryImageVersionId);
}
@Override
public VirtualMachineImpl withSpecializedWindowsGalleryImageVersion(String galleryImageVersionId) {
return this.withSpecializedWindowsCustomImage(galleryImageVersionId);
}
@Override
public VirtualMachineImpl withGeneralizedLinuxCustomImage(String customImageId) {
ImageReference imageReferenceInner = new ImageReference();
imageReferenceInner.withId(customImageId);
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
this.innerModel().storageProfile().withImageReference(imageReferenceInner);
this.innerModel().osProfile().withLinuxConfiguration(new LinuxConfiguration());
this.isMarketplaceLinuxImage = true;
return this;
}
@Override
public VirtualMachineImpl withSpecializedLinuxCustomImage(String customImageId) {
this.withGeneralizedLinuxCustomImage(customImageId);
this.removeOsProfile = true;
return this;
}
@Override
public VirtualMachineImpl withGeneralizedLinuxGalleryImageVersion(String galleryImageVersionId) {
return this.withGeneralizedLinuxCustomImage(galleryImageVersionId);
}
@Override
public VirtualMachineImpl withSpecializedLinuxGalleryImageVersion(String galleryImageVersionId) {
return this.withSpecializedLinuxCustomImage(galleryImageVersionId);
}
@Override
public VirtualMachineImpl withSpecializedOSUnmanagedDisk(String osDiskUrl, OperatingSystemTypes osType) {
VirtualHardDisk osVhd = new VirtualHardDisk();
osVhd.withUri(osDiskUrl);
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.ATTACH);
this.innerModel().storageProfile().osDisk().withVhd(osVhd);
this.innerModel().storageProfile().osDisk().withOsType(osType);
this.innerModel().storageProfile().osDisk().withManagedDisk(null);
return this;
}
@Override
public VirtualMachineImpl withSpecializedOSDisk(Disk disk, OperatingSystemTypes osType) {
ManagedDiskParameters diskParametersInner = new ManagedDiskParameters();
diskParametersInner.withId(disk.id());
this.innerModel().storageProfile().osDisk().withCreateOption(DiskCreateOptionTypes.ATTACH);
this.innerModel().storageProfile().osDisk().withManagedDisk(diskParametersInner);
this.innerModel().storageProfile().osDisk().withOsType(osType);
this.innerModel().storageProfile().osDisk().withVhd(null);
return this;
}
// Virtual machine user name fluent methods
@Override
public VirtualMachineImpl withRootUsername(String rootUserName) {
this.innerModel().osProfile().withAdminUsername(rootUserName);
return this;
}
@Override
public VirtualMachineImpl withAdminUsername(String adminUserName) {
this.innerModel().osProfile().withAdminUsername(adminUserName);
return this;
}
// Virtual machine optional fluent methods
@Override
public VirtualMachineImpl withSsh(String publicKeyData) {
OSProfile osProfile = this.innerModel().osProfile();
if (osProfile.linuxConfiguration().ssh() == null) {
SshConfiguration sshConfiguration = new SshConfiguration();
sshConfiguration.withPublicKeys(new ArrayList());
osProfile.linuxConfiguration().withSsh(sshConfiguration);
}
SshPublicKey sshPublicKey = new SshPublicKey();
sshPublicKey.withKeyData(publicKeyData);
sshPublicKey.withPath("/home/" + osProfile.adminUsername() + "/.ssh/authorized_keys");
osProfile.linuxConfiguration().ssh().publicKeys().add(sshPublicKey);
return this;
}
@Override
public VirtualMachineImpl withoutVMAgent() {
this.innerModel().osProfile().windowsConfiguration().withProvisionVMAgent(false);
return this;
}
@Override
public VirtualMachineImpl withoutAutoUpdate() {
this.innerModel().osProfile().windowsConfiguration().withEnableAutomaticUpdates(false);
return this;
}
@Override
public VirtualMachineImpl withTimeZone(String timeZone) {
this.innerModel().osProfile().windowsConfiguration().withTimeZone(timeZone);
return this;
}
@Override
public VirtualMachineImpl withWinRM(WinRMListener listener) {
if (this.innerModel().osProfile().windowsConfiguration().winRM() == null) {
WinRMConfiguration winRMConfiguration = new WinRMConfiguration();
this.innerModel().osProfile().windowsConfiguration().withWinRM(winRMConfiguration);
}
this.innerModel().osProfile().windowsConfiguration().winRM().listeners().add(listener);
return this;
}
@Override
public VirtualMachineImpl withRootPassword(String password) {
this.innerModel().osProfile().withAdminPassword(password);
return this;
}
@Override
public VirtualMachineImpl withAdminPassword(String password) {
this.innerModel().osProfile().withAdminPassword(password);
return this;
}
@Override
public VirtualMachineImpl withCustomData(String base64EncodedCustomData) {
this.innerModel().osProfile().withCustomData(base64EncodedCustomData);
return this;
}
@Override
public VirtualMachineImpl withUserData(String base64EncodedUserData) {
this.innerModel().withUserData(base64EncodedUserData);
return this;
}
@Override
public VirtualMachineImpl withComputerName(String computerName) {
this.innerModel().osProfile().withComputerName(computerName);
return this;
}
@Override
public VirtualMachineImpl withSize(String sizeName) {
this.innerModel().hardwareProfile().withVmSize(VirtualMachineSizeTypes.fromString(sizeName));
return this;
}
@Override
public VirtualMachineImpl withSize(VirtualMachineSizeTypes size) {
this.innerModel().hardwareProfile().withVmSize(size);
return this;
}
@Override
public VirtualMachineImpl withOSDiskCaching(CachingTypes cachingType) {
this.innerModel().storageProfile().osDisk().withCaching(cachingType);
return this;
}
@Override
public VirtualMachineImpl withOSDiskVhdLocation(String containerName, String vhdName) {
// Sets the native (un-managed) disk backing virtual machine OS disk
if (isManagedDiskEnabled()) {
return this;
}
StorageProfile storageProfile = this.innerModel().storageProfile();
OSDisk osDisk = storageProfile.osDisk();
// Setting native (un-managed) disk backing virtual machine OS disk is valid only when
// the virtual machine is created from image.
if (!this.isOSDiskFromImage(osDisk)) {
return this;
}
// Exclude custom user image as they won't support using native (un-managed) disk to back
// virtual machine OS disk.
if (this.isOsDiskFromCustomImage(storageProfile)) {
return this;
}
// OS Disk from 'Platform image' requires explicit storage account to be specified.
if (this.isOSDiskFromPlatformImage(storageProfile)) {
VirtualHardDisk osVhd = new VirtualHardDisk();
osVhd.withUri(temporaryBlobUrl(containerName, vhdName));
this.innerModel().storageProfile().osDisk().withVhd(osVhd);
return this;
}
// 'Stored image' and 'Bring your own feature image' has a restriction that the native
// disk backing OS disk based on these images should reside in the same storage account
// as the image.
if (this.isOSDiskFromStoredImage(storageProfile)) {
VirtualHardDisk osVhd = new VirtualHardDisk();
try {
URL sourceCustomImageUrl = new URL(osDisk.image().uri());
URL destinationVhdUrl =
new URL(
sourceCustomImageUrl.getProtocol(),
sourceCustomImageUrl.getHost(),
"/" + containerName + "/" + vhdName);
osVhd.withUri(destinationVhdUrl.toString());
} catch (MalformedURLException ex) {
throw logger.logExceptionAsError(new RuntimeException(ex));
}
this.innerModel().storageProfile().osDisk().withVhd(osVhd);
}
return this;
}
@Override
public VirtualMachineImpl withOSDiskStorageAccountType(StorageAccountTypes accountType) {
if (this.innerModel().storageProfile().osDisk().managedDisk() == null) {
this.innerModel().storageProfile().osDisk().withManagedDisk(new ManagedDiskParameters());
}
this.innerModel().storageProfile().osDisk().managedDisk().withStorageAccountType(accountType);
return this;
}
@Override
public VirtualMachineImpl withDataDiskDefaultCachingType(CachingTypes cachingType) {
this.managedDataDisks.setDefaultCachingType(cachingType);
return this;
}
@Override
public VirtualMachineImpl withDataDiskDefaultStorageAccountType(StorageAccountTypes storageAccountType) {
this.managedDataDisks.setDefaultStorageAccountType(storageAccountType);
return this;
}
@Override
public VirtualMachineImpl withDataDiskDefaultDeleteOptions(DeleteOptions deleteOptions) {
this.managedDataDisks.setDefaultDeleteOptions(diskDeleteOptionsFromDeleteOptions(deleteOptions));
return this;
}
@Override
public VirtualMachineImpl withDataDiskDefaultDiskEncryptionSet(
String diskEncryptionSetId) {
this.managedDataDisks.setDefaultEncryptionSet(diskEncryptionSetId);
return this;
}
@Override
public VirtualMachineImpl withOSDiskEncryptionSettings(DiskEncryptionSettings settings) {
this.innerModel().storageProfile().osDisk().withEncryptionSettings(settings);
return this;
}
@Override
public VirtualMachineImpl withOSDiskSizeInGB(int size) {
this.innerModel().storageProfile().osDisk().withDiskSizeGB(size);
return this;
}
@Override
public VirtualMachineImpl withOSDiskName(String name) {
this.innerModel().storageProfile().osDisk().withName(name);
return this;
}
@Override
public VirtualMachineImpl withOSDiskDeleteOptions(DeleteOptions deleteOptions) {
this.innerModel().storageProfile().osDisk()
.withDeleteOption(DiskDeleteOptionTypes.fromString(deleteOptions.toString()));
return this;
}
@Override
public VirtualMachineImpl withOSDiskDiskEncryptionSet(String diskEncryptionSetId) {
if (this.innerModel().storageProfile().osDisk().managedDisk() == null) {
this.innerModel().storageProfile().osDisk()
.withManagedDisk(new ManagedDiskParameters());
}
if (this.innerModel().storageProfile().osDisk().managedDisk().diskEncryptionSet() == null) {
this.innerModel().storageProfile().osDisk().managedDisk()
.withDiskEncryptionSet(new DiskEncryptionSetParameters());
}
this.innerModel().storageProfile().osDisk().managedDisk().diskEncryptionSet().withId(diskEncryptionSetId);
return this;
}
@Override
public VirtualMachineImpl withEphemeralOSDisk() {
if (this.innerModel().storageProfile().osDisk().diffDiskSettings() == null) {
this.innerModel().storageProfile().osDisk().withDiffDiskSettings(new DiffDiskSettings());
}
this.innerModel().storageProfile().osDisk().diffDiskSettings().withOption(DiffDiskOptions.LOCAL);
// For vm with ephemeral os disk, cache should be read-only
withOSDiskCaching(CachingTypes.READ_ONLY);
return this;
}
// Virtual machine optional native data disk fluent methods
@Override
public UnmanagedDataDiskImpl defineUnmanagedDataDisk(String name) {
throwIfManagedDiskEnabled(ManagedUnmanagedDiskErrors.VM_BOTH_MANAGED_AND_UNMANAGED_DISK_NOT_ALLOWED);
return UnmanagedDataDiskImpl.prepareDataDisk(name, this);
}
@Override
public VirtualMachineImpl withNewUnmanagedDataDisk(Integer sizeInGB) {
throwIfManagedDiskEnabled(ManagedUnmanagedDiskErrors.VM_BOTH_MANAGED_AND_UNMANAGED_DISK_NOT_ALLOWED);
return defineUnmanagedDataDisk(null).withNewVhd(sizeInGB).attach();
}
@Override
public VirtualMachineImpl withExistingUnmanagedDataDisk(
String storageAccountName, String containerName, String vhdName) {
throwIfManagedDiskEnabled(ManagedUnmanagedDiskErrors.VM_BOTH_MANAGED_AND_UNMANAGED_DISK_NOT_ALLOWED);
return defineUnmanagedDataDisk(null).withExistingVhd(storageAccountName, containerName, vhdName).attach();
}
@Override
public VirtualMachineImpl withoutUnmanagedDataDisk(String name) {
// Its ok not to throw here, since in general 'withoutXX' can be NOP
int idx = -1;
for (VirtualMachineUnmanagedDataDisk dataDisk : this.unmanagedDataDisks) {
idx++;
if (dataDisk.name().equalsIgnoreCase(name)) {
this.unmanagedDataDisks.remove(idx);
this.innerModel().storageProfile().dataDisks().remove(idx);
break;
}
}
return this;
}
@Override
public VirtualMachineImpl withoutUnmanagedDataDisk(int lun) {
// Its ok not to throw here, since in general 'withoutXX' can be NOP
int idx = -1;
for (VirtualMachineUnmanagedDataDisk dataDisk : this.unmanagedDataDisks) {
idx++;
if (dataDisk.lun() == lun) {
this.unmanagedDataDisks.remove(idx);
this.innerModel().storageProfile().dataDisks().remove(idx);
break;
}
}
return this;
}
@Override
public UnmanagedDataDiskImpl updateUnmanagedDataDisk(String name) {
throwIfManagedDiskEnabled(ManagedUnmanagedDiskErrors.VM_NO_UNMANAGED_DISK_TO_UPDATE);
for (VirtualMachineUnmanagedDataDisk dataDisk : this.unmanagedDataDisks) {
if (dataDisk.name().equalsIgnoreCase(name)) {
return (UnmanagedDataDiskImpl) dataDisk;
}
}
throw logger.logExceptionAsError(new RuntimeException("A data disk with name '" + name + "' not found"));
}
// Virtual machine optional managed data disk fluent methods
@Override
public VirtualMachineImpl withNewDataDisk(Creatable creatable) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
this.managedDataDisks.newDisksToAttach.put(this.addDependency(creatable), new DataDisk().withLun(-1));
return this;
}
@Override
public VirtualMachineImpl withNewDataDisk(Creatable creatable, int lun, CachingTypes cachingType) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
this
.managedDataDisks
.newDisksToAttach
.put(this.addDependency(creatable), new DataDisk().withLun(lun).withCaching(cachingType));
return this;
}
@Override
public VirtualMachineImpl withNewDataDisk(int sizeInGB) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
this.managedDataDisks.implicitDisksToAssociate.add(new DataDisk().withLun(-1).withDiskSizeGB(sizeInGB));
return this;
}
@Override
public VirtualMachineImpl withNewDataDisk(int sizeInGB, int lun, CachingTypes cachingType) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
this
.managedDataDisks
.implicitDisksToAssociate
.add(new DataDisk().withLun(lun).withDiskSizeGB(sizeInGB).withCaching(cachingType));
return this;
}
@Override
public VirtualMachineImpl withNewDataDisk(
int sizeInGB, int lun, CachingTypes cachingType, StorageAccountTypes storageAccountType) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
ManagedDiskParameters managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withStorageAccountType(storageAccountType);
this
.managedDataDisks
.implicitDisksToAssociate
.add(
new DataDisk()
.withLun(lun)
.withDiskSizeGB(sizeInGB)
.withCaching(cachingType)
.withManagedDisk(managedDiskParameters));
return this;
}
@Override
public VirtualMachineImpl withNewDataDisk(int sizeInGB, int lun, VirtualMachineDiskOptions options) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
ManagedDiskParameters managedDiskParameters = null;
if (options.storageAccountType() != null || options.isDiskEncryptionSetConfigured()) {
managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withStorageAccountType(options.storageAccountType());
if (options.isDiskEncryptionSetConfigured()) {
managedDiskParameters.withDiskEncryptionSet(
new DiskEncryptionSetParameters().withId(options.diskEncryptionSetId()));
}
}
this
.managedDataDisks
.implicitDisksToAssociate
.add(
new DataDisk()
.withLun(lun)
.withDiskSizeGB(sizeInGB)
.withCaching(options.cachingTypes())
.withDeleteOption(diskDeleteOptionsFromDeleteOptions(options.deleteOptions()))
.withManagedDisk(managedDiskParameters));
return this;
}
@Override
public VirtualMachineImpl withExistingDataDisk(Disk disk) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
ManagedDiskParameters managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withId(disk.id());
this
.managedDataDisks
.existingDisksToAttach
.add(new DataDisk().withLun(-1).withManagedDisk(managedDiskParameters));
return this;
}
@Override
public VirtualMachineImpl withExistingDataDisk(Disk disk, int lun, CachingTypes cachingType) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
ManagedDiskParameters managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withId(disk.id());
this
.managedDataDisks
.existingDisksToAttach
.add(new DataDisk().withLun(lun).withManagedDisk(managedDiskParameters).withCaching(cachingType));
return this;
}
@Override
public VirtualMachineImpl withExistingDataDisk(Disk disk, int newSizeInGB, int lun, CachingTypes cachingType) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
ManagedDiskParameters managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withId(disk.id());
this
.managedDataDisks
.existingDisksToAttach
.add(
new DataDisk()
.withLun(lun)
.withDiskSizeGB(newSizeInGB)
.withManagedDisk(managedDiskParameters)
.withCaching(cachingType));
return this;
}
@Override
public VirtualMachineImpl withExistingDataDisk(
Disk disk, int newSizeInGB, int lun, VirtualMachineDiskOptions options) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
// storageAccountType is not allowed to be modified
ManagedDiskParameters managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withId(disk.id());
if (options.isDiskEncryptionSetConfigured()) {
managedDiskParameters.withDiskEncryptionSet(
new DiskEncryptionSetParameters().withId(options.diskEncryptionSetId()));
}
this
.managedDataDisks
.existingDisksToAttach
.add(
new DataDisk()
.withLun(lun)
.withDiskSizeGB(newSizeInGB)
.withCaching(options.cachingTypes())
.withDeleteOption(diskDeleteOptionsFromDeleteOptions(options.deleteOptions()))
.withManagedDisk(managedDiskParameters));
return this;
}
@Override
public VirtualMachineImpl withNewDataDiskFromImage(int imageLun) {
this.managedDataDisks.newDisksFromImage.add(new DataDisk().withLun(imageLun));
return this;
}
@Override
public VirtualMachineImpl withNewDataDiskFromImage(int imageLun, int newSizeInGB, CachingTypes cachingType) {
this
.managedDataDisks
.newDisksFromImage
.add(new DataDisk().withLun(imageLun).withDiskSizeGB(newSizeInGB).withCaching(cachingType));
return this;
}
@Override
public VirtualMachineImpl withNewDataDiskFromImage(
int imageLun, int newSizeInGB, CachingTypes cachingType, StorageAccountTypes storageAccountType) {
ManagedDiskParameters managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withStorageAccountType(storageAccountType);
this
.managedDataDisks
.newDisksFromImage
.add(
new DataDisk()
.withLun(imageLun)
.withDiskSizeGB(newSizeInGB)
.withManagedDisk(managedDiskParameters)
.withCaching(cachingType));
return this;
}
@Override
public VirtualMachineImpl withNewDataDiskFromImage(
int imageLun, int newSizeInGB, VirtualMachineDiskOptions options) {
throwIfManagedDiskDisabled(ManagedUnmanagedDiskErrors.VM_BOTH_UNMANAGED_AND_MANAGED_DISK_NOT_ALLOWED);
ManagedDiskParameters managedDiskParameters = null;
if (options.storageAccountType() != null || options.isDiskEncryptionSetConfigured()) {
managedDiskParameters = new ManagedDiskParameters();
managedDiskParameters.withStorageAccountType(options.storageAccountType());
if (options.isDiskEncryptionSetConfigured()) {
managedDiskParameters.withDiskEncryptionSet(
new DiskEncryptionSetParameters().withId(options.diskEncryptionSetId()));
}
}
this
.managedDataDisks
.implicitDisksToAssociate
.add(
new DataDisk()
.withLun(imageLun)
.withDiskSizeGB(newSizeInGB)
.withCaching(options.cachingTypes())
.withDeleteOption(diskDeleteOptionsFromDeleteOptions(options.deleteOptions()))
.withManagedDisk(managedDiskParameters));
return this;
}
@Override
public VirtualMachineImpl withoutDataDisk(int lun) {
if (!isManagedDiskEnabled()) {
return this;
}
this.managedDataDisks.diskLunsToRemove.add(lun);
return this;
}
// Virtual machine optional storage account fluent methods
@Override
public VirtualMachineImpl withNewStorageAccount(Creatable creatable) {
// This method's effect is NOT additive.
if (this.creatableStorageAccountKey == null) {
this.creatableStorageAccountKey = this.addDependency(creatable);
}
return this;
}
@Override
public VirtualMachineImpl withNewStorageAccount(String name) {
StorageAccount.DefinitionStages.WithGroup definitionWithGroup =
this.storageManager.storageAccounts().define(name).withRegion(this.regionName());
Creatable definitionAfterGroup;
if (this.creatableGroup != null) {
definitionAfterGroup = definitionWithGroup.withNewResourceGroup(this.creatableGroup);
} else {
definitionAfterGroup = definitionWithGroup.withExistingResourceGroup(this.resourceGroupName());
}
return withNewStorageAccount(definitionAfterGroup);
}
@Override
public VirtualMachineImpl withExistingStorageAccount(StorageAccount storageAccount) {
this.existingStorageAccountToAssociate = storageAccount;
return this;
}
// Virtual machine optional availability set fluent methods
@Override
public VirtualMachineImpl withNewAvailabilitySet(Creatable creatable) {
// This method's effect is NOT additive.
if (this.creatableAvailabilitySetKey == null) {
this.creatableAvailabilitySetKey = this.addDependency(creatable);
}
return this;
}
@Override
public VirtualMachineImpl withProximityPlacementGroup(String proximityPlacementGroupId) {
this.innerModel().withProximityPlacementGroup(new SubResource().withId(proximityPlacementGroupId));
// clear the new setting
newProximityPlacementGroupName = null;
return this;
}
@Override
public VirtualMachineImpl withNewProximityPlacementGroup(
String proximityPlacementGroupName, ProximityPlacementGroupType type) {
this.newProximityPlacementGroupName = proximityPlacementGroupName;
this.newProximityPlacementGroupType = type;
this.innerModel().withProximityPlacementGroup(null);
return this;
}
@Override
public VirtualMachineImpl withoutProximityPlacementGroup() {
this.innerModel().withProximityPlacementGroup(null);
return this;
}
@Override
public VirtualMachineImpl withNewAvailabilitySet(String name) {
AvailabilitySet.DefinitionStages.WithGroup definitionWithGroup =
super.myManager.availabilitySets().define(name).withRegion(this.regionName());
AvailabilitySet.DefinitionStages.WithSku definitionWithSku;
if (this.creatableGroup != null) {
definitionWithSku = definitionWithGroup.withNewResourceGroup(this.creatableGroup);
} else {
definitionWithSku = definitionWithGroup.withExistingResourceGroup(this.resourceGroupName());
}
Creatable creatable;
if (isManagedDiskEnabled()) {
creatable = definitionWithSku.withSku(AvailabilitySetSkuTypes.ALIGNED);
} else {
creatable = definitionWithSku.withSku(AvailabilitySetSkuTypes.CLASSIC);
}
return withNewAvailabilitySet(creatable);
}
@Override
public VirtualMachineImpl withExistingAvailabilitySet(AvailabilitySet availabilitySet) {
this.existingAvailabilitySetToAssociate = availabilitySet;
return this;
}
@Override
public VirtualMachineImpl withNewSecondaryNetworkInterface(Creatable creatable) {
this.creatableSecondaryNetworkInterfaceKeys.add(this.addDependency(creatable));
return this;
}
@Override
public VirtualMachineImpl withNewSecondaryNetworkInterface(Creatable creatable,
DeleteOptions deleteOptions) {
String key = this.addDependency(creatable);
this.creatableSecondaryNetworkInterfaceKeys.add(key);
if (deleteOptions != null) {
this.secondaryNetworkInterfaceDeleteOptions.put(key, deleteOptions);
}
return this;
}
@Override
public VirtualMachineImpl withExistingSecondaryNetworkInterface(NetworkInterface networkInterface) {
this.existingSecondaryNetworkInterfacesToAssociate.add(networkInterface);
return this;
}
// Virtual machine optional extension settings
@Override
public VirtualMachineExtensionImpl defineNewExtension(String name) {
return this.virtualMachineExtensions.define(name);
}
@Override
public VirtualMachineImpl withoutSecondaryNetworkInterface(String name) {
if (this.innerModel().networkProfile() != null
&& this.innerModel().networkProfile().networkInterfaces() != null) {
int idx = -1;
for (NetworkInterfaceReference nicReference : this.innerModel().networkProfile().networkInterfaces()) {
idx++;
if (!nicReference.primary()
&& name.equalsIgnoreCase(ResourceUtils.nameFromResourceId(nicReference.id()))) {
this.innerModel().networkProfile().networkInterfaces().remove(idx);
break;
}
}
}
return this;
}
@Override
public VirtualMachineExtensionImpl updateExtension(String name) {
return this.virtualMachineExtensions.update(name);
}
@Override
public VirtualMachineImpl withoutExtension(String name) {
this.virtualMachineExtensions.remove(name);
return this;
}
@Override
public VirtualMachineImpl withPlan(PurchasePlan plan) {
this.innerModel().withPlan(new Plan());
this.innerModel().plan().withPublisher(plan.publisher()).withProduct(plan.product()).withName(plan.name());
return this;
}
@Override
public VirtualMachineImpl withPromotionalPlan(PurchasePlan plan, String promotionCode) {
this.withPlan(plan);
this.innerModel().plan().withPromotionCode(promotionCode);
return this;
}
@Override
public VirtualMachineImpl withUnmanagedDisks() {
this.isUnmanagedDiskSelected = true;
return this;
}
@Override
public VirtualMachineImpl withBootDiagnosticsOnManagedStorageAccount() {
this.bootDiagnosticsHandler.withBootDiagnostics(true);
return this;
}
@Override
public VirtualMachineImpl withBootDiagnostics() {
this.bootDiagnosticsHandler.withBootDiagnostics(false);
return this;
}
@Override
public VirtualMachineImpl withBootDiagnostics(Creatable creatable) {
this.bootDiagnosticsHandler.withBootDiagnostics(creatable);
return this;
}
@Override
public VirtualMachineImpl withBootDiagnostics(String storageAccountBlobEndpointUri) {
this.bootDiagnosticsHandler.withBootDiagnostics(storageAccountBlobEndpointUri);
return this;
}
@Override
public VirtualMachineImpl withBootDiagnostics(StorageAccount storageAccount) {
this.bootDiagnosticsHandler.withBootDiagnostics(storageAccount);
return this;
}
@Override
public VirtualMachineImpl withoutBootDiagnostics() {
this.bootDiagnosticsHandler.withoutBootDiagnostics();
return this;
}
@Override
public VirtualMachineImpl withPriority(VirtualMachinePriorityTypes priority) {
this.innerModel().withPriority(priority);
return this;
}
@Override
public VirtualMachineImpl withLowPriority() {
this.withPriority(VirtualMachinePriorityTypes.LOW);
return this;
}
@Override
public VirtualMachineImpl withLowPriority(VirtualMachineEvictionPolicyTypes policy) {
this.withLowPriority();
this.innerModel().withEvictionPolicy(policy);
return this;
}
@Override
public VirtualMachineImpl withSpotPriority() {
this.withPriority(VirtualMachinePriorityTypes.SPOT);
return this;
}
@Override
public VirtualMachineImpl withSpotPriority(VirtualMachineEvictionPolicyTypes policy) {
this.withSpotPriority();
this.innerModel().withEvictionPolicy(policy);
return this;
}
@Override
public VirtualMachineImpl withMaxPrice(Double maxPrice) {
this.innerModel().withBillingProfile(new BillingProfile().withMaxPrice(maxPrice));
return this;
}
@Override
public VirtualMachineImpl withSystemAssignedManagedServiceIdentity() {
this.virtualMachineMsiHandler.withLocalManagedServiceIdentity();
return this;
}
@Override
public VirtualMachineImpl withoutSystemAssignedManagedServiceIdentity() {
this.virtualMachineMsiHandler.withoutLocalManagedServiceIdentity();
return this;
}
@Override
public VirtualMachineImpl withSystemAssignedIdentityBasedAccessTo(String resourceId, BuiltInRole role) {
this.virtualMachineMsiHandler.withAccessTo(resourceId, role);
return this;
}
@Override
public VirtualMachineImpl withSystemAssignedIdentityBasedAccessToCurrentResourceGroup(BuiltInRole role) {
this.virtualMachineMsiHandler.withAccessToCurrentResourceGroup(role);
return this;
}
@Override
public VirtualMachineImpl withSystemAssignedIdentityBasedAccessTo(String resourceId, String roleDefinitionId) {
this.virtualMachineMsiHandler.withAccessTo(resourceId, roleDefinitionId);
return this;
}
@Override
public VirtualMachineImpl withSystemAssignedIdentityBasedAccessToCurrentResourceGroup(String roleDefinitionId) {
this.virtualMachineMsiHandler.withAccessToCurrentResourceGroup(roleDefinitionId);
return this;
}
@Override
public VirtualMachineImpl withNewUserAssignedManagedServiceIdentity(Creatable creatableIdentity) {
this.virtualMachineMsiHandler.withNewExternalManagedServiceIdentity(creatableIdentity);
return this;
}
@Override
public VirtualMachineImpl withExistingUserAssignedManagedServiceIdentity(Identity identity) {
this.virtualMachineMsiHandler.withExistingExternalManagedServiceIdentity(identity);
return this;
}
@Override
public VirtualMachineImpl withoutUserAssignedManagedServiceIdentity(String identityId) {
this.virtualMachineMsiHandler.withoutExternalManagedServiceIdentity(identityId);
return this;
}
@Override
public VirtualMachineImpl withLicenseType(String licenseType) {
innerModel().withLicenseType(licenseType);
return this;
}
@Override
public VirtualMachineImpl enableHibernation() {
ensureAdditionalCapabilities();
this.innerModel().additionalCapabilities().withHibernationEnabled(true);
return this;
}
@Override
public VirtualMachineImpl disableHibernation() {
ensureAdditionalCapabilities();
this.innerModel().additionalCapabilities().withHibernationEnabled(false);
return this;
}
@Override
public VirtualMachineImpl enableUltraSsd() {
ensureAdditionalCapabilities();
this.innerModel().additionalCapabilities().withUltraSsdEnabled(true);
return this;
}
@Override
public VirtualMachineImpl disableUltraSsd() {
ensureAdditionalCapabilities();
this.innerModel().additionalCapabilities().withUltraSsdEnabled(false);
return this;
}
public void ensureAdditionalCapabilities() {
if (this.innerModel().additionalCapabilities() == null) {
this.innerModel().withAdditionalCapabilities(new AdditionalCapabilities());
}
}
// GETTERS
@Override
public boolean isManagedDiskEnabled() {
if (isOsDiskFromCustomImage(this.innerModel().storageProfile())) {
return true;
}
if (isOSDiskAttachedManaged(this.innerModel().storageProfile().osDisk())) {
return true;
}
if (isOSDiskFromStoredImage(this.innerModel().storageProfile())) {
return false;
}
if (isOSDiskAttachedUnmanaged(this.innerModel().storageProfile().osDisk())) {
return false;
}
if (isOSDiskFromPlatformImage(this.innerModel().storageProfile())) {
if (this.isUnmanagedDiskSelected) {
return false;
}
}
if (isInCreateMode()) {
return true;
} else {
return this.innerModel().storageProfile().osDisk().vhd() == null;
}
}
@Override
public String computerName() {
if (innerModel().osProfile() == null) {
// VM created by attaching a specialized OS Disk VHD will not have the osProfile.
return null;
}
return innerModel().osProfile().computerName();
}
@Override
public VirtualMachineSizeTypes size() {
return innerModel().hardwareProfile().vmSize();
}
@Override
public OperatingSystemTypes osType() {
if (innerModel().storageProfile().osDisk().osType() != null) {
return innerModel().storageProfile().osDisk().osType();
}
if (innerModel().osProfile() != null) {
if (innerModel().osProfile().linuxConfiguration() != null) {
return OperatingSystemTypes.LINUX;
}
if (innerModel().osProfile().windowsConfiguration() != null) {
return OperatingSystemTypes.WINDOWS;
}
}
return null;
}
@Override
public String osUnmanagedDiskVhdUri() {
if (isManagedDiskEnabled() || this.storageProfile().osDisk().vhd() == null) {
return null;
}
return innerModel().storageProfile().osDisk().vhd().uri();
}
@Override
public CachingTypes osDiskCachingType() {
return innerModel().storageProfile().osDisk().caching();
}
@Override
public int osDiskSize() {
return ResourceManagerUtils.toPrimitiveInt(innerModel().storageProfile().osDisk().diskSizeGB());
}
@Override
public StorageAccountTypes osDiskStorageAccountType() {
if (!isManagedDiskEnabled() || this.storageProfile().osDisk().managedDisk() == null) {
return null;
}
return this.storageProfile().osDisk().managedDisk().storageAccountType();
}
@Override
public String osDiskId() {
if (!isManagedDiskEnabled()) {
return null;
}
return this.storageProfile().osDisk().managedDisk().id();
}
@Override
public DeleteOptions osDiskDeleteOptions() {
if (!isManagedDiskEnabled() || this.storageProfile().osDisk().deleteOption() == null) {
return null;
}
return DeleteOptions.fromString(this.storageProfile().osDisk().deleteOption().toString());
}
@Override
public String osDiskDiskEncryptionSetId() {
if (!isManagedDiskEnabled() || this.storageProfile().osDisk().managedDisk() == null
|| this.storageProfile().osDisk().managedDisk().diskEncryptionSet() == null) {
return null;
}
return this.storageProfile().osDisk().managedDisk().diskEncryptionSet().id();
}
@Override
public boolean isOSDiskEphemeral() {
return this.storageProfile().osDisk().diffDiskSettings() != null && this.storageProfile().osDisk().diffDiskSettings().placement() != null;
}
@Override
public boolean isEncryptionAtHost() {
return !Objects.isNull(this.innerModel().securityProfile()) && this.innerModel().securityProfile().encryptionAtHost();
}
@Override
public Map unmanagedDataDisks() {
Map dataDisks = new HashMap<>();
if (!isManagedDiskEnabled()) {
for (VirtualMachineUnmanagedDataDisk dataDisk : this.unmanagedDataDisks) {
dataDisks.put(dataDisk.lun(), dataDisk);
}
}
return Collections.unmodifiableMap(dataDisks);
}
@Override
public Map dataDisks() {
Map dataDisks = new HashMap<>();
if (isManagedDiskEnabled()) {
List innerDataDisks = this.innerModel().storageProfile().dataDisks();
if (innerDataDisks != null) {
for (DataDisk innerDataDisk : innerDataDisks) {
dataDisks.put(innerDataDisk.lun(), new VirtualMachineDataDiskImpl(innerDataDisk));
}
}
}
return Collections.unmodifiableMap(dataDisks);
}
@Override
public NetworkInterface getPrimaryNetworkInterface() {
return this.getPrimaryNetworkInterfaceAsync().block();
}
@Override
public Mono getPrimaryNetworkInterfaceAsync() {
return this.networkManager.networkInterfaces().getByIdAsync(primaryNetworkInterfaceId());
}
@Override
public PublicIpAddress getPrimaryPublicIPAddress() {
return this.getPrimaryNetworkInterface().primaryIPConfiguration().getPublicIpAddress();
}
@Override
public String getPrimaryPublicIPAddressId() {
return this.getPrimaryNetworkInterface().primaryIPConfiguration().publicIpAddressId();
}
@Override
public List networkInterfaceIds() {
List nicIds = new ArrayList<>();
for (NetworkInterfaceReference nicRef : innerModel().networkProfile().networkInterfaces()) {
nicIds.add(nicRef.id());
}
return nicIds;
}
@Override
public String primaryNetworkInterfaceId() {
final List nicRefs = this.innerModel().networkProfile().networkInterfaces();
String primaryNicRefId = null;
if (nicRefs.size() == 1) {
// One NIC so assume it to be primary
primaryNicRefId = nicRefs.get(0).id();
} else if (nicRefs.size() == 0) {
// No NICs so null
primaryNicRefId = null;
} else {
// Find primary interface as flagged by Azure
for (NetworkInterfaceReference nicRef : innerModel().networkProfile().networkInterfaces()) {
if (nicRef.primary() != null && nicRef.primary()) {
primaryNicRefId = nicRef.id();
break;
}
}
// If Azure didn't flag any NIC as primary then assume the first one
if (primaryNicRefId == null) {
primaryNicRefId = nicRefs.get(0).id();
}
}
return primaryNicRefId;
}
@Override
public String availabilitySetId() {
if (innerModel().availabilitySet() != null) {
return innerModel().availabilitySet().id();
}
return null;
}
@Override
public String virtualMachineScaleSetId() {
if (innerModel().virtualMachineScaleSet() != null) {
return innerModel().virtualMachineScaleSet().id();
}
return null;
}
@Override
public String provisioningState() {
return innerModel().provisioningState();
}
@Override
public String licenseType() {
return innerModel().licenseType();
}
@Override
public ProximityPlacementGroup proximityPlacementGroup() {
if (innerModel().proximityPlacementGroup() == null) {
return null;
} else {
ResourceId id = ResourceId.fromString(innerModel().proximityPlacementGroup().id());
ProximityPlacementGroupInner plgInner =
manager()
.serviceClient()
.getProximityPlacementGroups()
.getByResourceGroup(id.resourceGroupName(), id.name());
if (plgInner == null) {
return null;
} else {
return new ProximityPlacementGroupImpl(plgInner);
}
}
}
@Override
public Mono> listExtensionsAsync() {
return this.virtualMachineExtensions.listAsync();
}
@Override
public Map listExtensions() {
return this.virtualMachineExtensions.asMap();
}
@Override
public Plan plan() {
return innerModel().plan();
}
@Override
public StorageProfile storageProfile() {
return innerModel().storageProfile();
}
@Override
public OSProfile osProfile() {
return innerModel().osProfile();
}
@Override
public DiagnosticsProfile diagnosticsProfile() {
return innerModel().diagnosticsProfile();
}
@Override
public String vmId() {
return innerModel().vmId();
}
@Override
public VirtualMachineInstanceView instanceView() {
if (this.virtualMachineInstanceView == null) {
this.refreshInstanceView();
}
return this.virtualMachineInstanceView;
}
@Override
public Set availabilityZones() {
Set zones = new HashSet<>();
if (this.innerModel().zones() != null) {
for (String zone : this.innerModel().zones()) {
zones.add(AvailabilityZoneId.fromString(zone));
}
}
return Collections.unmodifiableSet(zones);
}
@Override
public PowerState powerState() {
return PowerState.fromInstanceView(this.instanceView());
}
@Override
public boolean isBootDiagnosticsEnabled() {
return this.bootDiagnosticsHandler.isBootDiagnosticsEnabled();
}
@Override
public String bootDiagnosticsStorageUri() {
return this.bootDiagnosticsHandler.bootDiagnosticsStorageUri();
}
@Override
public boolean isManagedServiceIdentityEnabled() {
ResourceIdentityType type = this.managedServiceIdentityType();
return type != null && !type.equals(ResourceIdentityType.NONE);
}
@Override
public String systemAssignedManagedServiceIdentityTenantId() {
if (this.innerModel().identity() != null) {
return this.innerModel().identity().tenantId();
}
return null;
}
@Override
public String systemAssignedManagedServiceIdentityPrincipalId() {
if (this.innerModel().identity() != null) {
return this.innerModel().identity().principalId();
}
return null;
}
@Override
public ResourceIdentityType managedServiceIdentityType() {
if (this.innerModel().identity() != null) {
return this.innerModel().identity().type();
}
return null;
}
@Override
public Set userAssignedManagedServiceIdentityIds() {
if (this.innerModel().identity() != null && this.innerModel().identity().userAssignedIdentities() != null) {
return Collections
.unmodifiableSet(new HashSet(this.innerModel().identity().userAssignedIdentities().keySet()));
}
return Collections.unmodifiableSet(new HashSet());
}
@Override
public BillingProfile billingProfile() {
return this.innerModel().billingProfile();
}
@Override
public boolean isHibernationEnabled() {
return this.innerModel().additionalCapabilities() != null
&& ResourceManagerUtils.toPrimitiveBoolean(this.innerModel().additionalCapabilities().hibernationEnabled());
}
@Override
public boolean isUltraSsdEnabled() {
return this.innerModel().additionalCapabilities() != null
&& ResourceManagerUtils.toPrimitiveBoolean(this.innerModel().additionalCapabilities().ultraSsdEnabled());
}
@Override
public SecurityTypes securityType() {
SecurityProfile securityProfile = this.innerModel().securityProfile();
if (securityProfile == null) {
return null;
}
return securityProfile.securityType();
}
@Override
public boolean isSecureBootEnabled() {
return securityType() != null && this.innerModel().securityProfile().uefiSettings() != null
&& ResourceManagerUtils.toPrimitiveBoolean(this.innerModel().securityProfile().uefiSettings().secureBootEnabled());
}
@Override
public boolean isVTpmEnabled() {
return securityType() != null && this.innerModel().securityProfile().uefiSettings() != null
&& ResourceManagerUtils.toPrimitiveBoolean(this.innerModel().securityProfile().uefiSettings().vTpmEnabled());
}
@Override
public OffsetDateTime timeCreated() {
return innerModel().timeCreated();
}
@Override
public DeleteOptions primaryNetworkInterfaceDeleteOptions() {
String nicId = primaryNetworkInterfaceId();
return networkInterfaceDeleteOptions(nicId);
}
@Override
public DeleteOptions networkInterfaceDeleteOptions(String networkInterfaceId) {
if (CoreUtils.isNullOrEmpty(networkInterfaceId)
|| this.innerModel().networkProfile() == null
|| this.innerModel().networkProfile().networkInterfaces() == null) {
return null;
}
return this.innerModel().networkProfile()
.networkInterfaces()
.stream()
.filter(nic -> networkInterfaceId.equalsIgnoreCase(nic.id()))
.findAny()
.map(NetworkInterfaceReference::deleteOption)
.orElse(null);
}
@Override
public VirtualMachinePriorityTypes priority() {
return this.innerModel().priority();
}
@Override
public VirtualMachineEvictionPolicyTypes evictionPolicy() {
return this.innerModel().evictionPolicy();
}
@Override
public String userData() {
return this.innerModel().userData();
}
// CreateUpdateTaskGroup.ResourceCreator.beforeGroupCreateOrUpdate implementation
@Override
public void beforeGroupCreateOrUpdate() {
// [1]. StorageProfile: If implicit storage account creation is required then add Creatable.
if (creatableStorageAccountKey == null && existingStorageAccountToAssociate == null) {
if (osDiskRequiresImplicitStorageAccountCreation() || dataDisksRequiresImplicitStorageAccountCreation()) {
Creatable storageAccountCreatable = null;
if (this.creatableGroup != null) {
storageAccountCreatable =
this
.storageManager
.storageAccounts()
.define(this.namer.getRandomName("stg", 24).replace("-", ""))
.withRegion(this.regionName())
.withNewResourceGroup(this.creatableGroup);
} else {
storageAccountCreatable =
this
.storageManager
.storageAccounts()
.define(this.namer.getRandomName("stg", 24).replace("-", ""))
.withRegion(this.regionName())
.withExistingResourceGroup(this.resourceGroupName());
}
this.creatableStorageAccountKey = this.addDependency(storageAccountCreatable);
}
}
// [2]. BootDiagnosticsProfile: If any implicit resource creation is required then add Creatable>.
this.bootDiagnosticsHandler.prepare();
}
// [2]. CreateUpdateTaskGroup.ResourceCreator.createResourceAsync implementation
@Override
public Mono createResourceAsync() {
// -- set creation-time only properties
return prepareCreateResourceAsync()
.flatMap(
virtualMachine ->
this
.manager()
.serviceClient()
.getVirtualMachines()
.createOrUpdateAsync(resourceGroupName(), vmName, innerModel())
.map(
virtualMachineInner -> {
reset(virtualMachineInner);
return this;
}));
}
private Mono prepareCreateResourceAsync() {
setOSDiskDefaults();
setOSProfileDefaults();
setHardwareProfileDefaults();
if (isManagedDiskEnabled()) {
managedDataDisks.setDataDisksDefaults();
} else {
UnmanagedDataDiskImpl.setDataDisksDefaults(this.unmanagedDataDisks, this.vmName);
}
this.handleUnManagedOSAndDataDisksStorageSettings();
this.bootDiagnosticsHandler.handleDiagnosticsSettings();
this.handleNetworkSettings();
return this
.createNewProximityPlacementGroupAsync()
.map(
virtualMachine -> {
this.handleAvailabilitySettings();
this.virtualMachineMsiHandler.processCreatedExternalIdentities();
this.virtualMachineMsiHandler.handleExternalIdentities();
return virtualMachine;
});
}
public Accepted beginCreate() {
return AcceptedImpl
.newAccepted(
logger,
this.manager().serviceClient().getHttpPipeline(),
this.manager().serviceClient().getDefaultPollInterval(),
() ->
this
.manager()
.serviceClient()
.getVirtualMachines()
.createOrUpdateWithResponseAsync(resourceGroupName(), vmName, innerModel(), null, null)
.block(),
inner ->
new VirtualMachineImpl(
inner.name(),
inner,
this.manager(),
this.storageManager,
this.networkManager,
this.authorizationManager),
VirtualMachineInner.class,
() -> {
Flux dependencyTasksAsync =
taskGroup().invokeDependencyAsync(taskGroup().newInvocationContext());
dependencyTasksAsync.blockLast();
// same as createResourceAsync
prepareCreateResourceAsync().block();
},
this::reset,
Context.NONE);
}
@Override
public Mono updateResourceAsync() {
if (isManagedDiskEnabled()) {
managedDataDisks.setDataDisksDefaults();
} else {
UnmanagedDataDiskImpl.setDataDisksDefaults(this.unmanagedDataDisks, this.vmName);
}
this.handleUnManagedOSAndDataDisksStorageSettings();
this.bootDiagnosticsHandler.handleDiagnosticsSettings();
this.handleNetworkSettings();
this.handleAvailabilitySettings();
this.virtualMachineMsiHandler.processCreatedExternalIdentities();
VirtualMachineUpdateInner updateParameter = new VirtualMachineUpdateInner();
this.copyInnerToUpdateParameter(updateParameter);
this.virtualMachineMsiHandler.handleExternalIdentities(updateParameter);
final boolean vmModified = this.isVirtualMachineModifiedDuringUpdate(updateParameter);
if (vmModified) {
return this
.manager()
.serviceClient()
.getVirtualMachines()
.updateAsync(resourceGroupName(), vmName, updateParameter)
.map(
virtualMachineInner -> {
reset(virtualMachineInner);
return this;
});
} else {
return Mono.just(this);
}
}
// CreateUpdateTaskGroup.ResourceCreator.afterPostRunAsync implementation
@Override
public Mono afterPostRunAsync(boolean isGroupFaulted) {
this.virtualMachineExtensions.clear();
if (isGroupFaulted) {
return Mono.empty();
} else {
return this.refreshAsync().then();
}
}
// Helpers
VirtualMachineImpl withExtension(VirtualMachineExtensionImpl extension) {
this.virtualMachineExtensions.addExtension(extension);
return this;
}
/*
* Serialize VirtualMachineCaptureResultInner and include read-only properties in the result.
*/
static String serializeCaptureResult(VirtualMachineCaptureResultInner captureResultInner, ClientLogger logger) {
Map resultMap = new HashMap<>();
resultMap.put("id", captureResultInner.id());
resultMap.put("contentVersion", captureResultInner.contentVersion());
resultMap.put("schema", captureResultInner.schema());
resultMap.put("resources", captureResultInner.resources());
resultMap.put("parameters", captureResultInner.parameters());
try {
return SerializerFactory.createDefaultManagementSerializerAdapter()
.serialize(resultMap, SerializerEncoding.JSON);
} catch (IOException e) {
throw logger.logExceptionAsError(Exceptions.propagate(e));
}
}
private void reset(VirtualMachineInner inner) {
this.setInner(inner);
clearCachedRelatedResources();
initializeDataDisks();
virtualMachineMsiHandler.clear();
creatableSecondaryNetworkInterfaceKeys.clear();
existingSecondaryNetworkInterfacesToAssociate.clear();
secondaryNetworkInterfaceDeleteOptions.clear();
primaryNetworkInterfaceDeleteOptions = null;
}
VirtualMachineImpl withUnmanagedDataDisk(UnmanagedDataDiskImpl dataDisk) {
this.innerModel().storageProfile().dataDisks().add(dataDisk.innerModel());
this.unmanagedDataDisks.add(dataDisk);
return this;
}
@Override
public VirtualMachineImpl withAvailabilityZone(AvailabilityZoneId zoneId) {
if (isInCreateMode()) {
// Note: Zone is not updatable as of now, so this is available only during definition time.
// Service return `ResourceAvailabilityZonesCannotBeModified` upon attempt to append a new
// zone or remove one. Trying to remove the last one means attempt to change resource from
// zonal to regional, which is not supported.
// though not updatable, still adding above 'isInCreateMode' check just as a reminder to
// take special handling of 'implicitPipCreatable' when avail zone update is supported.
if (this.innerModel().zones() == null) {
this.innerModel().withZones(new ArrayList());
}
this.innerModel().zones().add(zoneId.toString());
// zone aware VM can be attached to only zone aware public IP.
if (this.implicitPipCreatable != null) {
this.implicitPipCreatable
.withAvailabilityZone(zoneId)
.withSku(PublicIPSkuType.STANDARD) // standard sku is required for zone resiliency
.withStaticIP(); // static allocation is required for standard sku
}
}
return this;
}
@Override
public VirtualMachineImpl withOsDiskDeleteOptions(DeleteOptions deleteOptions) {
if (deleteOptions == null
|| this.innerModel().storageProfile() == null || this.innerModel().storageProfile().osDisk() == null) {
return null;
}
this.innerModel().storageProfile().osDisk().withDeleteOption(diskDeleteOptionsFromDeleteOptions(deleteOptions));
return this;
}
@Override
public VirtualMachineImpl withPrimaryNetworkInterfaceDeleteOptions(DeleteOptions deleteOptions) {
this.primaryNetworkInterfaceDeleteOptions = deleteOptions;
return this;
}
@Override
public VirtualMachineImpl withNetworkInterfacesDeleteOptions(DeleteOptions deleteOptions, String... nicIds) {
if (this.innerModel().networkProfile() != null
&& this.innerModel().networkProfile().networkInterfaces() != null) {
// vararg "nicIds" will never be null, an array will always be created to hold the variables
Set nicIdSet = Arrays.stream(nicIds).map(nicId -> nicId.toLowerCase(Locale.ROOT)).collect(Collectors.toSet());
this.innerModel().networkProfile().networkInterfaces().forEach(
nic -> {
if (nicIdSet.contains(nic.id().toLowerCase(Locale.ROOT))) {
nic.withDeleteOption(deleteOptions);
}
}
);
}
return this;
}
@Override
public VirtualMachineImpl withNetworkInterfacesDeleteOptions(DeleteOptions deleteOptions) {
this.innerModel().networkProfile().networkInterfaces().forEach(
nic -> nic.withDeleteOption(deleteOptions)
);
return this;
}
@Override
public VirtualMachineImpl withDataDisksDeleteOptions(DeleteOptions deleteOptions, Integer... luns) {
if (this.innerModel().storageProfile() != null && this.innerModel().storageProfile().dataDisks() != null) {
// vararg "luns" will never be null, an array will always be created to hold the variables
Set lunSet = Arrays.stream(luns).filter(Objects::nonNull).collect(Collectors.toSet());
this.innerModel().storageProfile().dataDisks().forEach(
dataDisk -> {
if (lunSet.contains(dataDisk.lun())) {
dataDisk.withDeleteOption(diskDeleteOptionsFromDeleteOptions(deleteOptions));
}
}
);
}
return this;
}
@Override
public VirtualMachineImpl withDataDisksDeleteOptions(DeleteOptions deleteOptions) {
this.innerModel().storageProfile().dataDisks().forEach(
dataDisk -> dataDisk.withDeleteOption(diskDeleteOptionsFromDeleteOptions(deleteOptions))
);
return this;
}
AzureEnvironment environment() {
return manager().environment();
}
private void setOSDiskDefaults() {
if (isInUpdateMode()) {
return;
}
StorageProfile storageProfile = this.innerModel().storageProfile();
OSDisk osDisk = storageProfile.osDisk();
if (isOSDiskFromImage(osDisk)) {
// ODDisk CreateOption: FROM_IMAGE
if (isManagedDiskEnabled()) {
// Note:
// Managed disk
// Supported: PlatformImage and CustomImage
// UnSupported: StoredImage
if (osDisk.managedDisk() == null) {
osDisk.withManagedDisk(new ManagedDiskParameters());
}
if (osDisk.managedDisk().storageAccountType() == null) {
osDisk.managedDisk().withStorageAccountType(StorageAccountTypes.STANDARD_LRS);
}
osDisk.withVhd(null);
// We won't set osDisk.name() explicitly for managed disk, if it is null CRP generates unique
// name for the disk resource within the resource group.
} else {
// Note:
// Native (un-managed) disk
// Supported: PlatformImage and StoredImage
// UnSupported: CustomImage
if (isOSDiskFromPlatformImage(storageProfile) || isOSDiskFromStoredImage(storageProfile)) {
if (osDisk.vhd() == null) {
String osDiskVhdContainerName = "vhds";
String osDiskVhdName = this.vmName + "-os-disk-" + UUID.randomUUID().toString() + ".vhd";
withOSDiskVhdLocation(osDiskVhdContainerName, osDiskVhdName);
}
osDisk.withManagedDisk(null);
}
if (osDisk.name() == null) {
withOSDiskName(this.vmName + "-os-disk");
}
}
} else {
// ODDisk CreateOption: ATTACH
if (isManagedDiskEnabled()) {
// In case of attach, it is not allowed to change the storage account type of the
// managed disk.
if (osDisk.managedDisk() != null) {
osDisk.managedDisk().withStorageAccountType(null);
}
osDisk.withVhd(null);
} else {
osDisk.withManagedDisk(null);
if (osDisk.name() == null) {
withOSDiskName(this.vmName + "-os-disk");
}
}
}
if (osDisk.caching() == null) {
withOSDiskCaching(CachingTypes.READ_WRITE);
}
}
private void setOSProfileDefaults() {
if (isInUpdateMode()) {
return;
}
StorageProfile storageProfile = this.innerModel().storageProfile();
OSDisk osDisk = storageProfile.osDisk();
if (!removeOsProfile && isOSDiskFromImage(osDisk)) {
// ODDisk CreateOption: FROM_IMAGE
if (osDisk.osType() == OperatingSystemTypes.LINUX || this.isMarketplaceLinuxImage) {
// linux image: PlatformImage | CustomImage | StoredImage
OSProfile osProfile = this.innerModel().osProfile();
if (osProfile.linuxConfiguration() == null) {
osProfile.withLinuxConfiguration(new LinuxConfiguration());
}
this
.innerModel()
.osProfile()
.linuxConfiguration()
.withDisablePasswordAuthentication(osProfile.adminPassword() == null);
}
if (this.innerModel().osProfile().computerName() == null) {
// VM name cannot contain only numeric values and cannot exceed 15 chars
if (vmName.matches("[0-9]+")) {
this.innerModel().osProfile().withComputerName(namer.getRandomName("vm", 15));
} else if (vmName.length() <= 15) {
this.innerModel().osProfile().withComputerName(vmName);
} else {
this.innerModel().osProfile().withComputerName(namer.getRandomName("vm", 15));
}
}
} else {
// ODDisk CreateOption: ATTACH
//
// OS Profile must be set to null when an VM's OS disk is ATTACH-ed to a managed disk or
// Specialized VHD
this.innerModel().withOsProfile(null);
}
}
private void setHardwareProfileDefaults() {
if (!isInCreateMode()) {
return;
}
HardwareProfile hardwareProfile = this.innerModel().hardwareProfile();
if (hardwareProfile.vmSize() == null) {
hardwareProfile.withVmSize(VirtualMachineSizeTypes.BASIC_A0);
}
}
/** Prepare virtual machine disks profile (StorageProfile). */
private void handleUnManagedOSAndDataDisksStorageSettings() {
if (isManagedDiskEnabled()) {
// NOP if the virtual machine is based on managed disk (managed and un-managed disk cannot be mixed)
return;
}
StorageAccount storageAccount = null;
if (this.creatableStorageAccountKey != null) {
storageAccount = this.taskResult(this.creatableStorageAccountKey);
} else if (this.existingStorageAccountToAssociate != null) {
storageAccount = this.existingStorageAccountToAssociate;
}
if (isInCreateMode()) {
if (storageAccount != null) {
if (isOSDiskFromPlatformImage(innerModel().storageProfile())) {
String uri =
innerModel()
.storageProfile()
.osDisk()
.vhd()
.uri()
.replaceFirst("\\{storage-base-url}", storageAccount.endPoints().primary().blob());
innerModel().storageProfile().osDisk().vhd().withUri(uri);
}
UnmanagedDataDiskImpl.ensureDisksVhdUri(unmanagedDataDisks, storageAccount, vmName);
}
} else { // Update Mode
if (storageAccount != null) {
UnmanagedDataDiskImpl.ensureDisksVhdUri(unmanagedDataDisks, storageAccount, vmName);
} else {
UnmanagedDataDiskImpl.ensureDisksVhdUri(unmanagedDataDisks, vmName);
}
}
}
private Mono createNewProximityPlacementGroupAsync() {
if (isInCreateMode()) {
if (this.newProximityPlacementGroupName != null && !this.newProximityPlacementGroupName.isEmpty()) {
ProximityPlacementGroupInner plgInner = new ProximityPlacementGroupInner();
plgInner.withProximityPlacementGroupType(this.newProximityPlacementGroupType);
plgInner.withLocation(this.innerModel().location());
return this
.manager()
.serviceClient()
.getProximityPlacementGroups()
.createOrUpdateAsync(this.resourceGroupName(), this.newProximityPlacementGroupName, plgInner)
.map(
createdPlgInner -> {
this
.innerModel()
.withProximityPlacementGroup(new SubResource().withId(createdPlgInner.id()));
return this;
});
}
}
return Mono.just(this);
}
private void handleNetworkSettings() {
if (isInCreateMode()) {
NetworkInterface primaryNetworkInterface = null;
if (this.creatablePrimaryNetworkInterfaceKey != null) {
primaryNetworkInterface = this.taskResult(this.creatablePrimaryNetworkInterfaceKey);
} else if (this.existingPrimaryNetworkInterfaceToAssociate != null) {
primaryNetworkInterface = this.existingPrimaryNetworkInterfaceToAssociate;
}
if (primaryNetworkInterface != null) {
NetworkInterfaceReference nicReference = new NetworkInterfaceReference();
nicReference.withPrimary(true);
nicReference.withId(primaryNetworkInterface.id());
this.innerModel().networkProfile().networkInterfaces().add(nicReference);
}
}
// sets the delete options for primary network interface
if (this.primaryNetworkInterfaceDeleteOptions != null) {
String primaryNetworkInterfaceId = primaryNetworkInterfaceId();
if (primaryNetworkInterfaceId != null) {
this.innerModel().networkProfile().networkInterfaces().stream()
.filter(nic -> primaryNetworkInterfaceId.equals(nic.id()))
.forEach(nic -> nic.withDeleteOption(this.primaryNetworkInterfaceDeleteOptions));
}
}
// sets the virtual machine secondary network interfaces
//
for (String creatableSecondaryNetworkInterfaceKey : this.creatableSecondaryNetworkInterfaceKeys) {
NetworkInterface secondaryNetworkInterface = this.taskResult(creatableSecondaryNetworkInterfaceKey);
NetworkInterfaceReference nicReference = new NetworkInterfaceReference();
nicReference.withPrimary(false);
nicReference.withId(secondaryNetworkInterface.id());
if (secondaryNetworkInterfaceDeleteOptions.containsKey(creatableSecondaryNetworkInterfaceKey)) {
DeleteOptions deleteOptions
= secondaryNetworkInterfaceDeleteOptions.get(creatableSecondaryNetworkInterfaceKey);
nicReference.withDeleteOption(deleteOptions);
}
this.innerModel().networkProfile().networkInterfaces().add(nicReference);
}
for (NetworkInterface secondaryNetworkInterface : this.existingSecondaryNetworkInterfacesToAssociate) {
NetworkInterfaceReference nicReference = new NetworkInterfaceReference();
nicReference.withPrimary(false);
nicReference.withId(secondaryNetworkInterface.id());
this.innerModel().networkProfile().networkInterfaces().add(nicReference);
}
}
private void handleAvailabilitySettings() {
if (!isInCreateMode()) {
return;
}
AvailabilitySet availabilitySet = null;
if (this.creatableAvailabilitySetKey != null) {
availabilitySet = this.taskResult(this.creatableAvailabilitySetKey);
} else if (this.existingAvailabilitySetToAssociate != null) {
availabilitySet = this.existingAvailabilitySetToAssociate;
}
if (availabilitySet != null) {
if (this.innerModel().availabilitySet() == null) {
this.innerModel().withAvailabilitySet(new SubResource());
}
this.innerModel().availabilitySet().withId(availabilitySet.id());
}
}
private boolean osDiskRequiresImplicitStorageAccountCreation() {
if (isManagedDiskEnabled()) {
return false;
}
if (this.creatableStorageAccountKey != null
|| this.existingStorageAccountToAssociate != null
|| !isInCreateMode()) {
return false;
}
return isOSDiskFromPlatformImage(this.innerModel().storageProfile());
}
private boolean dataDisksRequiresImplicitStorageAccountCreation() {
if (isManagedDiskEnabled()) {
return false;
}
if (this.creatableStorageAccountKey != null
|| this.existingStorageAccountToAssociate != null
|| this.unmanagedDataDisks.size() == 0) {
return false;
}
boolean hasEmptyVhd = false;
for (VirtualMachineUnmanagedDataDisk dataDisk : this.unmanagedDataDisks) {
if (dataDisk.creationMethod() == DiskCreateOptionTypes.EMPTY
|| dataDisk.creationMethod() == DiskCreateOptionTypes.FROM_IMAGE) {
if (dataDisk.innerModel().vhd() == null) {
hasEmptyVhd = true;
break;
}
}
}
if (isInCreateMode()) {
return hasEmptyVhd;
}
if (hasEmptyVhd) {
// In update mode, if any of the data disk has vhd uri set then use same container
// to store this disk, no need to create a storage account implicitly.
for (VirtualMachineUnmanagedDataDisk dataDisk : this.unmanagedDataDisks) {
if (dataDisk.creationMethod() == DiskCreateOptionTypes.ATTACH && dataDisk.innerModel().vhd() != null) {
return false;
}
}
return true;
}
return false;
}
/**
* Checks whether the OS disk is directly attached to a unmanaged VHD.
*
* @param osDisk the osDisk value in the storage profile
* @return true if the OS disk is attached to a unmanaged VHD, false otherwise
*/
private boolean isOSDiskAttachedUnmanaged(OSDisk osDisk) {
return osDisk.createOption() == DiskCreateOptionTypes.ATTACH
&& osDisk.vhd() != null
&& osDisk.vhd().uri() != null;
}
/**
* Checks whether the OS disk is directly attached to a managed disk.
*
* @param osDisk the osDisk value in the storage profile
* @return true if the OS disk is attached to a managed disk, false otherwise
*/
private boolean isOSDiskAttachedManaged(OSDisk osDisk) {
return osDisk.createOption() == DiskCreateOptionTypes.ATTACH
&& osDisk.managedDisk() != null
&& osDisk.managedDisk().id() != null;
}
/**
* Checks whether the OS disk is based on an image (image from PIR or custom image [captured, bringYourOwnFeature]).
*
* @param osDisk the osDisk value in the storage profile
* @return true if the OS disk is configured to use image from PIR or custom image
*/
private boolean isOSDiskFromImage(OSDisk osDisk) {
return osDisk.createOption() == DiskCreateOptionTypes.FROM_IMAGE;
}
/**
* Checks whether the OS disk is based on an platform image (image in PIR).
*
* @param storageProfile the storage profile
* @return true if the OS disk is configured to be based on platform image.
*/
private boolean isOSDiskFromPlatformImage(StorageProfile storageProfile) {
ImageReference imageReference = storageProfile.imageReference();
return isOSDiskFromImage(storageProfile.osDisk())
&& imageReference != null
&& imageReference.publisher() != null
&& imageReference.offer() != null
&& imageReference.sku() != null
&& imageReference.version() != null;
}
/**
* Checks whether the OS disk is based on a CustomImage.
*
* A custom image is represented by {@link VirtualMachineCustomImage}.
*
* @param storageProfile the storage profile
* @return true if the OS disk is configured to be based on custom image.
*/
private boolean isOsDiskFromCustomImage(StorageProfile storageProfile) {
ImageReference imageReference = storageProfile.imageReference();
return isOSDiskFromImage(storageProfile.osDisk()) && imageReference != null && imageReference.id() != null;
}
/**
* Checks whether the OS disk is based on a stored image ('captured' or 'bring your own feature').
*
*
A stored image is created by calling {@link VirtualMachine#capture(String, String, boolean)}.
*
* @param storageProfile the storage profile
* @return true if the OS disk is configured to use custom image ('captured' or 'bring your own feature')
*/
private boolean isOSDiskFromStoredImage(StorageProfile storageProfile) {
OSDisk osDisk = storageProfile.osDisk();
return isOSDiskFromImage(osDisk) && osDisk.image() != null && osDisk.image().uri() != null;
}
private String temporaryBlobUrl(String containerName, String blobName) {
return "{storage-base-url}" + containerName + "/" + blobName;
}
private NetworkInterface.DefinitionStages.WithPrimaryPublicIPAddress prepareNetworkInterface(String name) {
NetworkInterface.DefinitionStages.WithGroup definitionWithGroup =
this.networkManager.networkInterfaces().define(name).withRegion(this.regionName());
NetworkInterface.DefinitionStages.WithPrimaryNetwork definitionWithNetwork;
if (this.creatableGroup != null) {
definitionWithNetwork = definitionWithGroup.withNewResourceGroup(this.creatableGroup);
} else {
definitionWithNetwork = definitionWithGroup.withExistingResourceGroup(this.resourceGroupName());
}
return definitionWithNetwork.withNewPrimaryNetwork("vnet" + name).withPrimaryPrivateIPAddressDynamic();
}
private void initializeDataDisks() {
if (this.innerModel().storageProfile().dataDisks() == null) {
this.innerModel().storageProfile().withDataDisks(new ArrayList<>());
}
this.isUnmanagedDiskSelected = false;
this.managedDataDisks.clear();
this.unmanagedDataDisks = new ArrayList<>();
if (!isManagedDiskEnabled()) {
for (DataDisk dataDiskInner : this.storageProfile().dataDisks()) {
this.unmanagedDataDisks.add(new UnmanagedDataDiskImpl(dataDiskInner, this));
}
}
}
private NetworkInterface.DefinitionStages.WithPrimaryNetwork preparePrimaryNetworkInterface(String name) {
NetworkInterface.DefinitionStages.WithGroup definitionWithGroup =
this.networkManager.networkInterfaces().define(name).withRegion(this.regionName());
NetworkInterface.DefinitionStages.WithPrimaryNetwork definitionAfterGroup;
if (this.creatableGroup != null) {
definitionAfterGroup = definitionWithGroup.withNewResourceGroup(this.creatableGroup);
} else {
definitionAfterGroup = definitionWithGroup.withExistingResourceGroup(this.resourceGroupName());
}
return definitionAfterGroup;
}
private void clearCachedRelatedResources() {
this.virtualMachineInstanceView = null;
}
private void throwIfManagedDiskEnabled(String message) {
if (this.isManagedDiskEnabled()) {
throw logger.logExceptionAsError(new UnsupportedOperationException(message));
}
}
private void throwIfManagedDiskDisabled(String message) {
if (!this.isManagedDiskEnabled()) {
throw logger.logExceptionAsError(new UnsupportedOperationException(message));
}
}
private boolean isInUpdateMode() {
return !this.isInCreateMode();
}
private DiskDeleteOptionTypes diskDeleteOptionsFromDeleteOptions(DeleteOptions deleteOptions) {
return deleteOptions == null ? null : DiskDeleteOptionTypes.fromString(deleteOptions.toString());
}
boolean isVirtualMachineModifiedDuringUpdate(VirtualMachineUpdateInner updateParameter) {
if (updateParameterSnapshotOnUpdate == null || updateParameter == null) {
return true;
} else {
try {
String jsonStrSnapshot =
SERIALIZER_ADAPTER.serialize(updateParameterSnapshotOnUpdate, SerializerEncoding.JSON);
String jsonStr = SERIALIZER_ADAPTER.serialize(updateParameter, SerializerEncoding.JSON);
return !jsonStr.equals(jsonStrSnapshot);
} catch (IOException e) {
// ignored, treat as modified
return true;
}
}
}
VirtualMachineUpdateInner deepCopyInnerToUpdateParameter() {
VirtualMachineUpdateInner updateParameter = new VirtualMachineUpdateInner();
copyInnerToUpdateParameter(updateParameter);
try {
// deep copy via json
String jsonStr = SERIALIZER_ADAPTER.serialize(updateParameter, SerializerEncoding.JSON);
updateParameter =
SERIALIZER_ADAPTER.deserialize(jsonStr, VirtualMachineUpdateInner.class, SerializerEncoding.JSON);
} catch (IOException e) {
// ignored, null to signify not available
return null;
}
// deep copy identity, with userAssignedIdentities==null to signify no change
if (this.innerModel().identity() != null) {
VirtualMachineIdentity identity = new VirtualMachineIdentity();
identity.withType(this.innerModel().identity().type());
updateParameter.withIdentity(identity);
}
return updateParameter;
}
private void copyInnerToUpdateParameter(VirtualMachineUpdateInner updateParameter) {
//updateParameter.withPlan(this.innerModel().plan()); // update cannot change plan
updateParameter.withHardwareProfile(this.innerModel().hardwareProfile());
updateParameter.withStorageProfile(this.innerModel().storageProfile());
updateParameter.withOsProfile(this.innerModel().osProfile());
updateParameter.withNetworkProfile(this.innerModel().networkProfile());
updateParameter.withDiagnosticsProfile(this.innerModel().diagnosticsProfile());
updateParameter.withBillingProfile(this.innerModel().billingProfile());
updateParameter.withSecurityProfile(this.innerModel().securityProfile());
updateParameter.withAdditionalCapabilities(this.innerModel().additionalCapabilities());
updateParameter.withAvailabilitySet(this.innerModel().availabilitySet());
updateParameter.withLicenseType(this.innerModel().licenseType());
updateParameter.withZones(this.innerModel().zones());
updateParameter.withTags(this.innerModel().tags());
updateParameter.withProximityPlacementGroup(this.innerModel().proximityPlacementGroup());
updateParameter.withPriority(this.innerModel().priority());
updateParameter.withEvictionPolicy(this.innerModel().evictionPolicy());
updateParameter.withUserData(this.innerModel().userData());
}
RoleAssignmentHelper.IdProvider idProvider() {
return new RoleAssignmentHelper.IdProvider() {
@Override
public String principalId() {
if (innerModel() != null && innerModel().identity() != null) {
return innerModel().identity().principalId();
} else {
return null;
}
}
@Override
public String resourceId() {
if (innerModel() != null) {
return innerModel().id();
} else {
return null;
}
}
};
}
@Override
public VirtualMachineImpl withPlacement(DiffDiskPlacement placement) {
if (placement != null) {
this.innerModel().storageProfile().osDisk().diffDiskSettings().withPlacement(placement);
}
return this;
}
@Override
public VirtualMachineImpl withExistingVirtualMachineScaleSet(VirtualMachineScaleSet scaleSet) {
if (scaleSet != null) {
this.innerModel().withVirtualMachineScaleSet(new SubResource().withId(scaleSet.id()));
}
return this;
}
@Override
public VirtualMachineImpl withOSDisk(String diskId) {
if (diskId == null) {
return this;
}
if (!isManagedDiskEnabled() || this.innerModel().storageProfile().osDisk().managedDisk() == null) {
return this;
}
OSDisk osDisk = new OSDisk()
// CreateOption is marked "required" in swagger, but in actual update, it's not.
// This is a workaround for bypassing this swagger bug.
.withCreateOption(this.innerModel().storageProfile().osDisk().createOption());
osDisk.withManagedDisk(new ManagedDiskParameters().withId(diskId));
this.storageProfile().withOsDisk(osDisk);
this.storageProfile().osDisk().managedDisk().withId(diskId);
return this;
}
@Override
public VirtualMachineImpl withOSDisk(Disk disk) {
if (disk == null) {
return this;
}
return withOSDisk(disk.id());
}
@Override
public VirtualMachineImpl withTrustedLaunch() {
ensureSecurityProfile().withSecurityType(SecurityTypes.TRUSTED_LAUNCH);
return this;
}
@Override
public VirtualMachineImpl withSecureBoot() {
if (securityType() == null) {
return this;
}
ensureUefiSettings().withSecureBootEnabled(true);
return this;
}
@Override
public VirtualMachineImpl withoutSecureBoot() {
if (securityType() == null) {
return this;
}
ensureUefiSettings().withSecureBootEnabled(false);
return this;
}
@Override
public VirtualMachineImpl withVTpm() {
if (securityType() == null) {
return this;
}
ensureUefiSettings().withVTpmEnabled(true);
return this;
}
@Override
public VirtualMachineImpl withoutVTpm() {
if (securityType() == null) {
return this;
}
ensureUefiSettings().withVTpmEnabled(false);
return this;
}
private SecurityProfile ensureSecurityProfile() {
SecurityProfile securityProfile = this.innerModel().securityProfile();
if (securityProfile == null) {
securityProfile = new SecurityProfile();
this.innerModel().withSecurityProfile(securityProfile);
}
return securityProfile;
}
private UefiSettings ensureUefiSettings() {
UefiSettings uefiSettings = ensureSecurityProfile().uefiSettings();
if (uefiSettings == null) {
uefiSettings = new UefiSettings();
ensureSecurityProfile().withUefiSettings(uefiSettings);
}
return uefiSettings;
}
@Override
public VirtualMachineImpl withEncryptionAtHost() {
ensureSecurityProfile().withEncryptionAtHost(true);
return this;
}
@Override
public VirtualMachineImpl withoutEncryptionAtHost() {
ensureSecurityProfile().withEncryptionAtHost(false);
return this;
}
/** Class to manage Data disk collection. */
private class ManagedDataDiskCollection {
private final Map newDisksToAttach = new HashMap<>();
private final List existingDisksToAttach = new ArrayList<>();
private final List implicitDisksToAssociate = new ArrayList<>();
private final List diskLunsToRemove = new ArrayList<>();
private final List newDisksFromImage = new ArrayList<>();
private final VirtualMachineImpl vm;
private CachingTypes defaultCachingType;
private StorageAccountTypes defaultStorageAccountType;
private DiskDeleteOptionTypes defaultDeleteOptions;
private DiskEncryptionSetParameters defaultDiskEncryptionSet;
ManagedDataDiskCollection(VirtualMachineImpl vm) {
this.vm = vm;
}
void setDefaultCachingType(CachingTypes cachingType) {
this.defaultCachingType = cachingType;
}
void setDefaultDeleteOptions(DiskDeleteOptionTypes deleteOptions) {
this.defaultDeleteOptions = deleteOptions;
}
void setDefaultStorageAccountType(StorageAccountTypes defaultStorageAccountType) {
this.defaultStorageAccountType = defaultStorageAccountType;
}
void setDefaultEncryptionSet(String diskEncryptionSetId) {
this.defaultDiskEncryptionSet = new DiskEncryptionSetParameters().withId(diskEncryptionSetId);
}
void setDataDisksDefaults() {
VirtualMachineInner vmInner = this.vm.innerModel();
if (isPending()) {
if (vmInner.storageProfile().dataDisks() == null) {
vmInner.storageProfile().withDataDisks(new ArrayList<>());
}
List dataDisks = vmInner.storageProfile().dataDisks();
final List usedLuns = new ArrayList<>();
// Get all used luns
for (DataDisk dataDisk : dataDisks) {
if (dataDisk.lun() != -1) {
usedLuns.add(dataDisk.lun());
}
}
for (DataDisk dataDisk : this.newDisksToAttach.values()) {
if (dataDisk.lun() != -1) {
usedLuns.add(dataDisk.lun());
}
}
for (DataDisk dataDisk : this.existingDisksToAttach) {
if (dataDisk.lun() != -1) {
usedLuns.add(dataDisk.lun());
}
}
for (DataDisk dataDisk : this.implicitDisksToAssociate) {
if (dataDisk.lun() != -1) {
usedLuns.add(dataDisk.lun());
}
}
for (DataDisk dataDisk : this.newDisksFromImage) {
if (dataDisk.lun() != -1) {
usedLuns.add(dataDisk.lun());
}
}
// Func to get the next available lun
Callable nextLun =
() -> {
Integer lun = 0;
while (usedLuns.contains(lun)) {
lun++;
}
usedLuns.add(lun);
return lun;
};
try {
setAttachableNewDataDisks(nextLun);
setAttachableExistingDataDisks(nextLun);
setImplicitDataDisks(nextLun);
} catch (Exception ex) {
throw logger.logExceptionAsError(Exceptions.propagate(ex));
}
setImageBasedDataDisks();
removeDataDisks();
}
if (vmInner.storageProfile().dataDisks() != null && vmInner.storageProfile().dataDisks().size() == 0) {
if (vm.isInCreateMode()) {
// If there is no data disks at all, then setting it to null rather than [] is necessary.
// This is for take advantage of CRP's implicit creation of the data disks if the image has
// more than one data disk image(s).
vmInner.storageProfile().withDataDisks(null);
}
}
this.clear();
}
private void clear() {
newDisksToAttach.clear();
existingDisksToAttach.clear();
implicitDisksToAssociate.clear();
diskLunsToRemove.clear();
newDisksFromImage.clear();
defaultCachingType = null;
defaultStorageAccountType = null;
defaultDeleteOptions = null;
defaultDiskEncryptionSet = null;
}
private boolean isPending() {
return newDisksToAttach.size() > 0
|| existingDisksToAttach.size() > 0
|| implicitDisksToAssociate.size() > 0
|| diskLunsToRemove.size() > 0
|| newDisksFromImage.size() > 0;
}
private void setDefaultDiskEncryptionSetOptions(DataDisk dataDisk) {
if (getDefaultDiskEncryptionSetOptions() != null) {
if (dataDisk.managedDisk() != null && dataDisk.managedDisk().diskEncryptionSet() != null) {
if (dataDisk.managedDisk().diskEncryptionSet().id() == null) {
// case that configuration on specific disk override the default, set DiskEncryptionSet to null
dataDisk.managedDisk().withDiskEncryptionSet(null);
}
// else, keep the configuration on DiskEncryptionSet unmodified (via VirtualMachineDiskOptions)
} else {
if (dataDisk.managedDisk() == null) {
dataDisk.withManagedDisk(new ManagedDiskParameters());
}
dataDisk.managedDisk().withDiskEncryptionSet(getDefaultDiskEncryptionSetOptions());
}
}
}
private void setAttachableNewDataDisks(Callable nextLun) throws Exception {
List dataDisks = vm.innerModel().storageProfile().dataDisks();
for (Map.Entry entry : this.newDisksToAttach.entrySet()) {
Disk managedDisk = vm.taskResult(entry.getKey());
DataDisk dataDisk = entry.getValue();
dataDisk.withCreateOption(DiskCreateOptionTypes.ATTACH);
if (dataDisk.lun() == -1) {
dataDisk.withLun(nextLun.call());
}
dataDisk.withManagedDisk(new ManagedDiskParameters());
dataDisk.managedDisk().withId(managedDisk.id());
if (dataDisk.caching() == null) {
dataDisk.withCaching(getDefaultCachingType());
}
if (dataDisk.deleteOption() == null) {
dataDisk.withDeleteOption(getDefaultDeleteOptions());
}
setDefaultDiskEncryptionSetOptions(dataDisk);
// Don't set default storage account type for the attachable managed disks, it is already
// defined in the managed disk and not allowed to change.
dataDisk.withName(null);
dataDisks.add(dataDisk);
}
}
private void setAttachableExistingDataDisks(Callable nextLun) throws Exception {
List dataDisks = vm.innerModel().storageProfile().dataDisks();
for (DataDisk dataDisk : this.existingDisksToAttach) {
dataDisk.withCreateOption(DiskCreateOptionTypes.ATTACH);
if (dataDisk.lun() == -1) {
dataDisk.withLun(nextLun.call());
}
if (dataDisk.caching() == null) {
dataDisk.withCaching(getDefaultCachingType());
}
if (dataDisk.deleteOption() == null) {
dataDisk.withDeleteOption(getDefaultDeleteOptions());
}
setDefaultDiskEncryptionSetOptions(dataDisk);
// Don't set default storage account type for the attachable managed disks, it is already
// defined in the managed disk and not allowed to change.
dataDisk.withName(null);
dataDisks.add(dataDisk);
}
}
private void setImplicitDataDisks(Callable nextLun) throws Exception {
List dataDisks = vm.innerModel().storageProfile().dataDisks();
for (DataDisk dataDisk : this.implicitDisksToAssociate) {
dataDisk.withCreateOption(DiskCreateOptionTypes.EMPTY);
if (dataDisk.lun() == -1) {
dataDisk.withLun(nextLun.call());
}
if (dataDisk.caching() == null) {
dataDisk.withCaching(getDefaultCachingType());
}
if (dataDisk.managedDisk() == null) {
dataDisk.withManagedDisk(new ManagedDiskParameters());
}
if (dataDisk.managedDisk().storageAccountType() == null) {
dataDisk.managedDisk().withStorageAccountType(getDefaultStorageAccountType());
}
if (dataDisk.deleteOption() == null) {
dataDisk.withDeleteOption(getDefaultDeleteOptions());
}
setDefaultDiskEncryptionSetOptions(dataDisk);
dataDisk.withName(null);
dataDisks.add(dataDisk);
}
}
private void setImageBasedDataDisks() {
List dataDisks = vm.innerModel().storageProfile().dataDisks();
for (DataDisk dataDisk : this.newDisksFromImage) {
dataDisk.withCreateOption(DiskCreateOptionTypes.FROM_IMAGE);
if (dataDisk.caching() == null) {
dataDisk.withCaching(getDefaultCachingType());
}
if (dataDisk.deleteOption() == null) {
dataDisk.withDeleteOption(getDefaultDeleteOptions());
}
setDefaultDiskEncryptionSetOptions(dataDisk);
// Don't set default storage account type for the disk, either user has to specify it explicitly or let
// CRP pick it from the image
dataDisk.withName(null);
dataDisks.add(dataDisk);
}
}
private void removeDataDisks() {
List dataDisks = vm.innerModel().storageProfile().dataDisks();
for (Integer lun : this.diskLunsToRemove) {
int indexToRemove = 0;
for (DataDisk dataDisk : dataDisks) {
if (dataDisk.lun() == lun) {
dataDisks.remove(indexToRemove);
break;
}
indexToRemove++;
}
}
}
private CachingTypes getDefaultCachingType() {
if (defaultCachingType == null) {
return CachingTypes.READ_WRITE;
}
return defaultCachingType;
}
private StorageAccountTypes getDefaultStorageAccountType() {
if (defaultStorageAccountType == null) {
return StorageAccountTypes.STANDARD_LRS;
}
return defaultStorageAccountType;
}
private DiskDeleteOptionTypes getDefaultDeleteOptions() {
return defaultDeleteOptions;
}
private DiskEncryptionSetParameters getDefaultDiskEncryptionSetOptions() {
return defaultDiskEncryptionSet;
}
}
/** Class to manage VM boot diagnostics settings. */
private class BootDiagnosticsHandler {
private final VirtualMachineImpl vmImpl;
private String creatableDiagnosticsStorageAccountKey;
private boolean useManagedStorageAccount = false;
BootDiagnosticsHandler(VirtualMachineImpl vmImpl) {
this.vmImpl = vmImpl;
if (isBootDiagnosticsEnabled()
&& this.vmInner().diagnosticsProfile().bootDiagnostics().storageUri() == null) {
this.useManagedStorageAccount = true;
}
}
public boolean isBootDiagnosticsEnabled() {
if (this.vmInner().diagnosticsProfile() != null
&& this.vmInner().diagnosticsProfile().bootDiagnostics() != null
&& this.vmInner().diagnosticsProfile().bootDiagnostics().enabled() != null) {
return this.vmInner().diagnosticsProfile().bootDiagnostics().enabled();
}
return false;
}
public String bootDiagnosticsStorageUri() {
// Even though diagnostics can disabled azure still keep the storage uri
if (this.vmInner().diagnosticsProfile() != null
&& this.vmInner().diagnosticsProfile().bootDiagnostics() != null) {
return this.vmInner().diagnosticsProfile().bootDiagnostics().storageUri();
}
return null;
}
BootDiagnosticsHandler withBootDiagnostics(boolean useManagedStorageAccount) {
// Diagnostics storage uri will be set later by this.handleDiagnosticsSettings(..)
this.enableDisable(true);
this.useManagedStorageAccount = useManagedStorageAccount;
return this;
}
BootDiagnosticsHandler withBootDiagnostics(Creatable creatable) {
// Diagnostics storage uri will be set later by this.handleDiagnosticsSettings(..)
this.enableDisable(true);
this.useManagedStorageAccount = false;
this.creatableDiagnosticsStorageAccountKey = this.vmImpl.addDependency(creatable);
return this;
}
BootDiagnosticsHandler withBootDiagnostics(String storageAccountBlobEndpointUri) {
this.enableDisable(true);
this.useManagedStorageAccount = false;
this.vmInner().diagnosticsProfile().bootDiagnostics().withStorageUri(storageAccountBlobEndpointUri);
return this;
}
BootDiagnosticsHandler withBootDiagnostics(StorageAccount storageAccount) {
return this.withBootDiagnostics(storageAccount.endPoints().primary().blob());
}
BootDiagnosticsHandler withoutBootDiagnostics() {
this.enableDisable(false);
this.useManagedStorageAccount = false;
return this;
}
void prepare() {
if (useManagedStorageAccount) {
return;
}
DiagnosticsProfile diagnosticsProfile = this.vmInner().diagnosticsProfile();
if (diagnosticsProfile == null
|| diagnosticsProfile.bootDiagnostics() == null
|| diagnosticsProfile.bootDiagnostics().storageUri() != null) {
return;
}
boolean enableBD = ResourceManagerUtils.toPrimitiveBoolean(diagnosticsProfile.bootDiagnostics().enabled());
if (!enableBD) {
return;
}
if (this.creatableDiagnosticsStorageAccountKey != null
|| this.vmImpl.creatableStorageAccountKey != null
|| this.vmImpl.existingStorageAccountToAssociate != null) {
return;
}
String accountName = this.vmImpl.namer.getRandomName("stg", 24).replace("-", "");
Creatable storageAccountCreatable;
if (this.vmImpl.creatableGroup != null) {
storageAccountCreatable =
this
.vmImpl
.storageManager
.storageAccounts()
.define(accountName)
.withRegion(this.vmImpl.regionName())
.withNewResourceGroup(this.vmImpl.creatableGroup);
} else {
storageAccountCreatable =
this
.vmImpl
.storageManager
.storageAccounts()
.define(accountName)
.withRegion(this.vmImpl.regionName())
.withExistingResourceGroup(this.vmImpl.resourceGroupName());
}
this.creatableDiagnosticsStorageAccountKey = this.vmImpl.addDependency(storageAccountCreatable);
}
void handleDiagnosticsSettings() {
if (useManagedStorageAccount) {
return;
}
DiagnosticsProfile diagnosticsProfile = this.vmInner().diagnosticsProfile();
if (diagnosticsProfile == null
|| diagnosticsProfile.bootDiagnostics() == null
|| diagnosticsProfile.bootDiagnostics().storageUri() != null) {
return;
}
boolean enableBD = ResourceManagerUtils.toPrimitiveBoolean(diagnosticsProfile.bootDiagnostics().enabled());
if (!enableBD) {
return;
}
StorageAccount storageAccount = null;
if (creatableDiagnosticsStorageAccountKey != null) {
storageAccount = this.vmImpl.taskResult(creatableDiagnosticsStorageAccountKey);
} else if (this.vmImpl.creatableStorageAccountKey != null) {
storageAccount = this.vmImpl.taskResult(this.vmImpl.creatableStorageAccountKey);
} else if (this.vmImpl.existingStorageAccountToAssociate != null) {
storageAccount = this.vmImpl.existingStorageAccountToAssociate;
}
if (storageAccount == null) {
throw logger
.logExceptionAsError(
new IllegalStateException(
"Unable to retrieve expected storageAccount instance for BootDiagnostics"));
}
vmInner()
.diagnosticsProfile()
.bootDiagnostics()
.withStorageUri(storageAccount.endPoints().primary().blob());
}
private VirtualMachineInner vmInner() {
// Inner cannot be cached as parent VirtualMachineImpl can refresh the inner in various cases
return this.vmImpl.innerModel();
}
private void enableDisable(boolean enable) {
if (this.vmInner().diagnosticsProfile() == null) {
this.vmInner().withDiagnosticsProfile(new DiagnosticsProfile());
}
if (this.vmInner().diagnosticsProfile().bootDiagnostics() == null) {
this.vmInner().diagnosticsProfile().withBootDiagnostics(new BootDiagnostics());
}
if (enable) {
this.vmInner().diagnosticsProfile().bootDiagnostics().withEnabled(true);
} else {
this.vmInner().diagnosticsProfile().bootDiagnostics().withEnabled(false);
this.vmInner().diagnosticsProfile().bootDiagnostics().withStorageUri(null);
}
}
}
}