Adding support for provisioning of Windows VMs with enabled WinRM

- Provisioning using pre-existing KeyVault
- Enabling WinRM with pre-existing certificate
This commit is contained in:
Yavor Yanchev 2017-05-19 12:41:16 +03:00 committed by Svetoslav Neykov
parent 45480c4913
commit 50ae01985a
11 changed files with 513 additions and 73 deletions

View File

@ -64,6 +64,8 @@ import org.jclouds.azurecompute.arm.domain.ManagedDiskParameters;
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard; import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties; import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
import org.jclouds.azurecompute.arm.domain.NetworkProfile; import org.jclouds.azurecompute.arm.domain.NetworkProfile;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface.NetworkInterfaceProperties;
import org.jclouds.azurecompute.arm.domain.OSDisk; import org.jclouds.azurecompute.arm.domain.OSDisk;
import org.jclouds.azurecompute.arm.domain.OSProfile; import org.jclouds.azurecompute.arm.domain.OSProfile;
import org.jclouds.azurecompute.arm.domain.Offer; import org.jclouds.azurecompute.arm.domain.Offer;
@ -82,8 +84,6 @@ import org.jclouds.azurecompute.arm.domain.VMSize;
import org.jclouds.azurecompute.arm.domain.Version; import org.jclouds.azurecompute.arm.domain.Version;
import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.azurecompute.arm.domain.VirtualMachine;
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface.NetworkInterfaceProperties;
import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi; import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
import org.jclouds.azurecompute.arm.features.OSImageApi; import org.jclouds.azurecompute.arm.features.OSImageApi;
import org.jclouds.compute.ComputeServiceAdapter; import org.jclouds.compute.ComputeServiceAdapter;
@ -390,6 +390,17 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
builder.linuxConfiguration(linuxConfiguration); builder.linuxConfiguration(linuxConfiguration);
} }
AzureTemplateOptions azureTemplateOptions = template.getOptions().as(AzureTemplateOptions.class);
if (azureTemplateOptions.getWindowsConfiguration() != null) {
builder.windowsConfiguration(azureTemplateOptions.getWindowsConfiguration());
}
if (azureTemplateOptions.getSecrets() != null) {
builder.secrets(azureTemplateOptions.getSecrets());
}
return builder.build(); return builder.build();
} }
@ -526,5 +537,4 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
private IdReference getAvailabilitySetIdReference(AvailabilitySet availabilitySet) { private IdReference getAvailabilitySetIdReference(AvailabilitySet availabilitySet) {
return availabilitySet != null ? IdReference.create(availabilitySet.id()) : null; return availabilitySet != null ? IdReference.create(availabilitySet.id()) : null;
} }
} }

View File

@ -16,17 +16,19 @@
*/ */
package org.jclouds.azurecompute.arm.compute.options; package org.jclouds.azurecompute.arm.compute.options;
import static com.google.common.base.Preconditions.checkNotNull;
import java.util.List; import java.util.List;
import org.jclouds.azurecompute.arm.domain.AvailabilitySet; import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
import org.jclouds.azurecompute.arm.domain.DataDisk; import org.jclouds.azurecompute.arm.domain.DataDisk;
import org.jclouds.azurecompute.arm.domain.OSProfile.WindowsConfiguration;
import org.jclouds.azurecompute.arm.domain.Secrets;
import org.jclouds.compute.options.TemplateOptions; import org.jclouds.compute.options.TemplateOptions;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import static com.google.common.base.Preconditions.checkNotNull;
/** /**
* Azure ARM custom options * Azure ARM custom options
*/ */
@ -37,6 +39,8 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
private List<DataDisk> dataDisks = ImmutableList.of(); private List<DataDisk> dataDisks = ImmutableList.of();
private String resourceGroup; private String resourceGroup;
private List<IpOptions> ipOptions = ImmutableList.of(); private List<IpOptions> ipOptions = ImmutableList.of();
private WindowsConfiguration windowsConfiguration;
private List<Secrets> secrets = ImmutableList.of();
/** /**
* Sets the availability set where the nodes will be configured. If it does * Sets the availability set where the nodes will be configured. If it does
@ -99,11 +103,35 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
return ipOptions(ImmutableList.copyOf(checkNotNull(ipOptions, "ipOptions"))); return ipOptions(ImmutableList.copyOf(checkNotNull(ipOptions, "ipOptions")));
} }
/**
* Windows configuration parameters
*
* @see <a href="https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines/virtualmachines-create-or-update#bk_windowsconfig5">docs</a>
*/
public AzureTemplateOptions windowsConfiguration(WindowsConfiguration windowsConfiguration) {
this.windowsConfiguration = windowsConfiguration;
return this;
}
/**
* Import certificates in the Windows Certificate Store
*
* @see <a href="https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines/virtualmachines-create-or-update#bk_srcvault">docs</a>
*/
public AzureTemplateOptions secrets(Iterable<? extends Secrets> secrets) {
for (Secrets secret : checkNotNull(secrets, "secrets"))
checkNotNull(secret, "secrets can not be empty");
this.secrets = ImmutableList.copyOf(secrets);
return this;
}
public AvailabilitySet getAvailabilitySet() { return availabilitySet; } public AvailabilitySet getAvailabilitySet() { return availabilitySet; }
public String getAvailabilitySetName() { return availabilitySetName; } public String getAvailabilitySetName() { return availabilitySetName; }
public List<DataDisk> getDataDisks() { return dataDisks; } public List<DataDisk> getDataDisks() { return dataDisks; }
public String getResourceGroup() { return resourceGroup; } public String getResourceGroup() { return resourceGroup; }
public List<IpOptions> getIpOptions() { return ipOptions; } public List<IpOptions> getIpOptions() { return ipOptions; }
public WindowsConfiguration getWindowsConfiguration() { return windowsConfiguration; }
public List<Secrets> getSecrets() { return secrets; }
@Override @Override
public AzureTemplateOptions clone() { public AzureTemplateOptions clone() {
@ -122,6 +150,8 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
eTo.dataDisks(dataDisks); eTo.dataDisks(dataDisks);
eTo.resourceGroup(resourceGroup); eTo.resourceGroup(resourceGroup);
eTo.ipOptions(ipOptions); eTo.ipOptions(ipOptions);
eTo.windowsConfiguration(windowsConfiguration);
eTo.secrets(secrets);
} }
} }
@ -137,7 +167,9 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
Objects.equal(resourceGroup, that.resourceGroup) && Objects.equal(resourceGroup, that.resourceGroup) &&
Objects.equal(availabilitySet, that.availabilitySet) && Objects.equal(availabilitySet, that.availabilitySet) &&
Objects.equal(dataDisks, that.dataDisks) && Objects.equal(dataDisks, that.dataDisks) &&
Objects.equal(ipOptions, that.ipOptions); Objects.equal(ipOptions, that.ipOptions) &&
Objects.equal(windowsConfiguration, that.windowsConfiguration) &&
Objects.equal(secrets, that.secrets);
} }
@Override @Override
@ -159,6 +191,10 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
toString.add("resourceGroup", resourceGroup); toString.add("resourceGroup", resourceGroup);
if (!ipOptions.isEmpty()) if (!ipOptions.isEmpty())
toString.add("ipOptions", ipOptions); toString.add("ipOptions", ipOptions);
if (windowsConfiguration != null)
toString.add("windowsConfiguration", windowsConfiguration);
if (!secrets.isEmpty())
toString.add("secrets", secrets);
return toString; return toString;
} }
@ -219,5 +255,21 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
AzureTemplateOptions options = new AzureTemplateOptions(); AzureTemplateOptions options = new AzureTemplateOptions();
return options.ipOptions(ipOptions); return options.ipOptions(ipOptions);
} }
/**
* @see AzureTemplateOptions#windowsConfiguration(WindowsConfiguration)
*/
public static AzureTemplateOptions windowsConfiguration(WindowsConfiguration windowsConfiguration) {
AzureTemplateOptions options = new AzureTemplateOptions();
return options.windowsConfiguration(windowsConfiguration);
}
/**
* @see AzureTemplateOptions#secrets(List)
*/
public static AzureTemplateOptions secrets(Iterable<? extends Secrets> secrets) {
AzureTemplateOptions options = new AzureTemplateOptions();
return options.secrets(secrets);
}
} }
} }

View File

@ -16,15 +16,14 @@
*/ */
package org.jclouds.azurecompute.arm.domain; package org.jclouds.azurecompute.arm.domain;
import com.google.auto.value.AutoValue; import java.util.List;
import com.google.common.collect.ImmutableList;
import org.jclouds.azurecompute.arm.util.GetEnumValue;
import org.jclouds.javax.annotation.Nullable; import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames; import org.jclouds.json.SerializedNames;
import java.util.List; import com.google.auto.value.AutoValue;
import java.util.Map; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
@AutoValue @AutoValue
public abstract class OSProfile { public abstract class OSProfile {
@ -91,15 +90,52 @@ public abstract class OSProfile {
@AutoValue @AutoValue
public abstract static class WinRM { public abstract static class WinRM {
public enum Protocol {
HTTP("http"),
HTTPS("https"),
UNRECOGNIZED("Unrecognized");
private String value;
Protocol(String value) {
this.value = value;
}
public static Protocol fromValue(String value) {
return (Protocol) GetEnumValue.fromValueOrDefault(value, Protocol.UNRECOGNIZED);
}
@Override
public String toString() {
return this.value;
}
}
@AutoValue
public abstract static class ProtocolListener {
public abstract Protocol protocol();
@Nullable
public abstract String certificateUrl();
@SerializedNames({"protocol", "certificateUrl"})
public static ProtocolListener create(final Protocol protocol, final String certificateUrl) {
return new AutoValue_OSProfile_WindowsConfiguration_WinRM_ProtocolListener(
protocol, certificateUrl);
}
}
/** /**
* Map of different settings * Map of different settings
*/ */
public abstract Map<String, String> listeners(); public abstract List<ProtocolListener> listeners();
@SerializedNames({"listeners"}) @SerializedNames({"listeners"})
public static WinRM create(final Map<String, String> listeners) { public static WinRM create(final List<ProtocolListener> listeners) {
return new AutoValue_OSProfile_WindowsConfiguration_WinRM(listeners == null ? ImmutableMap.<String, String>of() : ImmutableMap.copyOf(listeners)); return new AutoValue_OSProfile_WindowsConfiguration_WinRM(listeners == null ? ImmutableList.<ProtocolListener>of() : ImmutableList.copyOf(listeners));
} }
} }
@ -139,27 +175,20 @@ public abstract class OSProfile {
* unattend content * unattend content
*/ */
@Nullable @Nullable
public abstract AdditionalUnattendContent additionalUnattendContent(); public abstract List<AdditionalUnattendContent> additionalUnattendContent();
/** /**
* is automatic updates enabled * is automatic updates enabled
*/ */
public abstract boolean enableAutomaticUpdates(); public abstract boolean enableAutomaticUpdates();
/** @SerializedNames({"provisionVMAgent", "winRM", "additionalUnattendContent", "enableAutomaticUpdates"})
* list of certificates
*/
@Nullable
public abstract List<String> secrets();
@SerializedNames({"provisionVMAgent", "winRM", "additionalUnattendContent", "enableAutomaticUpdates",
"secrets"})
public static WindowsConfiguration create(final boolean provisionVMAgent, final WinRM winRM, public static WindowsConfiguration create(final boolean provisionVMAgent, final WinRM winRM,
final AdditionalUnattendContent additionalUnattendContent, final List<AdditionalUnattendContent> additionalUnattendContent,
final boolean enableAutomaticUpdates, final List<String> secrets) { final boolean enableAutomaticUpdates) {
return new AutoValue_OSProfile_WindowsConfiguration(provisionVMAgent, winRM, return new AutoValue_OSProfile_WindowsConfiguration(provisionVMAgent, winRM,
additionalUnattendContent, enableAutomaticUpdates, secrets == null ? null : ImmutableList.copyOf(secrets)); additionalUnattendContent, enableAutomaticUpdates);
} }
} }
@ -199,11 +228,17 @@ public abstract class OSProfile {
@Nullable @Nullable
public abstract WindowsConfiguration windowsConfiguration(); public abstract WindowsConfiguration windowsConfiguration();
/**
* The Secrets configuration of the VM
*/
@Nullable
public abstract List<Secrets> secrets();
@SerializedNames({"computerName", "adminUsername", "adminPassword", "customData", "linuxConfiguration", @SerializedNames({"computerName", "adminUsername", "adminPassword", "customData", "linuxConfiguration",
"windowsConfiguration"}) "windowsConfiguration", "secrets"})
public static OSProfile create(final String computerName, final String adminUsername, final String adminPassword, public static OSProfile create(final String computerName, final String adminUsername, final String adminPassword,
final String customData, final LinuxConfiguration linuxConfiguration, final String customData, final LinuxConfiguration linuxConfiguration,
final WindowsConfiguration windowsConfiguration) { final WindowsConfiguration windowsConfiguration, final List<Secrets> secrets) {
return builder() return builder()
.computerName(computerName) .computerName(computerName)
.adminUsername(adminUsername) .adminUsername(adminUsername)
@ -211,6 +246,7 @@ public abstract class OSProfile {
.customData(customData) .customData(customData)
.linuxConfiguration(linuxConfiguration) .linuxConfiguration(linuxConfiguration)
.windowsConfiguration(windowsConfiguration) .windowsConfiguration(windowsConfiguration)
.secrets(secrets)
.build(); .build();
} }
@ -234,6 +270,8 @@ public abstract class OSProfile {
public abstract Builder windowsConfiguration(WindowsConfiguration windowsConfiguration); public abstract Builder windowsConfiguration(WindowsConfiguration windowsConfiguration);
public abstract Builder secrets(List<Secrets> secrets);
public abstract OSProfile build(); public abstract OSProfile build();
} }
} }

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.azurecompute.arm.domain;
import com.google.auto.value.AutoValue;
import org.jclouds.json.SerializedNames;
import java.util.List;
/**
* Group of certificates stored in one and the same KeyVault
*/
@AutoValue
public abstract class Secrets {
@AutoValue
public abstract static class SourceVault {
public abstract String id();
@SerializedNames({"id"})
public static SourceVault create(final String id) {
return new AutoValue_Secrets_SourceVault(id);
}
}
/**
* Name of the KeyVault which contains all the certificates
*/
public abstract SourceVault sourceVault();
/**
* List of the certificates
*/
public abstract List<VaultCertificate> vaultCertificates();
@SerializedNames({"sourceVault", "vaultCertificates"})
public static Secrets create(final SourceVault sourceVault, final List<VaultCertificate> vaultCertificates) {
return new AutoValue_Secrets(sourceVault, vaultCertificates);
}
}

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.azurecompute.arm.domain;
import com.google.auto.value.AutoValue;
import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;
/**
* Certificate stored in a Key Vault
*/
@AutoValue
public abstract class VaultCertificate {
/**
* The URL of the certificate
*/
public abstract String certificateUrl();
/**
* Certificate's store name
*/
@Nullable
public abstract String certificateStore();
@SerializedNames({"certificateUrl", "certificateStore"})
public static VaultCertificate create(final String certificateUrl, final String certificateStore) {
return new AutoValue_VaultCertificate(certificateUrl, certificateStore);
}
}

View File

@ -42,22 +42,28 @@ import org.jclouds.azurecompute.arm.domain.NetworkProfile;
import org.jclouds.azurecompute.arm.domain.OSDisk; import org.jclouds.azurecompute.arm.domain.OSDisk;
import org.jclouds.azurecompute.arm.domain.OSProfile; import org.jclouds.azurecompute.arm.domain.OSProfile;
import org.jclouds.azurecompute.arm.domain.ResourceDefinition; import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
import org.jclouds.azurecompute.arm.domain.Secrets;
import org.jclouds.azurecompute.arm.domain.StorageAccountType; import org.jclouds.azurecompute.arm.domain.StorageAccountType;
import org.jclouds.azurecompute.arm.domain.StorageProfile; import org.jclouds.azurecompute.arm.domain.StorageProfile;
import org.jclouds.azurecompute.arm.domain.StorageService; import org.jclouds.azurecompute.arm.domain.StorageService;
import org.jclouds.azurecompute.arm.domain.Subnet; import org.jclouds.azurecompute.arm.domain.Subnet;
import org.jclouds.azurecompute.arm.domain.VHD; import org.jclouds.azurecompute.arm.domain.VHD;
import org.jclouds.azurecompute.arm.domain.VaultCertificate;
import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.azurecompute.arm.domain.VirtualMachine;
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance; import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.PowerState; import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.PowerState;
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface; import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface.NetworkInterfaceProperties; import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface.NetworkInterfaceProperties;
import org.jclouds.azurecompute.arm.domain.OSProfile.WindowsConfiguration.WinRM.Protocol;
import org.jclouds.azurecompute.arm.domain.OSProfile.WindowsConfiguration.WinRM.ProtocolListener;
import org.jclouds.azurecompute.arm.functions.ParseJobStatus; import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest; import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import static org.testng.util.Strings.isNullOrEmpty;
import com.beust.jcommander.internal.Lists;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -79,6 +85,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
subscriptionid = getSubscriptionId(); subscriptionid = getSubscriptionId();
createTestResourceGroup(); createTestResourceGroup();
virtualNetworkName = String.format("vn-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name")); virtualNetworkName = String.format("vn-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
// Subnets belong to a virtual network so that needs to be created first // Subnets belong to a virtual network so that needs to be created first
@ -232,9 +239,9 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
private VirtualMachineProperties getProperties(String nic, String blob) { private VirtualMachineProperties getProperties(String nic, String blob) {
HardwareProfile hwProf = HardwareProfile.create("Standard_D1"); HardwareProfile hwProf = HardwareProfile.create("Standard_D1_v2");
ImageReference imgRef = ImageReference.builder().publisher("MicrosoftWindowsServerEssentials") ImageReference imgRef = ImageReference.builder().publisher("MicrosoftWindowsServer")
.offer("WindowsServerEssentials").sku("WindowsServerEssentials").version("latest").build(); .offer("WindowsServer").sku("2008-R2-SP1").version("latest").build();
DataDisk.Builder dataDisk = DataDisk.builder().name("data").diskSizeGB("100").lun(0).createOption(DataDisk.DiskCreateOptionTypes.EMPTY); DataDisk.Builder dataDisk = DataDisk.builder().name("data").diskSizeGB("100").lun(0).createOption(DataDisk.DiskCreateOptionTypes.EMPTY);
@ -252,9 +259,23 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
} }
StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk.build(), ImmutableList.of(dataDisk.build())); StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk.build(), ImmutableList.of(dataDisk.build()));
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
null); List<Secrets> secrets = null;
OSProfile osProfile = OSProfile.create(vmName, "azureuser", "RFe3&432dg", null, null, windowsConfig); OSProfile.WindowsConfiguration.WinRM winRm = null;
if (!isNullOrEmpty(vaultResourceGroup) && !isNullOrEmpty(vaultName) && !isNullOrEmpty(vaultCertificateUrl)) {
List<ProtocolListener> listeners = Lists.newArrayList();
listeners.add(OSProfile.WindowsConfiguration.WinRM.ProtocolListener.create(Protocol.HTTPS, vaultCertificateUrl));
listeners.add(OSProfile.WindowsConfiguration.WinRM.ProtocolListener.create(Protocol.HTTP, null));
winRm = OSProfile.WindowsConfiguration.WinRM.create(listeners);
VaultCertificate vaultCertificate = VaultCertificate.create(vaultCertificateUrl, vaultName);
secrets = ImmutableList.of(Secrets.create(Secrets.SourceVault.create(String.format("%s/providers/Microsoft.KeyVault/vaults/%s",
api.getResourceGroupApi().get(vaultResourceGroup).id(), vaultName)),
ImmutableList.of(vaultCertificate)));
}
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(true, winRm, null, true);
OSProfile osProfile = OSProfile.create(vmName, "azureuser", "RFe3&432dg", null, null, windowsConfig, secrets);
NetworkInterface networkInterface = NetworkInterface networkInterface =
NetworkInterface.create("/subscriptions/" + subscriptionid + NetworkInterface.create("/subscriptions/" + subscriptionid +
"/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/" "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/"

View File

@ -32,15 +32,23 @@ import java.util.List;
import org.jclouds.azurecompute.arm.domain.DataDisk; import org.jclouds.azurecompute.arm.domain.DataDisk;
import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile; import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile;
import org.jclouds.azurecompute.arm.domain.HardwareProfile; import org.jclouds.azurecompute.arm.domain.HardwareProfile;
import org.jclouds.azurecompute.arm.domain.IdReference;
import org.jclouds.azurecompute.arm.domain.ImageReference; import org.jclouds.azurecompute.arm.domain.ImageReference;
import org.jclouds.azurecompute.arm.domain.ManagedDiskParameters;
import org.jclouds.azurecompute.arm.domain.NetworkProfile; import org.jclouds.azurecompute.arm.domain.NetworkProfile;
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface; import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
import org.jclouds.azurecompute.arm.domain.OSDisk; import org.jclouds.azurecompute.arm.domain.OSDisk;
import org.jclouds.azurecompute.arm.domain.OSProfile; import org.jclouds.azurecompute.arm.domain.OSProfile;
import org.jclouds.azurecompute.arm.domain.OSProfile.LinuxConfiguration;
import org.jclouds.azurecompute.arm.domain.OSProfile.WindowsConfiguration.AdditionalUnattendContent;
import org.jclouds.azurecompute.arm.domain.OSProfile.WindowsConfiguration.WinRM.Protocol;
import org.jclouds.azurecompute.arm.domain.Secrets.SourceVault;
import org.jclouds.azurecompute.arm.domain.Plan; import org.jclouds.azurecompute.arm.domain.Plan;
import org.jclouds.azurecompute.arm.domain.Secrets;
import org.jclouds.azurecompute.arm.domain.Status; import org.jclouds.azurecompute.arm.domain.Status;
import org.jclouds.azurecompute.arm.domain.StorageProfile; import org.jclouds.azurecompute.arm.domain.StorageProfile;
import org.jclouds.azurecompute.arm.domain.VHD; import org.jclouds.azurecompute.arm.domain.VHD;
import org.jclouds.azurecompute.arm.domain.VaultCertificate;
import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.azurecompute.arm.domain.VirtualMachine;
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance; import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
@ -122,18 +130,30 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
"PUT", "PUT",
"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute"
+ "/virtualMachines/windowsmachine?validating=false&api-version=2016-04-30-preview", + "/virtualMachines/windowsmachine?validating=false&api-version=2016-04-30-preview",
"{\"location\":\"westus\",\"tags\":{\"foo\":\"bar\"},\"properties\":" "{\"location\":\"westus\",\"properties\":"
+ "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\"," + "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\",\"licenseType\":\"Windows_Server\","
+ "\"availabilitySet\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet\"},"
+ "\"hardwareProfile\":{\"vmSize\":\"Standard_D1\"}," + "\"hardwareProfile\":{\"vmSize\":\"Standard_D1\"},"
+ "\"storageProfile\":{\"imageReference\":{\"publisher\":\"publisher\",\"offer\":\"offer\",\"sku\":\"sku\",\"version\":\"ver\"}," + "\"storageProfile\":{\"imageReference\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute/locations/westus/publishers/MicrosoftWindowsServerEssentials/artifactype/vmimage/offers/OFFER/skus/OFFER/versions/latest\","
+ "\"publisher\":\"publisher\",\"offer\":\"OFFER\",\"sku\":\"sku\",\"version\":\"ver\"},"
+ "\"osDisk\":{\"osType\":\"Windows\",\"name\":\"windowsmachine\"," + "\"osDisk\":{\"osType\":\"Windows\",\"name\":\"windowsmachine\","
+ "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\"},\"dataDisks\":[]}," + "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\","
+ "\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"windowsConfiguration\":{\"provisionVMAgent\":false,\"enableAutomaticUpdates\":true}}," + "\"managedDisk\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk\",\"storageAccountType\":\"Standard_LRS\"}},"
+ "\"dataDisks\":[{\"name\":\"mydatadisk1\",\"diskSizeGB\":\"1\",\"lun\":0,\"vhd\":{\"uri\":\"http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd\"},\"createOption\":\"Empty\",\"caching\":\"Unrecognized\"}]},"
+ "\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"adminPassword\":\"password\",\"customData\":\"\",\"windowsConfiguration\":{\"provisionVMAgent\":false,"
+ "\"winRM\":{\"listeners\":[{\"protocol\":\"https\",\"certificateUrl\":\"url-to-certificate\"}]},\"additionalUnattendContent\":[{\"pass\":\"oobesystem\",\"component\":\"Microsoft-Windows-Shell-Setup\",\"settingName\":\"FirstLogonCommands\",\"content\":\"<XML unattend content>\"}],"
+ "\"enableAutomaticUpdates\":true},"
+ "\"secrets\":[{\"sourceVault\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup1/providers/Microsoft.KeyVault/vaults/myvault1\"},\"vaultCertificates\":[{\"certificateUrl\":\"https://myvault1.vault.azure.net/secrets/SECRETNAME/SECRETVERSION\",\"certificateStore\":\"CERTIFICATESTORENAME\"}]}]},"
+ "\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167\"}]}," + "\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167\"}]},"
+ "\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://groupname2760.blob.core.windows.net/\"}},\"provisioningState\":\"CREATING\"}," + "\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://groupname2760.blob.core.windows.net/\"}},\"provisioningState\":\"CREATING\"},"
+ "\"tags\":{\"foo\":\"bar\"},"
+ "\"plan\":{\"name\":\"deadline-slave-7-2\",\"publisher\":\"thinkboxsoftware\",\"product\":\"deadline7-2\"}}"); + "\"plan\":{\"name\":\"deadline-slave-7-2\",\"publisher\":\"thinkboxsoftware\",\"product\":\"deadline7-2\"}}");
} }
// See https://docs.microsoft.com/en-us/rest/api/compute/virtualmachines/virtualmachines-create-or-update
// for where part of the example json response comes from. Unfortunately examples in the microsoft docs
// are not valid json (e.g. missing commas, illegal quotes). Therefore this example merges the original
// real-world example (presumably taken from the jclouds wire log), and snippets from the microsoft docs.
public void testCreate() throws Exception { public void testCreate() throws Exception {
server.enqueue(jsonResponse("/createvirtualmachineresponse.json")); server.enqueue(jsonResponse("/createvirtualmachineresponse.json"));
@ -145,15 +165,23 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
"PUT", "PUT",
"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute"
+ "/virtualMachines/windowsmachine?validating=false&api-version=2016-04-30-preview", + "/virtualMachines/windowsmachine?validating=false&api-version=2016-04-30-preview",
"{\"location\":\"westus\",\"tags\":{\"foo\":\"bar\"},\"properties\":" "{\"location\":\"westus\",\"properties\":"
+ "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\"," + "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\",\"licenseType\":\"Windows_Server\","
+ "\"availabilitySet\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet\"},"
+ "\"hardwareProfile\":{\"vmSize\":\"Standard_D1\"}," + "\"hardwareProfile\":{\"vmSize\":\"Standard_D1\"},"
+ "\"storageProfile\":{\"imageReference\":{\"publisher\":\"publisher\",\"offer\":\"offer\",\"sku\":\"sku\",\"version\":\"ver\"}," + "\"storageProfile\":{\"imageReference\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute/locations/westus/publishers/MicrosoftWindowsServerEssentials/artifactype/vmimage/offers/OFFER/skus/OFFER/versions/latest\","
+ "\"publisher\":\"publisher\",\"offer\":\"OFFER\",\"sku\":\"sku\",\"version\":\"ver\"},"
+ "\"osDisk\":{\"osType\":\"Windows\",\"name\":\"windowsmachine\"," + "\"osDisk\":{\"osType\":\"Windows\",\"name\":\"windowsmachine\","
+ "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\"},\"dataDisks\":[]}," + "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\","
+ "\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"windowsConfiguration\":{\"provisionVMAgent\":false,\"enableAutomaticUpdates\":true}}," + "\"managedDisk\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk\",\"storageAccountType\":\"Standard_LRS\"}},"
+ "\"dataDisks\":[{\"name\":\"mydatadisk1\",\"diskSizeGB\":\"1\",\"lun\":0,\"vhd\":{\"uri\":\"http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd\"},\"createOption\":\"Empty\",\"caching\":\"Unrecognized\"}]},"
+ "\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"adminPassword\":\"password\",\"customData\":\"\",\"windowsConfiguration\":{\"provisionVMAgent\":false,"
+ "\"winRM\":{\"listeners\":[{\"protocol\":\"https\",\"certificateUrl\":\"url-to-certificate\"}]},\"additionalUnattendContent\":[{\"pass\":\"oobesystem\",\"component\":\"Microsoft-Windows-Shell-Setup\",\"settingName\":\"FirstLogonCommands\",\"content\":\"<XML unattend content>\"}],"
+ "\"enableAutomaticUpdates\":true},"
+ "\"secrets\":[{\"sourceVault\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup1/providers/Microsoft.KeyVault/vaults/myvault1\"},\"vaultCertificates\":[{\"certificateUrl\":\"https://myvault1.vault.azure.net/secrets/SECRETNAME/SECRETVERSION\",\"certificateStore\":\"CERTIFICATESTORENAME\"}]}]},"
+ "\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167\"}]}," + "\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167\"}]},"
+ "\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://groupname2760.blob.core.windows.net/\"}},\"provisioningState\":\"CREATING\"}}"); + "\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://groupname2760.blob.core.windows.net/\"}},\"provisioningState\":\"CREATING\"},"
+ "\"tags\":{\"foo\":\"bar\"}}");
} }
public void testDeleteReturns404() throws Exception { public void testDeleteReturns404() throws Exception {
@ -248,15 +276,31 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
} }
private VirtualMachineProperties getProperties() { private VirtualMachineProperties getProperties() {
String licenseType = "Windows_Server";
IdReference availabilitySet = IdReference.create("/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet");
HardwareProfile hwProf = HardwareProfile.create("Standard_D1"); HardwareProfile hwProf = HardwareProfile.create("Standard_D1");
ImageReference imgRef = ImageReference.builder().publisher("publisher").offer("offer").sku("sku").version("ver").build(); ImageReference imgRef = ImageReference.builder().publisher("publisher").offer("OFFER").sku("sku").version("ver")
.customImageId("/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute/locations/westus/publishers/MicrosoftWindowsServerEssentials/artifactype/vmimage/offers/OFFER/skus/OFFER/versions/latest")
.build();
VHD vhd = VHD.create("https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"); VHD vhd = VHD.create("https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd");
List<DataDisk> dataDisks = new ArrayList<DataDisk>(); List<DataDisk> dataDisks = ImmutableList.of(
OSDisk osDisk = OSDisk.create("Windows", "windowsmachine", vhd, "ReadWrite", "FromImage", null, null, null); DataDisk.create("mydatadisk1", "1", 0, VHD.create("http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"),
null, "Empty", null, null, null));
ManagedDiskParameters managedDiskParameters = ManagedDiskParameters.create("/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
"Standard_LRS");
OSDisk osDisk = OSDisk.create("Windows", "windowsmachine", vhd, "ReadWrite", "FromImage", null, managedDiskParameters, null);
StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk, dataDisks); StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk, dataDisks);
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true, LinuxConfiguration linuxConfig = null;
null); OSProfile.WindowsConfiguration.WinRM winrm = OSProfile.WindowsConfiguration.WinRM.create(
OSProfile osProfile = OSProfile.create("windowsmachine", "azureuser", null, null, null, windowsConfig); ImmutableList.of(
OSProfile.WindowsConfiguration.WinRM.ProtocolListener.create(Protocol.HTTPS, "url-to-certificate")));
List<AdditionalUnattendContent> additionalUnattendContent = ImmutableList.of(
AdditionalUnattendContent.create("oobesystem", "Microsoft-Windows-Shell-Setup", "FirstLogonCommands", "<XML unattend content>"));
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, winrm, additionalUnattendContent, true);
List<Secrets> secrets = ImmutableList.of(
Secrets.create(SourceVault.create("/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup1/providers/Microsoft.KeyVault/vaults/myvault1"),
ImmutableList.of(VaultCertificate.create("https://myvault1.vault.azure.net/secrets/SECRETNAME/SECRETVERSION", "CERTIFICATESTORENAME"))));
OSProfile osProfile = OSProfile.create("windowsmachine", "azureuser", "password", "", linuxConfig, windowsConfig, secrets);
NetworkInterface networkInterface = NetworkInterface.create("/subscriptions/SUBSCRIPTIONID" NetworkInterface networkInterface = NetworkInterface.create("/subscriptions/SUBSCRIPTIONID"
+ "/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/" + "windowsmachine167", null); + "/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/" + "windowsmachine167", null);
List<NetworkInterface> networkInterfaces = new ArrayList<NetworkInterface>(); List<NetworkInterface> networkInterfaces = new ArrayList<NetworkInterface>();
@ -266,7 +310,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
"https://groupname2760.blob.core.windows.net/"); "https://groupname2760.blob.core.windows.net/");
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics); DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
VirtualMachineProperties properties = VirtualMachineProperties.create("27ee085b-d707-xxxx-yyyy-2370e2eb1cc1", VirtualMachineProperties properties = VirtualMachineProperties.create("27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
null, null, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile, licenseType, availabilitySet, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile,
VirtualMachineProperties.ProvisioningState.CREATING); VirtualMachineProperties.ProvisioningState.CREATING);
return properties; return properties;
} }

View File

@ -41,6 +41,7 @@ import org.jclouds.azurecompute.arm.domain.ResourceGroup;
import org.jclouds.azurecompute.arm.domain.Subnet; import org.jclouds.azurecompute.arm.domain.Subnet;
import org.jclouds.azurecompute.arm.domain.VirtualNetwork; import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
import org.testng.annotations.AfterClass; import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.base.Supplier; import com.google.common.base.Supplier;
@ -66,6 +67,10 @@ public class BaseAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi
protected String resourceGroupName; protected String resourceGroupName;
protected String vaultResourceGroup;
protected String vaultName;
protected String vaultCertificateUrl;
public BaseAzureComputeApiLiveTest() { public BaseAzureComputeApiLiveTest() {
provider = "azurecompute-arm"; provider = "azurecompute-arm";
} }
@ -82,6 +87,20 @@ public class BaseAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi
} }
} }
@BeforeClass
@Override
public void setup() {
super.setup();
// Providing system properties for specifying the required Azure KeyVault configurations for Live tests
// They have to be externally provided, because azurecompute-arm doesn't support creating KeyVaults yet
//
// TODO Replace the used configurations once full KeyVault implementation is added to azurecompute-arm
vaultResourceGroup = System.getProperty("test.azurecompute-arm.vault.resource.group");
vaultName = System.getProperty("test.azurecompute-arm.vault.name");
vaultCertificateUrl = System.getProperty("test.azurecompute-arm.vault.certificate.url");
}
@Override protected AzureComputeApi create(Properties props, Iterable<Module> modules) { @Override protected AzureComputeApi create(Properties props, Iterable<Module> modules) {
Injector injector = newBuilder().modules(modules).overrides(props).buildInjector(); Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
imageAvailablePredicate = injector.getInstance(Key.get(new TypeLiteral<Predicate<URI>>() { imageAvailablePredicate = injector.getInstance(Key.get(new TypeLiteral<Predicate<URI>>() {

View File

@ -1,37 +1,92 @@
{ {
"properties": { "properties": {
"vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1", "vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
"licenseType": "Windows_Server",
"availabilitySet": {
"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet"
},
"hardwareProfile": { "hardwareProfile": {
"vmSize": "Standard_D1" "vmSize": "Standard_D1"
}, },
"storageProfile": { "storageProfile": {
"imageReference": { "imageReference": {
"publisher": "publisher", "publisher": "publisher",
"offer": "offer", "offer": "OFFER",
"sku": "sku", "sku": "sku",
"version": "ver" "version": "ver",
"id": "/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute/locations/westus/publishers/MicrosoftWindowsServerEssentials/artifactype/vmimage/offers/OFFER/skus/OFFER/versions/latest"
}, },
"osDisk": { "osDisk": {
"osType": "Windows", "osType": "Windows",
"name": "windowsmachine", "name": "windowsmachine",
"createOption": "FromImage", "createOption": "FromImage",
"managedDisk": {
"id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
"storageAccountType": "Standard_LRS"
},
"vhd": { "vhd": {
"uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd" "uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"
}, },
"caching": "ReadWrite" "caching": "ReadWrite"
}, },
"dataDisks": [] "dataDisks":[
{
"name":"mydatadisk1",
"diskSizeGB":"1",
"lun": 0,
"vhd": {
"uri" : "http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"
},
"createOption":"Empty"
}
]
}, },
"osProfile": { "osProfile": {
"computerName": "windowsmachine", "computerName": "windowsmachine",
"adminUsername": "azureuser", "adminUsername": "azureuser",
"adminPassword": "password",
"customData": "",
"windowsConfiguration": { "windowsConfiguration": {
"provisionVMAgent": false, "provisionVMAgent": false,
"enableAutomaticUpdates": true "enableAutomaticUpdates": true,
"winRM": {
"listeners": [
{
"protocol": "https",
"certificateUrl": "url-to-certificate"
}
]
}, },
"secrets": [] "additionalUnattendContent": [
{
"pass":"oobesystem",
"component":"Microsoft-Windows-Shell-Setup",
"settingName":"FirstLogonCommands",
"content":"<XML unattend content>"
}
]
},
"secrets":[
{
"sourceVault": {
"id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup1/providers/Microsoft.KeyVault/vaults/myvault1"
},
"vaultCertificates": [
{
"certificateUrl": "https://myvault1.vault.azure.net/secrets/SECRETNAME/SECRETVERSION",
"certificateStore": "CERTIFICATESTORENAME"
}
]
}
]
},
"networkProfile": {
"networkInterfaces":[
{
"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167"
}
]
}, },
"networkProfile": {"networkInterfaces":[{"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167"}]},
"diagnosticsProfile": { "diagnosticsProfile": {
"bootDiagnostics": { "bootDiagnostics": {
"enabled": true, "enabled": true,

View File

@ -1,37 +1,90 @@
{ {
"properties": { "properties": {
"vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1", "vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
"licenseType": "Windows_Server",
"availabilitySet":{
"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet"
},
"hardwareProfile": { "hardwareProfile": {
"vmSize": "Standard_D1" "vmSize": "Standard_D1"
}, },
"storageProfile": { "storageProfile": {
"imageReference": { "imageReference": {
"publisher": "publisher", "publisher": "publisher",
"offer": "offer", "offer": "OFFER",
"sku": "sku", "sku": "sku",
"version": "ver" "version": "ver",
"id": "/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute/locations/westus/publishers/MicrosoftWindowsServerEssentials/artifactype/vmimage/offers/OFFER/skus/OFFER/versions/latest"
}, },
"osDisk": { "osDisk": {
"osType": "Windows", "osType": "Windows",
"name": "windowsmachine", "name": "windowsmachine",
"createOption": "FromImage", "createOption": "FromImage",
"managedDisk": {
"id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
"storageAccountType": "Standard_LRS"
},
"vhd": { "vhd": {
"uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd" "uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"
}, },
"caching": "ReadWrite" "caching": "ReadWrite"
}, },
"dataDisks": [] "dataDisks":[
{
"name":"mydatadisk1",
"diskSizeGB":"1",
"lun": 0,
"vhd": {
"uri" : "http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"
},
"createOption":"Empty"
}
]
}, },
"osProfile": { "osProfile": {
"computerName": "windowsmachine", "computerName": "windowsmachine",
"adminUsername": "azureuser", "adminUsername": "azureuser",
"adminPassword":"password",
"customData":"",
"windowsConfiguration": { "windowsConfiguration": {
"provisionVMAgent": false, "provisionVMAgent": false,
"enableAutomaticUpdates": true "enableAutomaticUpdates": true,
"winRM": {
"listeners":[{
"protocol": "https",
"certificateUrl": "url-to-certificate"
}]
}, },
"secrets": [] "additionalUnattendContent":[
{
"pass":"oobesystem",
"component":"Microsoft-Windows-Shell-Setup",
"settingName":"FirstLogonCommands",
"content":"<XML unattend content>"
}
]
},
"secrets":[
{
"sourceVault": {
"id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup1/providers/Microsoft.KeyVault/vaults/myvault1"
},
"vaultCertificates": [
{
"certificateUrl": "https://myvault1.vault.azure.net/secrets/SECRETNAME/SECRETVERSION",
"certificateStore": "CERTIFICATESTORENAME"
}
]
}
]
},
"networkProfile": {
"networkInterfaces":[
{
"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167"
}
]
}, },
"networkProfile": {"networkInterfaces":[{"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167"}]},
"diagnosticsProfile": { "diagnosticsProfile": {
"bootDiagnostics": { "bootDiagnostics": {
"enabled": true, "enabled": true,

View File

@ -3,35 +3,82 @@
{ {
"properties": { "properties": {
"vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1", "vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
"licenseType": "Windows_Server",
"availabilitySet":{
"id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet"
},
"hardwareProfile": { "hardwareProfile": {
"vmSize": "Standard_D1" "vmSize": "Standard_D1"
}, },
"storageProfile": { "storageProfile": {
"imageReference": { "imageReference": {
"publisher": "publisher", "publisher": "publisher",
"offer": "offer", "offer": "OFFER",
"sku": "sku", "sku": "sku",
"version": "ver" "version": "ver",
"id": "/subscriptions/SUBSCRIPTIONID/providers/Microsoft.Compute/locations/westus/publishers/MicrosoftWindowsServerEssentials/artifactype/vmimage/offers/OFFER/skus/OFFER/versions/latest"
}, },
"osDisk": { "osDisk": {
"osType": "Windows", "osType": "Windows",
"name": "windowsmachine", "name": "windowsmachine",
"createOption": "FromImage", "createOption": "FromImage",
"managedDisk": {
"id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
"storageAccountType": "Standard_LRS"
},
"vhd": { "vhd": {
"uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd" "uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"
}, },
"caching": "ReadWrite" "caching": "ReadWrite"
}, },
"dataDisks": [] "dataDisks":[
{
"name":"mydatadisk1",
"diskSizeGB":"1",
"lun": 0,
"vhd": {
"uri" : "http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"
},
"createOption":"Empty"
}
]
}, },
"osProfile": { "osProfile": {
"computerName": "windowsmachine", "computerName": "windowsmachine",
"adminUsername": "azureuser", "adminUsername": "azureuser",
"adminPassword":"password",
"customData":"",
"windowsConfiguration": { "windowsConfiguration": {
"provisionVMAgent": false, "provisionVMAgent": false,
"enableAutomaticUpdates": true "enableAutomaticUpdates": true,
"winRM": {
"listeners":[{
"protocol": "https",
"certificateUrl": "url-to-certificate"
}]
}, },
"secrets": [] "additionalUnattendContent":[
{
"pass":"oobesystem",
"component":"Microsoft-Windows-Shell-Setup",
"settingName":"FirstLogonCommands",
"content":"<XML unattend content>"
}
]
},
"secrets":[
{
"sourceVault": {
"id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myresourcegroup1/providers/Microsoft.KeyVault/vaults/myvault1"
},
"vaultCertificates": [
{
"certificateUrl": "https://myvault1.vault.azure.net/secrets/SECRETNAME/SECRETVERSION",
"certificateStore": "CERTIFICATESTORENAME"
}
]
}
]
}, },
"networkProfile": { "networkProfile": {
"networkInterfaces": [ "networkInterfaces": [