Skip to content
Permalink
Browse files
Adding support for provisioning of Windows VMs with enabled WinRM
- Provisioning using pre-existing KeyVault
- Enabling WinRM with pre-existing certificate
  • Loading branch information
ygy authored and neykov committed May 25, 2017
1 parent 3bd117e commit 6e0cbc915cfb1e3f0cb9cdafd3b56b948e0e80a8
Showing 11 changed files with 513 additions and 73 deletions.
@@ -64,6 +64,8 @@
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.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 @@ private OSProfile createOsProfile(String computerName, Template template) {
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 @@ private OSDisk createOSDisk(Image image) {
private IdReference getAvailabilitySetIdReference(AvailabilitySet availabilitySet) {
return availabilitySet != null ? IdReference.create(availabilitySet.id()) : null;
}

}
@@ -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 AzureTemplateOptions ipOptions(Iterable<IpOptions> ipOptions) {
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 void copyTo(TemplateOptions to) {
eTo.dataDisks(dataDisks);
eTo.resourceGroup(resourceGroup);
eTo.ipOptions(ipOptions);
eTo.windowsConfiguration(windowsConfiguration);
eTo.secrets(secrets);
}
}

@@ -137,7 +167,9 @@ public boolean equals(Object o) {
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 Objects.ToStringHelper string() {
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 static AzureTemplateOptions ipOptions(Iterable<IpOptions> ipOptions) {
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);
}
}
}
@@ -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 static class WindowsConfiguration {

@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 static AdditionalUnattendContent create(final String pass, final String c
* 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,18 +228,25 @@ public static WindowsConfiguration create(final boolean provisionVMAgent, final
@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)
.adminPassword(adminPassword)
.customData(customData)
.linuxConfiguration(linuxConfiguration)
.windowsConfiguration(windowsConfiguration)
.secrets(secrets)
.build();
}

@@ -234,6 +270,8 @@ public abstract static class Builder {

public abstract Builder windowsConfiguration(WindowsConfiguration windowsConfiguration);

public abstract Builder secrets(List<Secrets> secrets);

public abstract OSProfile build();
}
}
@@ -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);
}
}

0 comments on commit 6e0cbc9

Please sign in to comment.