You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by sv...@apache.org on 2017/05/25 13:35:03 UTC

jclouds-labs git commit: Adding support for provisioning of Windows VMs with enabled WinRM

Repository: jclouds-labs
Updated Branches:
  refs/heads/master 3bd117ecd -> 6e0cbc915


Adding support for provisioning of Windows VMs with enabled WinRM

- Provisioning using pre-existing KeyVault
- Enabling WinRM with pre-existing certificate


Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/6e0cbc91
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/6e0cbc91
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/6e0cbc91

Branch: refs/heads/master
Commit: 6e0cbc915cfb1e3f0cb9cdafd3b56b948e0e80a8
Parents: 3bd117e
Author: Yavor Yanchev <ya...@yanchev.com>
Authored: Fri May 19 12:41:16 2017 +0300
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Thu May 25 16:34:00 2017 +0300

----------------------------------------------------------------------
 .../arm/compute/AzureComputeServiceAdapter.java | 16 +++-
 .../compute/options/AzureTemplateOptions.java   | 60 +++++++++++++-
 .../azurecompute/arm/domain/OSProfile.java      | 82 ++++++++++++++------
 .../azurecompute/arm/domain/Secrets.java        | 55 +++++++++++++
 .../arm/domain/VaultCertificate.java            | 46 +++++++++++
 .../arm/features/VirtualMachineApiLiveTest.java | 35 +++++++--
 .../arm/features/VirtualMachineApiMockTest.java | 82 +++++++++++++++-----
 .../internal/BaseAzureComputeApiLiveTest.java   | 19 +++++
 .../resources/createvirtualmachineresponse.json | 69 ++++++++++++++--
 .../src/test/resources/virtualmachine.json      | 65 ++++++++++++++--
 .../src/test/resources/virtualmachines.json     | 57 ++++++++++++--
 11 files changed, 513 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
index 02e69fa..ccb748a 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -64,6 +64,8 @@ import org.jclouds.azurecompute.arm.domain.ManagedDiskParameters;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
 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.OSProfile;
 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.VirtualMachine;
 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.OSImageApi;
 import org.jclouds.compute.ComputeServiceAdapter;
@@ -390,6 +390,17 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
          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();
    }
 
@@ -526,5 +537,4 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
    private IdReference getAvailabilitySetIdReference(AvailabilitySet availabilitySet) {
       return availabilitySet != null ? IdReference.create(availabilitySet.id()) : null;
    }
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
index c3140dd..6ba85d1 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
@@ -16,17 +16,19 @@
  */
 package org.jclouds.azurecompute.arm.compute.options;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 import java.util.List;
 
 import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
 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 com.google.common.base.Objects;
 import com.google.common.collect.ImmutableList;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
 /**
  * Azure ARM custom options
  */
@@ -37,6 +39,8 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
    private List<DataDisk> dataDisks = ImmutableList.of();
    private String resourceGroup;
    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
@@ -98,12 +102,36 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
    public AzureTemplateOptions ipOptions(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 String getAvailabilitySetName() { return availabilitySetName; }
    public List<DataDisk> getDataDisks() { return dataDisks; }
    public String getResourceGroup() { return resourceGroup; }
    public List<IpOptions> getIpOptions() { return ipOptions; }
+   public WindowsConfiguration getWindowsConfiguration() { return windowsConfiguration; }
+   public List<Secrets> getSecrets() { return secrets; }
 
    @Override
    public AzureTemplateOptions clone() {
@@ -122,6 +150,8 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
          eTo.dataDisks(dataDisks);
          eTo.resourceGroup(resourceGroup);
          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(availabilitySet, that.availabilitySet) &&
             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
@@ -159,6 +191,10 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
          toString.add("resourceGroup", resourceGroup);
       if (!ipOptions.isEmpty())
          toString.add("ipOptions", ipOptions);
+      if (windowsConfiguration != null)
+          toString.add("windowsConfiguration", windowsConfiguration);
+      if (!secrets.isEmpty())
+          toString.add("secrets", secrets);
       return toString;
    }
 
@@ -219,5 +255,21 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
          AzureTemplateOptions options = new AzureTemplateOptions();
          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);
+      }
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSProfile.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSProfile.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSProfile.java
index 5592b4c..b77dc9e 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSProfile.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSProfile.java
@@ -16,15 +16,14 @@
  */
 package org.jclouds.azurecompute.arm.domain;
 
-import com.google.auto.value.AutoValue;
-import com.google.common.collect.ImmutableList;
+import java.util.List;
 
+import org.jclouds.azurecompute.arm.util.GetEnumValue;
 import org.jclouds.javax.annotation.Nullable;
 import org.jclouds.json.SerializedNames;
 
-import java.util.List;
-import java.util.Map;
-import com.google.common.collect.ImmutableMap;
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
 
 @AutoValue
 public abstract class OSProfile {
@@ -91,15 +90,52 @@ public abstract class OSProfile {
 
       @AutoValue
       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
           */
-         public abstract Map<String, String> listeners();
+         public abstract List<ProtocolListener> listeners();
 
          @SerializedNames({"listeners"})
-         public static WinRM create(final Map<String, String> listeners) {
-            return new AutoValue_OSProfile_WindowsConfiguration_WinRM(listeners == null ? ImmutableMap.<String, String>of() : ImmutableMap.copyOf(listeners));
+         public static WinRM create(final List<ProtocolListener> 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
        */
       @Nullable
-      public abstract AdditionalUnattendContent additionalUnattendContent();
+      public abstract List<AdditionalUnattendContent> additionalUnattendContent();
 
       /**
        * is automatic updates enabled
        */
       public abstract boolean enableAutomaticUpdates();
 
-      /**
-       * list of certificates
-       */
-      @Nullable
-      public abstract List<String> secrets();
-
-      @SerializedNames({"provisionVMAgent", "winRM", "additionalUnattendContent", "enableAutomaticUpdates",
-              "secrets"})
+      @SerializedNames({"provisionVMAgent", "winRM", "additionalUnattendContent", "enableAutomaticUpdates"})
       public static WindowsConfiguration create(final boolean provisionVMAgent, final WinRM winRM,
-                                                final AdditionalUnattendContent additionalUnattendContent,
-                                                final boolean enableAutomaticUpdates, final List<String> secrets) {
+                                                final List<AdditionalUnattendContent> additionalUnattendContent,
+                                                final boolean enableAutomaticUpdates) {
 
          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
    public abstract WindowsConfiguration windowsConfiguration();
 
+   /**
+    * The Secrets configuration of the VM
+    */
+   @Nullable
+   public abstract List<Secrets> secrets();
+
    @SerializedNames({"computerName", "adminUsername", "adminPassword", "customData", "linuxConfiguration",
-           "windowsConfiguration"})
+           "windowsConfiguration", "secrets"})
    public static OSProfile create(final String computerName, final String adminUsername, final String adminPassword,
                                   final String customData, final LinuxConfiguration linuxConfiguration,
-                                  final WindowsConfiguration windowsConfiguration) {
+                                  final WindowsConfiguration windowsConfiguration, final List<Secrets> secrets) {
       return builder()
               .computerName(computerName)
               .adminUsername(adminUsername)
@@ -211,6 +246,7 @@ public abstract class OSProfile {
               .customData(customData)
               .linuxConfiguration(linuxConfiguration)
               .windowsConfiguration(windowsConfiguration)
+              .secrets(secrets)
               .build();
    }
    
@@ -234,6 +270,8 @@ public abstract class OSProfile {
 
       public abstract Builder windowsConfiguration(WindowsConfiguration windowsConfiguration);
 
+      public abstract Builder secrets(List<Secrets> secrets);
+
       public abstract OSProfile build();
    }
 }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Secrets.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Secrets.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Secrets.java
new file mode 100644
index 0000000..5fcf704
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Secrets.java
@@ -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);
+    }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VaultCertificate.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VaultCertificate.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VaultCertificate.java
new file mode 100644
index 0000000..dd35eb6
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VaultCertificate.java
@@ -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);
+    }
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
index f3f6aac..34b289e 100644
--- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java
@@ -42,22 +42,28 @@ import org.jclouds.azurecompute.arm.domain.NetworkProfile;
 import org.jclouds.azurecompute.arm.domain.OSDisk;
 import org.jclouds.azurecompute.arm.domain.OSProfile;
 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.StorageProfile;
 import org.jclouds.azurecompute.arm.domain.StorageService;
 import org.jclouds.azurecompute.arm.domain.Subnet;
 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.VirtualMachineInstance;
 import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.PowerState;
 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.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.internal.BaseAzureComputeApiLiveTest;
 import org.testng.annotations.BeforeClass;
 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.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -79,6 +85,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
       subscriptionid = getSubscriptionId();
 
       createTestResourceGroup();
+
       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
@@ -232,9 +239,9 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
 
    private VirtualMachineProperties getProperties(String nic, String blob) {
 
-      HardwareProfile hwProf = HardwareProfile.create("Standard_D1");
-      ImageReference imgRef = ImageReference.builder().publisher("MicrosoftWindowsServerEssentials")
-              .offer("WindowsServerEssentials").sku("WindowsServerEssentials").version("latest").build();
+      HardwareProfile hwProf = HardwareProfile.create("Standard_D1_v2");
+      ImageReference imgRef = ImageReference.builder().publisher("MicrosoftWindowsServer")
+              .offer("WindowsServer").sku("2008-R2-SP1").version("latest").build();
       
       DataDisk.Builder dataDisk = DataDisk.builder().name("data").diskSizeGB("100").lun(0).createOption(DataDisk.DiskCreateOptionTypes.EMPTY);
       
@@ -250,11 +257,25 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
          osDisk.vhd(VHD.create(blob + "vhds/" + vmName + ".vhd"));
          dataDisk.vhd(VHD.create(blob + "vhds/" + vmName + "data.vhd"));
       }
-      
+
       StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk.build(), ImmutableList.of(dataDisk.build()));
-      OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
-              null);
-      OSProfile osProfile = OSProfile.create(vmName, "azureuser", "RFe3&432dg", null, null, windowsConfig);
+
+      List<Secrets> secrets = null;
+      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.create("/subscriptions/" + subscriptionid +
                       "/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/"

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiMockTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiMockTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiMockTest.java
index 95d967e..83e5ef2 100644
--- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiMockTest.java
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiMockTest.java
@@ -32,15 +32,23 @@ import java.util.List;
 import org.jclouds.azurecompute.arm.domain.DataDisk;
 import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile;
 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.ManagedDiskParameters;
 import org.jclouds.azurecompute.arm.domain.NetworkProfile;
 import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
 import org.jclouds.azurecompute.arm.domain.OSDisk;
 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.Secrets;
 import org.jclouds.azurecompute.arm.domain.Status;
 import org.jclouds.azurecompute.arm.domain.StorageProfile;
 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.VirtualMachineInstance;
 import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
@@ -122,18 +130,30 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
             "PUT",
             "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute"
                   + "/virtualMachines/windowsmachine?validating=false&api-version=2016-04-30-preview",
-            "{\"location\":\"westus\",\"tags\":{\"foo\":\"bar\"},\"properties\":"
-                  + "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\","
+            "{\"location\":\"westus\",\"properties\":"
+                  + "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\",\"licenseType\":\"Windows_Server\","
+                  + "\"availabilitySet\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet\"},"
                   + "\"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\","
-                  + "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\"},\"dataDisks\":[]},"
-                  + "\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"windowsConfiguration\":{\"provisionVMAgent\":false,\"enableAutomaticUpdates\":true}},"
+                  + "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\","
+                  + "\"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\"}]},"
                   + "\"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\"}}");
    }
-   
+
+   // 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 {
       server.enqueue(jsonResponse("/createvirtualmachineresponse.json"));
 
@@ -145,15 +165,23 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
             "PUT",
             "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute"
                   + "/virtualMachines/windowsmachine?validating=false&api-version=2016-04-30-preview",
-            "{\"location\":\"westus\",\"tags\":{\"foo\":\"bar\"},\"properties\":"
-                  + "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\","
+            "{\"location\":\"westus\",\"properties\":"
+                  + "{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\",\"licenseType\":\"Windows_Server\","
+                  + "\"availabilitySet\":{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet\"},"
                   + "\"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\","
-                  + "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\"},\"dataDisks\":[]},"
-                  + "\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"windowsConfiguration\":{\"provisionVMAgent\":false,\"enableAutomaticUpdates\":true}},"
+                  + "\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\","
+                  + "\"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\"}]},"
-                  + "\"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 {
@@ -248,15 +276,31 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
    }
 
    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");
-      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");
-      List<DataDisk> dataDisks = new ArrayList<DataDisk>();
-      OSDisk osDisk = OSDisk.create("Windows", "windowsmachine", vhd, "ReadWrite", "FromImage", null, null, null);
+      List<DataDisk> dataDisks = ImmutableList.of(
+            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);
-      OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
-            null);
-      OSProfile osProfile = OSProfile.create("windowsmachine", "azureuser", null, null, null, windowsConfig);
+      LinuxConfiguration linuxConfig = null;
+      OSProfile.WindowsConfiguration.WinRM winrm = OSProfile.WindowsConfiguration.WinRM.create(
+            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"
             + "/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/" + "windowsmachine167", null);
       List<NetworkInterface> networkInterfaces = new ArrayList<NetworkInterface>();
@@ -266,7 +310,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
             "https://groupname2760.blob.core.windows.net/");
       DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
       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);
       return properties;
    }

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
index 10406b8..90502fe 100644
--- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
+++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/internal/BaseAzureComputeApiLiveTest.java
@@ -41,6 +41,7 @@ import org.jclouds.azurecompute.arm.domain.ResourceGroup;
 import org.jclouds.azurecompute.arm.domain.Subnet;
 import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
 import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
 
 import com.google.common.base.Predicate;
 import com.google.common.base.Supplier;
@@ -66,6 +67,10 @@ public class BaseAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi
    
    protected String resourceGroupName;
    
+   protected String vaultResourceGroup;
+   protected String vaultName;
+   protected String vaultCertificateUrl;
+
    public BaseAzureComputeApiLiveTest() {
       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) {
       Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
       imageAvailablePredicate = injector.getInstance(Key.get(new TypeLiteral<Predicate<URI>>() {

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/test/resources/createvirtualmachineresponse.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/createvirtualmachineresponse.json b/azurecompute-arm/src/test/resources/createvirtualmachineresponse.json
index 2963100..bc8ca2d 100644
--- a/azurecompute-arm/src/test/resources/createvirtualmachineresponse.json
+++ b/azurecompute-arm/src/test/resources/createvirtualmachineresponse.json
@@ -1,37 +1,92 @@
 {
   "properties": {
     "vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
+    "licenseType": "Windows_Server",
+    "availabilitySet": {
+      "id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet"
+    },
     "hardwareProfile": {
       "vmSize": "Standard_D1"
     },
     "storageProfile": {
       "imageReference": {
         "publisher": "publisher",
-        "offer": "offer",
+        "offer": "OFFER",
         "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": {
         "osType": "Windows",
         "name": "windowsmachine",
         "createOption": "FromImage",
+        "managedDisk": {
+          "id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
+          "storageAccountType": "Standard_LRS"
+        },
         "vhd": {
           "uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"
         },
         "caching": "ReadWrite"
       },
-      "dataDisks": []
+      "dataDisks":[
+        {
+          "name":"mydatadisk1",
+          "diskSizeGB":"1",
+          "lun": 0,
+          "vhd": {
+            "uri" : "http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"
+          },
+          "createOption":"Empty"
+        }
+      ]
     },
     "osProfile": {
       "computerName": "windowsmachine",
       "adminUsername": "azureuser",
+      "adminPassword": "password",
+      "customData": "",
       "windowsConfiguration": {
         "provisionVMAgent": false,
-        "enableAutomaticUpdates": true
+        "enableAutomaticUpdates": true,
+        "winRM": {    
+          "listeners": [
+            {    
+              "protocol": "https",    
+              "certificateUrl": "url-to-certificate"    
+            }
+          ]
+        },    
+        "additionalUnattendContent": [
+          {      
+            "pass":"oobesystem",    
+            "component":"Microsoft-Windows-Shell-Setup",    
+            "settingName":"FirstLogonCommands",    
+            "content":"<XML unattend content>"    
+          }
+        ]
       },
-      "secrets": []
+      "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,
@@ -52,4 +107,4 @@
     "publisher": "thinkboxsoftware",
     "product": "deadline7-2"
   }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/test/resources/virtualmachine.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/virtualmachine.json b/azurecompute-arm/src/test/resources/virtualmachine.json
index 874227d..70e7f4a 100644
--- a/azurecompute-arm/src/test/resources/virtualmachine.json
+++ b/azurecompute-arm/src/test/resources/virtualmachine.json
@@ -1,37 +1,90 @@
 {
   "properties": {
     "vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
+    "licenseType": "Windows_Server",    
+    "availabilitySet":{    
+      "id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet"
+    },
     "hardwareProfile": {
       "vmSize": "Standard_D1"
     },
     "storageProfile": {
       "imageReference": {
         "publisher": "publisher",
-        "offer": "offer",
+        "offer": "OFFER",
         "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": {
         "osType": "Windows",
         "name": "windowsmachine",
         "createOption": "FromImage",
+        "managedDisk": {
+          "id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
+          "storageAccountType": "Standard_LRS"
+        },
         "vhd": {
           "uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"
         },
         "caching": "ReadWrite"
       },
-      "dataDisks": []
+      "dataDisks":[
+        {
+          "name":"mydatadisk1",
+          "diskSizeGB":"1",
+          "lun": 0,
+          "vhd": {
+            "uri" : "http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"
+          },
+          "createOption":"Empty"
+        }
+      ]
     },
     "osProfile": {
       "computerName": "windowsmachine",
       "adminUsername": "azureuser",
+      "adminPassword":"password",
+      "customData":"",
       "windowsConfiguration": {
         "provisionVMAgent": false,
-        "enableAutomaticUpdates": true
+        "enableAutomaticUpdates": true,
+        "winRM": {
+           "listeners":[{
+             "protocol": "https",
+             "certificateUrl": "url-to-certificate"
+           }]
+        },
+        "additionalUnattendContent":[
+          {
+            "pass":"oobesystem",    
+            "component":"Microsoft-Windows-Shell-Setup",
+            "settingName":"FirstLogonCommands",
+            "content":"<XML unattend content>"
+          }
+        ]
       },
-      "secrets": []
+      "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,

http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/6e0cbc91/azurecompute-arm/src/test/resources/virtualmachines.json
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/test/resources/virtualmachines.json b/azurecompute-arm/src/test/resources/virtualmachines.json
index cd0e24b..758a109 100644
--- a/azurecompute-arm/src/test/resources/virtualmachines.json
+++ b/azurecompute-arm/src/test/resources/virtualmachines.json
@@ -3,35 +3,82 @@
     {
       "properties": {
         "vmId": "27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
+        "licenseType": "Windows_Server",    
+        "availabilitySet":{    
+          "id":"/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/availabilitySets/myAVSet"
+        },    
         "hardwareProfile": {
           "vmSize": "Standard_D1"
         },
         "storageProfile": {
           "imageReference": {
             "publisher": "publisher",
-            "offer": "offer",
+            "offer": "OFFER",
             "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": {
             "osType": "Windows",
             "name": "windowsmachine",
             "createOption": "FromImage",
+            "managedDisk": {
+              "id": "/subscriptions/SUBSCRIPTIONID/resourceGroups/myResourceGroup/providers/Microsoft.Compute/disks/osDisk",
+              "storageAccountType": "Standard_LRS" 
+            },
             "vhd": {
               "uri": "https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd"
             },
             "caching": "ReadWrite"
           },
-          "dataDisks": []
+          "dataDisks":[
+            {
+              "name":"mydatadisk1",
+              "diskSizeGB":"1",
+              "lun": 0,
+              "vhd": {
+                "uri" : "http://mystorage1.blob.core.windows.net/vhds/mydatadisk1.vhd"
+              },
+              "createOption":"Empty"
+            }
+          ]    
         },
         "osProfile": {
           "computerName": "windowsmachine",
           "adminUsername": "azureuser",
+          "adminPassword":"password",
+          "customData":"",
           "windowsConfiguration": {
             "provisionVMAgent": false,
-            "enableAutomaticUpdates": true
+            "enableAutomaticUpdates": true,
+            "winRM": {
+               "listeners":[{
+                 "protocol": "https",
+                 "certificateUrl": "url-to-certificate"
+               }]
+            },    
+            "additionalUnattendContent":[
+              {
+                "pass":"oobesystem",    
+                "component":"Microsoft-Windows-Shell-Setup",
+                "settingName":"FirstLogonCommands",
+                "content":"<XML unattend content>"
+              }
+            ]
           },
-          "secrets": []
+          "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": [