mirror of https://github.com/apache/jclouds.git
JCLOUDS-1278: Allow to configure virtual machine NICs
This commit is contained in:
parent
ec67fdea32
commit
df30057386
|
@ -99,7 +99,7 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
|||
// Api versions used in each API
|
||||
properties.put(API_VERSION_PREFIX + DeploymentApi.class.getSimpleName(), "2016-02-01");
|
||||
properties.put(API_VERSION_PREFIX + LocationApi.class.getSimpleName(), "2015-11-01");
|
||||
properties.put(API_VERSION_PREFIX + NetworkInterfaceCardApi.class.getSimpleName(), "2015-06-15");
|
||||
properties.put(API_VERSION_PREFIX + NetworkInterfaceCardApi.class.getSimpleName(), "2017-03-01");
|
||||
properties.put(API_VERSION_PREFIX + NetworkSecurityGroupApi.class.getSimpleName(), "2016-03-30");
|
||||
properties.put(API_VERSION_PREFIX + NetworkSecurityRuleApi.class.getSimpleName(), "2016-03-30");
|
||||
properties.put(API_VERSION_PREFIX + OSImageApi.class.getSimpleName(), "2015-06-15");
|
||||
|
@ -107,7 +107,7 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
|||
properties.put(API_VERSION_PREFIX + ResourceGroupApi.class.getSimpleName(), "2015-01-01");
|
||||
properties.put(API_VERSION_PREFIX + ResourceProviderApi.class.getSimpleName(), "2015-01-01");
|
||||
properties.put(API_VERSION_PREFIX + StorageAccountApi.class.getSimpleName(), "2015-06-15");
|
||||
properties.put(API_VERSION_PREFIX + SubnetApi.class.getSimpleName(), "2015-06-15");
|
||||
properties.put(API_VERSION_PREFIX + SubnetApi.class.getSimpleName(), "2017-03-01");
|
||||
properties.put(API_VERSION_PREFIX + VirtualNetworkApi.class.getSimpleName(), "2015-06-15");
|
||||
properties.put(API_VERSION_PREFIX + VMSizeApi.class.getSimpleName(), "2015-06-15");
|
||||
properties.put(API_VERSION_PREFIX + VirtualMachineApi.class.getSimpleName(), "2016-04-30-preview");
|
||||
|
|
|
@ -27,9 +27,14 @@ import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromSl
|
|||
import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.getMarketplacePlanFromImageMetadata;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup;
|
||||
import static org.jclouds.azurecompute.arm.util.VMImages.isCustom;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -44,6 +49,7 @@ import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextMod
|
|||
import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.compute.options.IpOptions;
|
||||
import org.jclouds.azurecompute.arm.compute.strategy.CleanupResources;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
|
||||
import org.jclouds.azurecompute.arm.domain.CreationData;
|
||||
|
@ -62,6 +68,7 @@ import org.jclouds.azurecompute.arm.domain.OSDisk;
|
|||
import org.jclouds.azurecompute.arm.domain.OSProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.Offer;
|
||||
import org.jclouds.azurecompute.arm.domain.Plan;
|
||||
import org.jclouds.azurecompute.arm.domain.Provisionable;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
|
@ -75,13 +82,15 @@ 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.azurecompute.arm.features.PublicIPAddressApi;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
@ -105,6 +114,7 @@ import com.google.common.collect.Lists;
|
|||
public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location> {
|
||||
|
||||
public static final String GROUP_KEY = "jclouds_group";
|
||||
public static final String AUTOGENERATED_IP_KEY = "jclouds-autogenerated";
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
|
@ -116,40 +126,40 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
private final Supplier<Set<String>> regionIds;
|
||||
private final PublicIpAvailablePredicateFactory publicIpAvailable;
|
||||
private final CustomImageToVMImage customImagetoVmImage;
|
||||
private final GroupNamingConvention namingConvention;
|
||||
private Predicate<Supplier<Provisionable>> resourceAvailable;
|
||||
|
||||
@Inject
|
||||
AzureComputeServiceAdapter(final AzureComputeApi api, @Named(IMAGE_PUBLISHERS) String imagePublishers,
|
||||
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
|
||||
PublicIpAvailablePredicateFactory publicIpAvailable,
|
||||
CustomImageToVMImage customImagetoVmImage) {
|
||||
PublicIpAvailablePredicateFactory publicIpAvailable, CustomImageToVMImage customImagetoVmImage,
|
||||
GroupNamingConvention.Factory namingConvention, Predicate<Supplier<Provisionable>> resourceAvailable) {
|
||||
this.api = api;
|
||||
this.imagePublishers = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(imagePublishers);
|
||||
this.cleanupResources = cleanupResources;
|
||||
this.regionIds = regionIds;
|
||||
this.publicIpAvailable = publicIpAvailable;
|
||||
this.customImagetoVmImage = customImagetoVmImage;
|
||||
this.namingConvention = namingConvention.create();
|
||||
this.resourceAvailable = resourceAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(final String group, final String name, final Template template) {
|
||||
// TODO network ids => create one nic in each network
|
||||
|
||||
String locationName = template.getLocation().getId();
|
||||
Image image = template.getImage();
|
||||
String hardwareId = fromSlashEncoded(template.getHardware().getId()).name();
|
||||
// TODO ARM specific options
|
||||
AzureTemplateOptions templateOptions = template.getOptions().as(AzureTemplateOptions.class);
|
||||
String subnetId = templateOptions.getSubnetId();
|
||||
String resourceGroupName = templateOptions.getResourceGroup();
|
||||
|
||||
IdReference availabilitySet = getAvailabilitySetIdReference(templateOptions.getAvailabilitySet());
|
||||
NetworkProfile networkProfile = createNetworkProfile(createNetworkInterfaceCards(name, locationName,
|
||||
templateOptions));
|
||||
StorageProfile storageProfile = createStorageProfile(image, templateOptions.getDataDisks());
|
||||
NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName, resourceGroupName, template.getOptions());
|
||||
HardwareProfile hardwareProfile = HardwareProfile.builder().vmSize(hardwareId).build();
|
||||
OSProfile osProfile = createOsProfile(name, template);
|
||||
NetworkProfile networkProfile = NetworkProfile.builder().networkInterfaces(of(IdReference.create(nic.id()))).build();
|
||||
|
||||
VirtualMachineProperties virtualMachineProperties = VirtualMachineProperties.builder()
|
||||
.licenseType(null) // TODO
|
||||
.availabilitySet(availabilitySet)
|
||||
.hardwareProfile(hardwareProfile)
|
||||
.storageProfile(storageProfile)
|
||||
|
@ -159,11 +169,11 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
|
||||
// Store group apart from the name to be able to identify nodes with
|
||||
// custom names in the configured group
|
||||
template.getOptions().getUserMetadata().put(GROUP_KEY, group);
|
||||
Map<String, String> metadataAndTags = metadataAndTagsAsCommaDelimitedValue(template.getOptions());
|
||||
Plan plan = getMarketplacePlanFromImageMetadata(template.getImage());
|
||||
templateOptions.getUserMetadata().put(GROUP_KEY, group);
|
||||
Map<String, String> metadataAndTags = metadataAndTagsAsCommaDelimitedValue(templateOptions);
|
||||
Plan plan = getMarketplacePlanFromImageMetadata(image);
|
||||
|
||||
VirtualMachine virtualMachine = api.getVirtualMachineApi(resourceGroupName).createOrUpdate(name, template.getLocation().getId(),
|
||||
VirtualMachine virtualMachine = api.getVirtualMachineApi(resourceGroupName).createOrUpdate(name, locationName,
|
||||
virtualMachineProperties, metadataAndTags, plan);
|
||||
|
||||
// Safe to pass null credentials here, as jclouds will default populate
|
||||
|
@ -383,39 +393,113 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, String name, String locationName,
|
||||
String azureGroup, TemplateOptions options) {
|
||||
final PublicIPAddressApi ipApi = api.getPublicIPAddressApi(azureGroup);
|
||||
|
||||
PublicIPAddressProperties properties = PublicIPAddressProperties.builder().publicIPAllocationMethod("Static")
|
||||
.idleTimeoutInMinutes(4).build();
|
||||
|
||||
String publicIpAddressName = "public-address-" + name;
|
||||
PublicIPAddress ip = ipApi.createOrUpdate(publicIpAddressName, locationName, ImmutableMap.of("jclouds", name),
|
||||
properties);
|
||||
|
||||
checkState(publicIpAvailable.create(azureGroup).apply(publicIpAddressName),
|
||||
"Public IP was not provisioned in the configured timeout");
|
||||
|
||||
final NetworkInterfaceCardProperties.Builder networkInterfaceCardProperties = NetworkInterfaceCardProperties
|
||||
.builder()
|
||||
.ipConfigurations(
|
||||
of(IpConfiguration
|
||||
.builder()
|
||||
.name("ipConfig-" + name)
|
||||
.properties(
|
||||
IpConfigurationProperties.builder().privateIPAllocationMethod("Dynamic")
|
||||
.publicIPAddress(IdReference.create(ip.id())).subnet(IdReference.create(subnetId))
|
||||
.build()).build()));
|
||||
|
||||
String securityGroup = getOnlyElement(options.getGroups(), null);
|
||||
if (securityGroup != null) {
|
||||
networkInterfaceCardProperties.networkSecurityGroup(IdReference.create(securityGroup));
|
||||
private List<NetworkInterfaceCard> createNetworkInterfaceCards(final String nodeName, final String location,
|
||||
AzureTemplateOptions options) {
|
||||
// Prefer a sorted list of NICs with the ones with public IPs first, to
|
||||
// make sure the primary NIC is the public one
|
||||
final String securityGroup = getOnlyElement(options.getGroups(), null);
|
||||
return Lists.transform(publicIpsFirst(options.getIpOptions()), new Function<IpOptions, NetworkInterfaceCard>() {
|
||||
@Override
|
||||
public NetworkInterfaceCard apply(IpOptions input) {
|
||||
return createNetworkInterfaceCard(input, nodeName, location, securityGroup);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
String networkInterfaceCardName = "jc-nic-" + name;
|
||||
return api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName,
|
||||
networkInterfaceCardProperties.build(), ImmutableMap.of("jclouds", name));
|
||||
private NetworkInterfaceCard createNetworkInterfaceCard(IpOptions ipConfig, String nodeName, String location,
|
||||
String securityGroup) {
|
||||
String resourceGroup = extractResourceGroup(ipConfig.subnet());
|
||||
String subnetName = extractName(ipConfig.subnet());
|
||||
|
||||
IpConfigurationProperties.Builder ipProperties = IpConfigurationProperties.builder()
|
||||
.subnet(IdReference.create(ipConfig.subnet()))
|
||||
.privateIPAllocationMethod(ipConfig.address().isPresent() ? "Static" : "Dynamic")
|
||||
.privateIPAddress(ipConfig.address().orNull());
|
||||
|
||||
configurePublicIP(ipConfig, ipProperties, resourceGroup, location, nodeName);
|
||||
|
||||
String ipName = namingConvention.uniqueNameForGroup(subnetName);
|
||||
final String nicName = namingConvention.uniqueNameForGroup(subnetName);
|
||||
|
||||
IpConfiguration config = IpConfiguration.builder().name(ipName).properties(ipProperties.build()).build();
|
||||
|
||||
NetworkInterfaceCardProperties.Builder nicProperties = NetworkInterfaceCardProperties.builder().ipConfigurations(
|
||||
ImmutableList.of(config));
|
||||
|
||||
if (securityGroup != null) {
|
||||
nicProperties.networkSecurityGroup(IdReference.create(securityGroup));
|
||||
}
|
||||
|
||||
logger.debug(">> creating nic %s(%s) with security groups (%s)", nicName, config,
|
||||
securityGroup != null ? securityGroup : "");
|
||||
|
||||
final NetworkInterfaceCardApi nicApi = api.getNetworkInterfaceCardApi(resourceGroup);
|
||||
NetworkInterfaceCard nic = nicApi.createOrUpdate(nicName, location, nicProperties.build(),
|
||||
ImmutableMap.of("jclouds", nodeName));
|
||||
|
||||
resourceAvailable.apply(new Supplier<Provisionable>() {
|
||||
@Override
|
||||
public Provisionable get() {
|
||||
NetworkInterfaceCard updated = nicApi.get(nicName);
|
||||
return updated == null ? null : updated.properties();
|
||||
}
|
||||
});
|
||||
|
||||
return nic;
|
||||
}
|
||||
|
||||
private void configurePublicIP(IpOptions ipConfig, IpConfigurationProperties.Builder ipProperties,
|
||||
String resourceGroup, String location, String nodeName) {
|
||||
if (ipConfig.publicIpId() != null) {
|
||||
logger.debug(">> configuring public ip: %s", extractName(ipConfig.publicIpId()));
|
||||
PublicIPAddress publicIp = api.getPublicIPAddressApi(extractResourceGroup(ipConfig.publicIpId())).get(
|
||||
extractName(ipConfig.publicIpId()));
|
||||
ipProperties.publicIPAddress(IdReference.create(publicIp.id()));
|
||||
} else if (ipConfig.allocateNewPublicIp()) {
|
||||
PublicIPAddress publicIp = createPublicIp(resourceGroup, location, nodeName);
|
||||
ipProperties.publicIPAddress(IdReference.create(publicIp.id()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the network profile and configure the first NIC as primary.
|
||||
*/
|
||||
private NetworkProfile createNetworkProfile(List<NetworkInterfaceCard> nics) {
|
||||
List<NetworkInterface> nicAttachments = new ArrayList<NetworkInterface>(nics.size());
|
||||
for (int i = 0; i < nics.size(); i++) {
|
||||
nicAttachments.add(NetworkInterface.create(nics.get(i).id(), NetworkInterfaceProperties.create(i == 0)));
|
||||
}
|
||||
return NetworkProfile.create(nicAttachments);
|
||||
}
|
||||
|
||||
private static List<IpOptions> publicIpsFirst(List<IpOptions> ipOptions) {
|
||||
List<IpOptions> sorted = new ArrayList<IpOptions>(ipOptions);
|
||||
Collections.sort(sorted, new Comparator<IpOptions>() {
|
||||
@Override
|
||||
public int compare(IpOptions o1, IpOptions o2) {
|
||||
return o1.allocateNewPublicIp() == o2.allocateNewPublicIp() ? 0 : o1.allocateNewPublicIp() ? -1 : 1;
|
||||
}
|
||||
});
|
||||
return sorted;
|
||||
}
|
||||
|
||||
private PublicIPAddress createPublicIp(String resourceGroup, String location, String nodeName) {
|
||||
String name = namingConvention.uniqueNameForGroup(nodeName);
|
||||
|
||||
PublicIPAddressProperties properties = PublicIPAddressProperties.builder()
|
||||
.publicIPAllocationMethod("Static")
|
||||
.idleTimeoutInMinutes(4)
|
||||
.build();
|
||||
|
||||
logger.debug(">> allocating new public ip address: %s", name);
|
||||
|
||||
PublicIPAddress ip = api.getPublicIPAddressApi(resourceGroup).createOrUpdate(name, location,
|
||||
ImmutableMap.of("jclouds", nodeName, AUTOGENERATED_IP_KEY, "true"), properties);
|
||||
|
||||
checkState(publicIpAvailable.create(resourceGroup).apply(name),
|
||||
"Public IP was not provisioned in the configured timeout");
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
private StorageProfile createStorageProfile(Image image, List<DataDisk> dataDisks) {
|
||||
|
|
|
@ -23,6 +23,8 @@ import static com.google.common.collect.Iterables.any;
|
|||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
|
@ -36,8 +38,8 @@ import javax.inject.Named;
|
|||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.SecurityGroupAvailablePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName;
|
||||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
|
||||
|
@ -135,12 +137,12 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
|
|||
if (vm == null) {
|
||||
throw new IllegalArgumentException("Node " + nodeId + " was not found");
|
||||
}
|
||||
List<IdReference> networkInterfacesIdReferences = vm.properties().networkProfile().networkInterfaces();
|
||||
List<NetworkInterface> networkInterfaces = vm.properties().networkProfile().networkInterfaces();
|
||||
List<NetworkSecurityGroup> networkGroups = new ArrayList<NetworkSecurityGroup>();
|
||||
|
||||
for (IdReference networkInterfaceCardIdReference : networkInterfacesIdReferences) {
|
||||
String nicName = networkInterfaceCardIdReference.name();
|
||||
String nicResourceGroup = networkInterfaceCardIdReference.resourceGroup();
|
||||
for (NetworkInterface networkInterfaceCardIdReference : networkInterfaces) {
|
||||
String nicName = extractName(networkInterfaceCardIdReference.id());
|
||||
String nicResourceGroup = extractResourceGroup(networkInterfaceCardIdReference.id());
|
||||
NetworkInterfaceCard card = api.getNetworkInterfaceCardApi(nicResourceGroup).get(nicName);
|
||||
if (card != null && card.properties().networkSecurityGroup() != null) {
|
||||
String secGroupName = card.properties().networkSecurityGroup().name();
|
||||
|
@ -172,8 +174,13 @@ public class AzureComputeSecurityGroupExtension implements SecurityGroupExtensio
|
|||
builder.name(name);
|
||||
builder.location(location);
|
||||
|
||||
return securityGroupConverter.apply(api.getNetworkSecurityGroupApi(resourceGroup.name()).createOrUpdate(name,
|
||||
location.getId(), null, NetworkSecurityGroupProperties.builder().build()));
|
||||
NetworkSecurityGroup sg = api.getNetworkSecurityGroupApi(resourceGroup.name()).createOrUpdate(name,
|
||||
location.getId(), null, NetworkSecurityGroupProperties.builder().build());
|
||||
|
||||
checkState(securityGroupAvailable.create(resourceGroup.name()).apply(name),
|
||||
"Security group was not created in the configured timeout");
|
||||
|
||||
return securityGroupConverter.apply(sg);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,6 +22,7 @@ import static com.google.common.collect.Iterables.find;
|
|||
import static org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter.GROUP_KEY;
|
||||
import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromLocationAndName;
|
||||
import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromCommaDelimitedValue;
|
||||
import static org.jclouds.location.predicates.LocationPredicates.idEquals;
|
||||
|
@ -40,6 +41,7 @@ import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToStatus.Sta
|
|||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
|
@ -136,9 +138,9 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
private Iterable<String> getPrivateIpAddresses(List<IdReference> idReferences) {
|
||||
private Iterable<String> getPrivateIpAddresses(List<NetworkInterface> networkInterfaces) {
|
||||
List<String> privateIpAddresses = Lists.newArrayList();
|
||||
for (IdReference networkInterfaceCardIdReference : idReferences) {
|
||||
for (NetworkInterface networkInterfaceCardIdReference : networkInterfaces) {
|
||||
NetworkInterfaceCard networkInterfaceCard = getNetworkInterfaceCard(networkInterfaceCardIdReference);
|
||||
if (networkInterfaceCard != null && networkInterfaceCard.properties() != null
|
||||
&& networkInterfaceCard.properties().ipConfigurations() != null) {
|
||||
|
@ -152,21 +154,21 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
|||
return privateIpAddresses;
|
||||
}
|
||||
|
||||
private NetworkInterfaceCard getNetworkInterfaceCard(IdReference nic) {
|
||||
return api.getNetworkInterfaceCardApi(nic.resourceGroup()).get(nic.name());
|
||||
private NetworkInterfaceCard getNetworkInterfaceCard(NetworkInterface nic) {
|
||||
return api.getNetworkInterfaceCardApi(extractResourceGroup(nic.id())).get(extractName(nic.id()));
|
||||
}
|
||||
|
||||
private Iterable<String> getPublicIpAddresses(List<IdReference> idReferences) {
|
||||
private Iterable<String> getPublicIpAddresses(List<NetworkInterface> networkInterfaces) {
|
||||
List<String> publicIpAddresses = Lists.newArrayList();
|
||||
for (IdReference networkInterfaceCardIdReference : idReferences) {
|
||||
for (NetworkInterface networkInterfaceCardIdReference : networkInterfaces) {
|
||||
NetworkInterfaceCard networkInterfaceCard = getNetworkInterfaceCard(networkInterfaceCardIdReference);
|
||||
if (networkInterfaceCard != null && networkInterfaceCard.properties() != null
|
||||
&& networkInterfaceCard.properties().ipConfigurations() != null) {
|
||||
String resourceGroup = networkInterfaceCardIdReference.resourceGroup();
|
||||
for (IpConfiguration ipConfiguration : networkInterfaceCard.properties().ipConfigurations()) {
|
||||
if (ipConfiguration.properties().publicIPAddress() != null) {
|
||||
IdReference publicIpId = ipConfiguration.properties().publicIPAddress();
|
||||
PublicIPAddress publicIp = api.getPublicIPAddressApi(resourceGroup).get(publicIpId.name());
|
||||
PublicIPAddress publicIp = api.getPublicIPAddressApi(publicIpId.resourceGroup()).get(
|
||||
publicIpId.name());
|
||||
if (publicIp != null && publicIp.properties().ipAddress() != null) {
|
||||
publicIpAddresses.add(publicIp.properties().ipAddress());
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.compute.loaders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.getPortRangesFromList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -28,6 +29,7 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.SecurityGroupAvailablePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndNameAndIngressRules;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
|
||||
|
@ -48,10 +50,12 @@ public class CreateSecurityGroupIfNeeded extends CacheLoader<ResourceGroupAndNam
|
|||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final AzureComputeApi api;
|
||||
private final SecurityGroupAvailablePredicateFactory securityGroupAvailable;
|
||||
|
||||
@Inject
|
||||
CreateSecurityGroupIfNeeded(AzureComputeApi api) {
|
||||
CreateSecurityGroupIfNeeded(AzureComputeApi api, SecurityGroupAvailablePredicateFactory securityRuleAvailable) {
|
||||
this.api = api;
|
||||
this.securityGroupAvailable = securityRuleAvailable;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,6 +91,9 @@ public class CreateSecurityGroupIfNeeded extends CacheLoader<ResourceGroupAndNam
|
|||
NetworkSecurityGroup securityGroup = api.getNetworkSecurityGroupApi(resourceGroup).createOrUpdate(name, location,
|
||||
null, NetworkSecurityGroupProperties.builder().securityRules(rules).build());
|
||||
|
||||
checkState(securityGroupAvailable.create(resourceGroup).apply(name),
|
||||
"Security group was not created in the configured timeout");
|
||||
|
||||
return securityGroup.id();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,28 +32,11 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||
*/
|
||||
public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||
|
||||
private String virtualNetworkName;
|
||||
private String subnetId;
|
||||
private AvailabilitySet availabilitySet;
|
||||
private String availabilitySetName;
|
||||
private List<DataDisk> dataDisks = ImmutableList.of();
|
||||
private String resourceGroup;
|
||||
|
||||
/**
|
||||
* Sets the virtual network name
|
||||
*/
|
||||
public AzureTemplateOptions virtualNetworkName(String virtualNetworkName) {
|
||||
this.virtualNetworkName = virtualNetworkName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subnet name
|
||||
*/
|
||||
public AzureTemplateOptions subnetId(String subnetId) {
|
||||
this.subnetId = subnetId;
|
||||
return this;
|
||||
}
|
||||
private List<IpOptions> ipOptions = ImmutableList.of();
|
||||
|
||||
/**
|
||||
* Sets the availability set where the nodes will be configured. If it does
|
||||
|
@ -92,12 +75,35 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
|||
return dataDisks(ImmutableList.copyOf(checkNotNull(dataDisks, "dataDisks")));
|
||||
}
|
||||
|
||||
public String getVirtualNetworkName() { return virtualNetworkName; }
|
||||
public String getSubnetId() { return subnetId; }
|
||||
/**
|
||||
* Configure the NICs that will be attached to the created nodes.
|
||||
* <p>
|
||||
* Note that the number of NICs that can be attached depends on the size of
|
||||
* the virtual machine, and that the guest operating system needs to be
|
||||
* prepared to set up all the configured interfaces.
|
||||
* <p>
|
||||
* Depending on the image being used, a cloud-init or bootstrap script might
|
||||
* be needed to make the interface setup.
|
||||
*/
|
||||
public AzureTemplateOptions ipOptions(Iterable<IpOptions> ipOptions) {
|
||||
for (IpOptions ipOption : checkNotNull(ipOptions, "ipOptions"))
|
||||
checkNotNull(ipOption, "all ipOptions must be non-empty");
|
||||
this.ipOptions = ImmutableList.copyOf(ipOptions);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see {@link AzureTemplateOptions#ipOptions(Iterable)
|
||||
*/
|
||||
public AzureTemplateOptions ipOptions(IpOptions... ipOptions) {
|
||||
return ipOptions(ImmutableList.copyOf(checkNotNull(ipOptions, "ipOptions")));
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
@Override
|
||||
public AzureTemplateOptions clone() {
|
||||
|
@ -111,12 +117,11 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
|||
super.copyTo(to);
|
||||
if (to instanceof AzureTemplateOptions) {
|
||||
AzureTemplateOptions eTo = AzureTemplateOptions.class.cast(to);
|
||||
eTo.virtualNetworkName(virtualNetworkName);
|
||||
eTo.subnetId(subnetId);
|
||||
eTo.availabilitySet(availabilitySet);
|
||||
eTo.availabilitySet(availabilitySetName);
|
||||
eTo.dataDisks(dataDisks);
|
||||
eTo.resourceGroup(resourceGroup);
|
||||
eTo.ipOptions(ipOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,27 +133,22 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
|||
|
||||
AzureTemplateOptions that = (AzureTemplateOptions) o;
|
||||
|
||||
return Objects.equal(virtualNetworkName, that.virtualNetworkName) &&
|
||||
Objects.equal(subnetId, that.subnetId) &&
|
||||
return Objects.equal(availabilitySetName, that.availabilitySetName) &&
|
||||
Objects.equal(resourceGroup, that.resourceGroup) &&
|
||||
Objects.equal(availabilitySet, that.availabilitySet) &&
|
||||
Objects.equal(availabilitySetName, that.availabilitySetName) &&
|
||||
Objects.equal(dataDisks, that.dataDisks) &&
|
||||
Objects.equal(resourceGroup, that.resourceGroup);
|
||||
Objects.equal(ipOptions, that.ipOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(virtualNetworkName, subnetId, availabilitySet, availabilitySetName, dataDisks,
|
||||
resourceGroup);
|
||||
return Objects.hashCode(availabilitySet, availabilitySetName, dataDisks,
|
||||
resourceGroup, ipOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Objects.ToStringHelper string() {
|
||||
Objects.ToStringHelper toString = super.string();
|
||||
if (virtualNetworkName != null)
|
||||
toString.add("virtualNetworkName", virtualNetworkName);
|
||||
if (subnetId != null)
|
||||
toString.add("subnetId", subnetId);
|
||||
if (availabilitySet != null)
|
||||
toString.add("availabilitySet", availabilitySet);
|
||||
if (availabilitySetName != null)
|
||||
|
@ -157,27 +157,13 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
|||
toString.add("dataDisks", dataDisks);
|
||||
if (resourceGroup != null)
|
||||
toString.add("resourceGroup", resourceGroup);
|
||||
if (!ipOptions.isEmpty())
|
||||
toString.add("ipOptions", ipOptions);
|
||||
return toString;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see AzureTemplateOptions#virtualNetworkName(String)
|
||||
*/
|
||||
public static AzureTemplateOptions virtualNetworkName(String virtualNetworkName) {
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
return options.virtualNetworkName(virtualNetworkName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AzureTemplateOptions#subnetId(String)
|
||||
*/
|
||||
public static AzureTemplateOptions subnetId(String subnetId) {
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
return options.subnetId(subnetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AzureTemplateOptions#availabilitySet(AvailabilitySet)
|
||||
*/
|
||||
|
@ -217,5 +203,21 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
|||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
return options.resourceGroup(resourceGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AzureTemplateOptions#ipOptions(IpOptions...)
|
||||
*/
|
||||
public static AzureTemplateOptions ipOptions(IpOptions... ipOptions) {
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
return options.ipOptions(ipOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see AzureTemplateOptions#ipOptions(Iterable)
|
||||
*/
|
||||
public static AzureTemplateOptions ipOptions(Iterable<IpOptions> ipOptions) {
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
return options.ipOptions(ipOptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.compute.options;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
/**
|
||||
* Configures the ip addresses to be configured for the created nodes.
|
||||
*/
|
||||
@AutoValue
|
||||
public abstract class IpOptions {
|
||||
|
||||
/**
|
||||
* The subnet where the NIC will be attached.
|
||||
*/
|
||||
public abstract String subnet();
|
||||
|
||||
/**
|
||||
* The IP address to be configured, in case of static allocation, or absent
|
||||
* for dynamic assignment.
|
||||
*/
|
||||
public abstract Optional<String> address();
|
||||
|
||||
/**
|
||||
* Flag to indicate if a public ip address should be allocated and bound to
|
||||
* this NIC.
|
||||
*/
|
||||
public abstract boolean allocateNewPublicIp();
|
||||
|
||||
/**
|
||||
* ID of the public IP to associate with the NIC.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String publicIpId();
|
||||
|
||||
IpOptions() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
return new AutoValue_IpOptions.Builder().address((String) null).allocateNewPublicIp(false);
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder subnet(String subnet);
|
||||
public abstract Builder allocateNewPublicIp(boolean allocatePublicIp);
|
||||
public abstract Builder publicIpId(String publicIpId);
|
||||
|
||||
abstract Builder address(Optional<String> address);
|
||||
public Builder address(String address) {
|
||||
return address(Optional.fromNullable(address));
|
||||
}
|
||||
|
||||
public abstract IpOptions build();
|
||||
}
|
||||
}
|
|
@ -21,7 +21,10 @@ import static com.google.common.base.Predicates.notNull;
|
|||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Maps.filterValues;
|
||||
import static org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter.AUTOGENERATED_IP_KEY;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.HashMap;
|
||||
|
@ -42,8 +45,10 @@ import org.jclouds.azurecompute.arm.domain.IdReference;
|
|||
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||
import org.jclouds.azurecompute.arm.domain.ManagedDiskParameters;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.OSDisk;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
|
@ -98,10 +103,10 @@ public class CleanupResources {
|
|||
|
||||
public boolean cleanupVirtualMachineNICs(VirtualMachine virtualMachine) {
|
||||
boolean deleted = true;
|
||||
for (IdReference nicRef : virtualMachine.properties().networkProfile().networkInterfaces()) {
|
||||
String nicResourceGroup = nicRef.resourceGroup();
|
||||
String nicName = nicRef.name();
|
||||
NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(nicRef.resourceGroup()).get(nicName);
|
||||
for (NetworkInterface nicRef : virtualMachine.properties().networkProfile().networkInterfaces()) {
|
||||
String nicResourceGroup = extractResourceGroup(nicRef.id());
|
||||
String nicName = extractName(nicRef.id());
|
||||
NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(nicResourceGroup).get(nicName);
|
||||
|
||||
Iterable<IdReference> publicIps = getPublicIps(nic);
|
||||
|
||||
|
@ -113,10 +118,13 @@ public class CleanupResources {
|
|||
String publicIpResourceGroup = publicIp.resourceGroup();
|
||||
String publicIpName = publicIp.name();
|
||||
|
||||
logger.debug(">> deleting public ip nic %s...", publicIpName);
|
||||
PublicIPAddress ip = api.getPublicIPAddressApi(publicIpResourceGroup).get(publicIpName);
|
||||
if (ip.tags() != null && Boolean.parseBoolean(ip.tags().get(AUTOGENERATED_IP_KEY))) {
|
||||
logger.debug(">> deleting public ip %s...", publicIpName);
|
||||
deleted &= api.getPublicIPAddressApi(publicIpResourceGroup).delete(publicIpName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
package org.jclouds.azurecompute.arm.compute.strategy;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup;
|
||||
import static org.jclouds.azurecompute.arm.domain.Subnet.extractVirtualNetwork;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
@ -37,13 +40,15 @@ import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName;
|
|||
import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndNameAndIngressRules;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.TemplateToAvailabilitySet;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.compute.options.IpOptions;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
||||
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
||||
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
|
||||
import org.jclouds.azurecompute.arm.domain.Subnet.SubnetProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork.AddressSpace;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork.VirtualNetworkProperties;
|
||||
import org.jclouds.compute.config.CustomizationResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
|
@ -56,8 +61,9 @@ import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThen
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
@ -89,8 +95,7 @@ public class CreateResourcesThenCreateNodes extends CreateNodesWithGroupEncodedI
|
|||
TemplateToAvailabilitySet templateToAvailabilitySet) {
|
||||
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
|
||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||
this.api = checkNotNull(api, "api cannot be null");
|
||||
checkNotNull(userExecutor, "userExecutor cannot be null");
|
||||
this.api = api;
|
||||
this.securityGroupMap = securityGroupMap;
|
||||
this.defaultVnetAddressPrefix = defaultVnetAddressPrefix;
|
||||
this.defaultSubnetAddressPrefix = defaultSubnetAddressPrefix;
|
||||
|
@ -112,42 +117,38 @@ public class CreateResourcesThenCreateNodes extends CreateNodesWithGroupEncodedI
|
|||
+ "Authentication will delegate to the ssh-agent");
|
||||
}
|
||||
|
||||
// This sill create the resource group if it does not exist
|
||||
String location = template.getLocation().getId();
|
||||
|
||||
createResourceGroupIfNeeded(group, location, options);
|
||||
getOrCreateVirtualNetworkWithSubnet(location, options);
|
||||
|
||||
normalizeNetworkOptions(options);
|
||||
createDefaultNetworkIfNeeded(group, location, options);
|
||||
|
||||
configureSecurityGroupForOptions(group, template.getLocation(), options);
|
||||
configureAvailabilitySetForTemplate(template);
|
||||
|
||||
return super.execute(group, count, template, goodNodes, badNodes, customizationResponses);
|
||||
}
|
||||
|
||||
protected synchronized void getOrCreateVirtualNetworkWithSubnet(final String location, AzureTemplateOptions options) {
|
||||
String virtualNetworkName = Optional.fromNullable(options.getVirtualNetworkName()).or(
|
||||
options.getResourceGroup() + "virtualnetwork");
|
||||
String subnetName = options.getResourceGroup() + "subnet";
|
||||
protected synchronized void createDefaultNetworkIfNeeded(String group, String location, AzureTemplateOptions options) {
|
||||
if (options.getIpOptions().isEmpty()) {
|
||||
String name = namingConvention.create().sharedNameForGroup(group);
|
||||
|
||||
// Subnets belong to a virtual network so that needs to be created first
|
||||
VirtualNetworkApi vnApi = api.getVirtualNetworkApi(options.getResourceGroup());
|
||||
VirtualNetwork vn = vnApi.get(virtualNetworkName);
|
||||
Subnet subnet = Subnet.builder().name(name)
|
||||
.properties(SubnetProperties.builder().addressPrefix(defaultSubnetAddressPrefix).build()).build();
|
||||
|
||||
if (vn == null) {
|
||||
Subnet subnet = Subnet.create(subnetName, null, null,
|
||||
Subnet.SubnetProperties.builder().addressPrefix(defaultSubnetAddressPrefix).build());
|
||||
|
||||
VirtualNetwork.VirtualNetworkProperties virtualNetworkProperties = VirtualNetwork.VirtualNetworkProperties
|
||||
.builder().addressSpace(VirtualNetwork.AddressSpace.create(Arrays.asList(defaultVnetAddressPrefix)))
|
||||
VirtualNetworkProperties properties = VirtualNetworkProperties.builder()
|
||||
.addressSpace(AddressSpace.create(Arrays.asList(defaultVnetAddressPrefix)))
|
||||
.subnets(Arrays.asList(subnet)).build();
|
||||
|
||||
vn = vnApi.createOrUpdate(virtualNetworkName, location, virtualNetworkProperties);
|
||||
logger.debug(">> network options have not been configured. Creating network %s(%s) and subnet %s(%s)", name,
|
||||
defaultVnetAddressPrefix, name, defaultSubnetAddressPrefix);
|
||||
|
||||
api.getVirtualNetworkApi(options.getResourceGroup()).createOrUpdate(name, location, properties);
|
||||
Subnet createdSubnet = api.getSubnetApi(options.getResourceGroup(), name).get(name);
|
||||
|
||||
options.ipOptions(IpOptions.builder().subnet(createdSubnet.id()).allocateNewPublicIp(true).build());
|
||||
}
|
||||
|
||||
SubnetApi subnetApi = api.getSubnetApi(options.getResourceGroup(), virtualNetworkName);
|
||||
Subnet subnet = subnetApi.get(subnetName);
|
||||
|
||||
options.virtualNetworkName(virtualNetworkName);
|
||||
options.subnetId(subnet.id());
|
||||
}
|
||||
|
||||
private static boolean hasRunScriptWithKeyAuthAndNoPrivateKey(Template template) {
|
||||
|
@ -196,4 +197,45 @@ public class CreateResourcesThenCreateNodes extends CreateNodesWithGroupEncodedI
|
|||
ImmutableMap.of("description", "jclouds default resource group"));
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void normalizeNetworkOptions(AzureTemplateOptions options) {
|
||||
if (!options.getNetworks().isEmpty() && !options.getIpOptions().isEmpty()) {
|
||||
throw new IllegalArgumentException("The options.networks and options.ipOptions are exclusive");
|
||||
}
|
||||
|
||||
if (!options.getNetworks().isEmpty() && options.getIpOptions().isEmpty()) {
|
||||
// The portable interface allows to configure network IDs (subnet IDs),
|
||||
// but we don't know the type of the IP configurations to be applied
|
||||
// when attaching nodes to those networks. We'll assume private IPs
|
||||
// with Dynamic allocation and no public ip address associated.
|
||||
ImmutableList.Builder<IpOptions> ipOptions = ImmutableList.builder();
|
||||
for (String subnetId : options.getNetworks()) {
|
||||
ipOptions.add(IpOptions.builder().subnet(subnetId).build());
|
||||
}
|
||||
options.ipOptions(ipOptions.build());
|
||||
}
|
||||
|
||||
if (!options.getIpOptions().isEmpty()) {
|
||||
// Eagerly validate that all configured subnets exist.
|
||||
for (IpOptions ipConfig : options.getIpOptions()) {
|
||||
if (ipConfig.allocateNewPublicIp() && ipConfig.publicIpId() != null) {
|
||||
throw new IllegalArgumentException("The allocateNewPublicIps and publicIpId are exclusive");
|
||||
}
|
||||
|
||||
String resourceGroup = extractResourceGroup(ipConfig.subnet());
|
||||
String networkName = extractVirtualNetwork(ipConfig.subnet());
|
||||
String subnetName = extractName(ipConfig.subnet());
|
||||
|
||||
Subnet subnet = api.getSubnetApi(resourceGroup, networkName).get(subnetName);
|
||||
checkState(subnet != null, "Configured subnet %s does not exist", ipConfig.subnet());
|
||||
|
||||
if (ipConfig.publicIpId() != null) {
|
||||
PublicIPAddress publicIp = api.getPublicIPAddressApi(extractResourceGroup(ipConfig.publicIpId())).get(
|
||||
extractName(ipConfig.publicIpId()));
|
||||
checkState(publicIp != null, "Configured public ip %s does not exist", ipConfig.publicIpId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,23 +26,16 @@ import java.util.List;
|
|||
@AutoValue
|
||||
public abstract class NetworkInterfaceCardProperties implements Provisionable {
|
||||
|
||||
@Nullable
|
||||
public abstract String provisioningState();
|
||||
|
||||
@Nullable
|
||||
public abstract String resourceGuid();
|
||||
|
||||
@Nullable
|
||||
public abstract Boolean enableIPForwarding();
|
||||
|
||||
@Nullable
|
||||
public abstract List<IpConfiguration> ipConfigurations();
|
||||
|
||||
@Nullable
|
||||
public abstract IdReference networkSecurityGroup();
|
||||
@Nullable public abstract String provisioningState();
|
||||
@Nullable public abstract String resourceGuid();
|
||||
@Nullable public abstract Boolean enableIPForwarding();
|
||||
@Nullable public abstract List<IpConfiguration> ipConfigurations();
|
||||
@Nullable public abstract IdReference networkSecurityGroup();
|
||||
|
||||
@SerializedNames({"provisioningState", "resourceGuid", "enableIPForwarding", "ipConfigurations", "networkSecurityGroup"})
|
||||
public static NetworkInterfaceCardProperties create(final String provisioningState, final String resourceGuid, final Boolean enableIPForwarding, final List<IpConfiguration> ipConfigurations, final IdReference networkSecurityGroup) {
|
||||
public static NetworkInterfaceCardProperties create(final String provisioningState, final String resourceGuid,
|
||||
final Boolean enableIPForwarding, final List<IpConfiguration> ipConfigurations,
|
||||
final IdReference networkSecurityGroup) {
|
||||
NetworkInterfaceCardProperties.Builder builder = NetworkInterfaceCardProperties.builder()
|
||||
.provisioningState(provisioningState)
|
||||
.resourceGuid(resourceGuid)
|
||||
|
@ -53,27 +46,25 @@ public abstract class NetworkInterfaceCardProperties implements Provisionable {
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
NetworkInterfaceCardProperties() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
|
||||
return new AutoValue_NetworkInterfaceCardProperties.Builder();
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder provisioningState(String provisioningState);
|
||||
|
||||
public abstract Builder resourceGuid(String resourceGuid);
|
||||
|
||||
public abstract Builder enableIPForwarding(Boolean enableIPForwarding);
|
||||
|
||||
public abstract Builder ipConfigurations(List<IpConfiguration> ipConfigurations);
|
||||
|
||||
abstract List<IpConfiguration> ipConfigurations();
|
||||
|
||||
public abstract Builder networkSecurityGroup(IdReference networkSecurityGroup);
|
||||
|
||||
abstract List<IpConfiguration> ipConfigurations();
|
||||
abstract NetworkInterfaceCardProperties autoBuild();
|
||||
|
||||
public NetworkInterfaceCardProperties build() {
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.jclouds.azurecompute.arm.domain;
|
|||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.json.SerializedNames;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -26,16 +27,49 @@ import java.util.List;
|
|||
@AutoValue
|
||||
public abstract class NetworkProfile {
|
||||
|
||||
@AutoValue
|
||||
public abstract static class NetworkInterface {
|
||||
public abstract String id();
|
||||
@Nullable public abstract NetworkInterfaceProperties properties();
|
||||
|
||||
@AutoValue
|
||||
public abstract static class NetworkInterfaceProperties {
|
||||
public abstract boolean primary();
|
||||
|
||||
NetworkInterfaceProperties() {
|
||||
|
||||
}
|
||||
|
||||
@SerializedNames({"primary"})
|
||||
public static NetworkInterfaceProperties create(boolean primary) {
|
||||
return new AutoValue_NetworkProfile_NetworkInterface_NetworkInterfaceProperties(primary);
|
||||
}
|
||||
}
|
||||
|
||||
NetworkInterface() {
|
||||
|
||||
}
|
||||
|
||||
@SerializedNames({"id", "properties"})
|
||||
public static NetworkInterface create(String id, NetworkInterfaceProperties properties) {
|
||||
return new AutoValue_NetworkProfile_NetworkInterface(id, properties);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* List of network interfaces
|
||||
*/
|
||||
public abstract List<IdReference> networkInterfaces();
|
||||
public abstract List<NetworkInterface> networkInterfaces();
|
||||
|
||||
@SerializedNames({"networkInterfaces"})
|
||||
public static NetworkProfile create(final List<IdReference> networkInterfaces) {
|
||||
public static NetworkProfile create(final List<NetworkInterface> networkInterfaces) {
|
||||
return builder().networkInterfaces(networkInterfaces).build();
|
||||
}
|
||||
|
||||
NetworkProfile() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
|
@ -44,14 +78,14 @@ public abstract class NetworkProfile {
|
|||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder networkInterfaces(List<IdReference> networkInterfaces);
|
||||
public abstract Builder networkInterfaces(List<NetworkInterface> networkInterfaces);
|
||||
|
||||
abstract List<IdReference> networkInterfaces();
|
||||
abstract List<NetworkInterface> networkInterfaces();
|
||||
|
||||
abstract NetworkProfile autoBuild();
|
||||
|
||||
public NetworkProfile build() {
|
||||
networkInterfaces(networkInterfaces() != null ? ImmutableList.copyOf(networkInterfaces()) : ImmutableList.<IdReference>of());
|
||||
networkInterfaces(networkInterfaces() != null ? ImmutableList.copyOf(networkInterfaces()) : ImmutableList.<NetworkInterface>of());
|
||||
return autoBuild();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,36 +17,55 @@
|
|||
|
||||
package org.jclouds.azurecompute.arm.domain;
|
||||
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.json.SerializedNames;
|
||||
|
||||
import java.util.Map;
|
||||
import com.google.auto.value.AutoValue;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
@AutoValue
|
||||
public abstract class PublicIPAddress {
|
||||
|
||||
public abstract String name();
|
||||
|
||||
public abstract String id();
|
||||
|
||||
public abstract String etag();
|
||||
|
||||
public abstract String location();
|
||||
|
||||
@Nullable
|
||||
public abstract Map<String, String> tags();
|
||||
|
||||
@Nullable public abstract Map<String, String> tags();
|
||||
public abstract PublicIPAddressProperties properties();
|
||||
|
||||
@SerializedNames({ "name", "id", "etag", "location", "tags", "properties" })
|
||||
public static PublicIPAddress create(final String name,
|
||||
final String id,
|
||||
final String etag,
|
||||
final String location,
|
||||
final Map<String, String> tags,
|
||||
final PublicIPAddressProperties properties) {
|
||||
return new AutoValue_PublicIPAddress(name, id, etag, location, tags == null ? null : ImmutableMap.copyOf(tags), properties);
|
||||
public static PublicIPAddress create(String name, String id, String etag, String location, Map<String, String> tags,
|
||||
PublicIPAddressProperties properties) {
|
||||
return builder().name(name).id(id).etag(etag).location(location).tags(tags).properties(properties).build();
|
||||
}
|
||||
|
||||
PublicIPAddress() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
return new AutoValue_PublicIPAddress.Builder();
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder name(String name);
|
||||
public abstract Builder id(String id);
|
||||
public abstract Builder etag(String etag);
|
||||
public abstract Builder location(String location);
|
||||
public abstract Builder tags(Map<String, String> tags);
|
||||
public abstract Builder properties(PublicIPAddressProperties properties);
|
||||
|
||||
abstract Map<String, String> tags();
|
||||
abstract PublicIPAddress autoBuild();
|
||||
|
||||
public PublicIPAddress build() {
|
||||
tags(tags() != null ? ImmutableMap.copyOf(tags()) : null);
|
||||
return autoBuild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ package org.jclouds.azurecompute.arm.domain;
|
|||
import static com.google.common.collect.ImmutableList.copyOf;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
|
@ -29,6 +31,8 @@ import org.jclouds.json.SerializedNames;
|
|||
@AutoValue
|
||||
public abstract class Subnet {
|
||||
|
||||
private static final Pattern NETWORK_PATTERN = Pattern.compile("^.*/virtualNetworks/([^/]+)(/.*)?$");
|
||||
|
||||
@AutoValue
|
||||
public abstract static class IpConfiguration {
|
||||
|
||||
|
@ -38,19 +42,18 @@ public abstract class Subnet {
|
|||
public static IpConfiguration create(final String id) {
|
||||
return new AutoValue_Subnet_IpConfiguration(id);
|
||||
}
|
||||
|
||||
IpConfiguration() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public abstract static class SubnetProperties implements Provisionable {
|
||||
|
||||
@Nullable
|
||||
public abstract String provisioningState();
|
||||
|
||||
@Nullable
|
||||
public abstract String addressPrefix();
|
||||
|
||||
@Nullable
|
||||
public abstract List<IpConfiguration> ipConfigurations();
|
||||
@Nullable public abstract String provisioningState();
|
||||
@Nullable public abstract String addressPrefix();
|
||||
@Nullable public abstract List<IpConfiguration> ipConfigurations();
|
||||
|
||||
@SerializedNames({"provisioningState", "addressPrefix", "ipConfigurations"})
|
||||
public static SubnetProperties create(final String provisioningState, final String addressPrefix, final List<IpConfiguration> ipConfigurations) {
|
||||
|
@ -61,6 +64,10 @@ public abstract class Subnet {
|
|||
.build();
|
||||
}
|
||||
|
||||
SubnetProperties() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
|
@ -70,13 +77,10 @@ public abstract class Subnet {
|
|||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder provisioningState(String provisioningState);
|
||||
|
||||
public abstract Builder addressPrefix(String addressPrefix);
|
||||
|
||||
public abstract Builder ipConfigurations(List<IpConfiguration> ipConfigurations);
|
||||
|
||||
abstract List<IpConfiguration> ipConfigurations();
|
||||
|
||||
abstract SubnetProperties autoBuild();
|
||||
|
||||
public SubnetProperties build() {
|
||||
|
@ -86,23 +90,47 @@ public abstract class Subnet {
|
|||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract String name();
|
||||
@Nullable public abstract String name();
|
||||
@Nullable public abstract String id();
|
||||
@Nullable public abstract String etag();
|
||||
@Nullable public abstract SubnetProperties properties();
|
||||
|
||||
@Nullable
|
||||
public abstract String id();
|
||||
@Nullable public String virtualNetwork() {
|
||||
return extractVirtualNetwork(id());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract String etag();
|
||||
|
||||
@Nullable
|
||||
public abstract SubnetProperties properties();
|
||||
public static String extractVirtualNetwork(String id) {
|
||||
if (id == null)
|
||||
return null;
|
||||
Matcher m = NETWORK_PATTERN.matcher(id);
|
||||
m.matches();
|
||||
return m.group(1);
|
||||
}
|
||||
|
||||
@SerializedNames({"name", "id", "etag", "properties"})
|
||||
public static Subnet create(final String name,
|
||||
final String id,
|
||||
final String etag,
|
||||
final SubnetProperties properties) {
|
||||
return new AutoValue_Subnet(name, id, etag, properties);
|
||||
return builder().name(name).id(id).etag(etag).properties(properties).build();
|
||||
}
|
||||
|
||||
Subnet() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
return new AutoValue_Subnet.Builder();
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder name(String name);
|
||||
public abstract Builder id(String id);
|
||||
public abstract Builder etag(String etag);
|
||||
public abstract Builder properties(SubnetProperties properties);
|
||||
public abstract Subnet build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
|||
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
||||
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
|
@ -60,7 +61,7 @@ public interface PublicIPAddressApi {
|
|||
@PUT
|
||||
PublicIPAddress createOrUpdate(@PathParam("publicipaddressname") String publicipaddressname,
|
||||
@PayloadParam("location") String location,
|
||||
@PayloadParam("tags") Map<String, String> tags,
|
||||
@Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||
@PayloadParam("properties") PublicIPAddressProperties properties);
|
||||
|
||||
@Named("publicipaddress:get")
|
||||
|
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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.compute.strategy;
|
||||
|
||||
import static org.easymock.EasyMock.anyObject;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.compute.options.IpOptions;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
|
||||
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@Test(groups = "unit", testName = "CreateResourcesThenCreateNodesTest")
|
||||
public class CreateResourcesThenCreateNodesTest {
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "The options.networks and options.ipOptions are exclusive")
|
||||
public void testNormalizeNetworkOptionsWithConflictingConfig() {
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
options.ipOptions(IpOptions.builder().subnet(netResource("/virtualNetworks/vn/subnets/foo")).build());
|
||||
options.networks(netResource("/virtualNetworks/vn/subnets/bar"));
|
||||
strategy(null).normalizeNetworkOptions(options);
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "The allocateNewPublicIps and publicIpId are exclusive")
|
||||
public void testNormalizeNetworkOptionsExclusivePublicIps() {
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
options.ipOptions(IpOptions.builder().subnet(netResource("/virtualNetworks/vn/subnets/foo"))
|
||||
.allocateNewPublicIp(true).publicIpId(netResource("/publicIPAddresses/pub")).build());
|
||||
strategy(null).normalizeNetworkOptions(options);
|
||||
}
|
||||
|
||||
public void testPortableNetworkOptions() {
|
||||
AzureComputeApi api = createMock(AzureComputeApi.class);
|
||||
SubnetApi subnetApi = createMock(SubnetApi.class);
|
||||
|
||||
expect(api.getSubnetApi(anyObject(String.class), anyObject(String.class))).andReturn(subnetApi).times(2);
|
||||
expect(subnetApi.get(anyObject(String.class))).andReturn(Subnet.builder().build()).times(2);
|
||||
replay(api, subnetApi);
|
||||
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
options.networks(netResource("/virtualNetworks/vn/subnets/foo"), netResource("/virtualNetworks/vn/subnets/bar"));
|
||||
strategy(api).normalizeNetworkOptions(options);
|
||||
|
||||
assertEquals(options.getIpOptions(), ImmutableList.of(
|
||||
IpOptions.builder().subnet(netResource("/virtualNetworks/vn/subnets/foo")).build(), IpOptions.builder()
|
||||
.subnet(netResource("/virtualNetworks/vn/subnets/bar")).build()));
|
||||
|
||||
// Verify that the code has validated that the subnets exist
|
||||
verify(api, subnetApi);
|
||||
}
|
||||
|
||||
public void testProviderSpecificNetworkOptions() {
|
||||
AzureComputeApi api = createMock(AzureComputeApi.class);
|
||||
SubnetApi subnetApi = createMock(SubnetApi.class);
|
||||
PublicIPAddressApi publicIpApi = createMock(PublicIPAddressApi.class);
|
||||
|
||||
expect(api.getSubnetApi(anyObject(String.class), anyObject(String.class))).andReturn(subnetApi).times(2);
|
||||
expect(api.getPublicIPAddressApi(anyObject(String.class))).andReturn(publicIpApi);
|
||||
expect(subnetApi.get(anyObject(String.class))).andReturn(Subnet.builder().build()).times(2);
|
||||
expect(publicIpApi.get(anyObject(String.class))).andReturn(mockAddress());
|
||||
replay(api, subnetApi, publicIpApi);
|
||||
|
||||
IpOptions publicOpts = IpOptions.builder().subnet(netResource("/virtualNetworks/vn/subnets/foo"))
|
||||
.publicIpId(netResource("/publicIPAddresses/pub")).address("10.0.0.2").build();
|
||||
IpOptions privateOpts = IpOptions.builder().subnet(netResource("/virtualNetworks/vn/subnets/bar")).build();
|
||||
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
options.ipOptions(publicOpts, privateOpts);
|
||||
strategy(api).normalizeNetworkOptions(options);
|
||||
|
||||
assertEquals(options.getIpOptions(), ImmutableList.of(publicOpts, privateOpts));
|
||||
|
||||
// Verify that the code has validated that the subnets exist
|
||||
verify(api, subnetApi, publicIpApi);
|
||||
}
|
||||
|
||||
private static CreateResourcesThenCreateNodes strategy(AzureComputeApi api) {
|
||||
return new CreateResourcesThenCreateNodes(null, null, null, null, null, api, null, null, null, null);
|
||||
}
|
||||
|
||||
private static String netResource(String resource) {
|
||||
return "/subscriptions/subs/resourceGroups/rg/providers/Microsoft.Network" + resource;
|
||||
}
|
||||
|
||||
private static PublicIPAddress mockAddress() {
|
||||
return PublicIPAddress.builder().name("name").id("id").etag("etag").location("location")
|
||||
.properties(PublicIPAddressProperties.builder().publicIPAllocationMethod("Dynamic").build()).build();
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import static org.testng.Assert.assertEquals;
|
|||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = "unit", testName = "IdReferenceTest")
|
||||
public class IdReferenceTest {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = "unit", testName = "SubnetTest")
|
||||
public class SubnetTest {
|
||||
|
||||
@Test
|
||||
public void testExtractVirtualNetwork() {
|
||||
|
||||
assertEquals(Subnet.builder().build().virtualNetwork(), null);
|
||||
assertEquals(
|
||||
Subnet.builder()
|
||||
.id("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks/vn/subnets/subnet")
|
||||
.build().virtualNetwork(), "vn");
|
||||
assertInvalidId("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Network/virtualNetworks");
|
||||
assertInvalidId("virtualNetworks/vn");
|
||||
}
|
||||
|
||||
private static void assertInvalidId(String id) {
|
||||
try {
|
||||
Subnet.builder().id(id).build().virtualNetwork();
|
||||
fail("The given ID " + id + "should not match a valid virtual network");
|
||||
} catch (IllegalStateException ex) {
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,6 +23,7 @@ import static com.google.common.collect.Iterables.transform;
|
|||
import static com.google.common.collect.Lists.newArrayList;
|
||||
import static org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions.Builder.availabilitySet;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.azurecompute.arm.domain.IdReference.extractName;
|
||||
import static org.jclouds.azurecompute.arm.domain.InboundNatRuleProperties.Protocol.Tcp;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
@ -360,7 +361,7 @@ public class LoadBalancerApiLiveTest extends BaseComputeServiceContextLiveTest {
|
|||
VirtualMachine vm = api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).get(
|
||||
resourceGroupAndName.name());
|
||||
|
||||
String nicName = vm.properties().networkProfile().networkInterfaces().get(0).name();
|
||||
String nicName = extractName(vm.properties().networkProfile().networkInterfaces().get(0).id());
|
||||
nicNames.add(nicName);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ public class NetworkInterfaceCardApiMockTest extends BaseAzureComputeApiMockTest
|
|||
|
||||
private final String subscriptionid = "SUBSCRIPTIONID";
|
||||
private final String resourcegroup = "myresourcegroup";
|
||||
private final String apiVersion = "api-version=2015-06-15";
|
||||
private final String apiVersion = "api-version=2017-03-01";
|
||||
private final String location = "northeurope";
|
||||
private final String nicName = "myNic";
|
||||
|
||||
|
@ -65,7 +65,8 @@ public class NetworkInterfaceCardApiMockTest extends BaseAzureComputeApiMockTest
|
|||
|
||||
assertNull(nicApi.get(nicName));
|
||||
|
||||
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourcegroups/myresourcegroup/providers/Microsoft.Network/networkInterfaces/myNic?api-version=2015-06-15");
|
||||
String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/networkInterfaces/%s?%s", subscriptionid, resourcegroup, nicName, apiVersion);
|
||||
assertSent(server, "GET", path);
|
||||
}
|
||||
|
||||
public void listNetworkInterfaceCards() throws InterruptedException {
|
||||
|
|
|
@ -36,7 +36,7 @@ public class SubnetApiMockTest extends BaseAzureComputeApiMockTest {
|
|||
private final String resourcegroup = "myresourcegroup";
|
||||
private final String virtualNetwork = "myvirtualnetwork";
|
||||
private final String subnetName = "mysubnet";
|
||||
private final String apiVersion = "api-version=2015-06-15";
|
||||
private final String apiVersion = "api-version=2017-03-01";
|
||||
|
||||
public void createSubnet() throws InterruptedException {
|
||||
|
||||
|
|
|
@ -51,6 +51,8 @@ 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.functions.ParseJobStatus;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
|
@ -253,12 +255,11 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
|||
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
|
||||
null);
|
||||
OSProfile osProfile = OSProfile.create(vmName, "azureuser", "RFe3&432dg", null, null, windowsConfig);
|
||||
IdReference networkInterface =
|
||||
IdReference.create("/subscriptions/" + subscriptionid +
|
||||
NetworkInterface networkInterface =
|
||||
NetworkInterface.create("/subscriptions/" + subscriptionid +
|
||||
"/resourceGroups/" + resourceGroupName + "/providers/Microsoft.Network/networkInterfaces/"
|
||||
+ nic);
|
||||
List<IdReference> networkInterfaces =
|
||||
new ArrayList<IdReference>();
|
||||
+ nic, NetworkInterfaceProperties.create(true));
|
||||
List<NetworkInterface> networkInterfaces = new ArrayList<NetworkInterface>();
|
||||
networkInterfaces.add(networkInterface);
|
||||
NetworkProfile networkProfile = NetworkProfile.create(networkInterfaces);
|
||||
VirtualMachineProperties properties = VirtualMachineProperties.create(null,
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
*/
|
||||
package org.jclouds.azurecompute.arm.features;
|
||||
|
||||
import static com.google.common.collect.Iterables.isEmpty;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -26,9 +32,9 @@ 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.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.Plan;
|
||||
|
@ -45,12 +51,6 @@ import com.google.common.collect.ImmutableList;
|
|||
import com.google.common.collect.ImmutableMap;
|
||||
import com.squareup.okhttp.mockwebserver.MockResponse;
|
||||
|
||||
import static com.google.common.collect.Iterables.isEmpty;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
@Test(groups = "unit", testName = "VirtualMachineApiMockTest", singleThreaded = true)
|
||||
public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
|
||||
|
@ -257,9 +257,9 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
|||
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
|
||||
null);
|
||||
OSProfile osProfile = OSProfile.create("windowsmachine", "azureuser", null, null, null, windowsConfig);
|
||||
IdReference networkInterface = IdReference.create("/subscriptions/SUBSCRIPTIONID"
|
||||
+ "/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/" + "windowsmachine167");
|
||||
List<IdReference> networkInterfaces = new ArrayList<IdReference>();
|
||||
NetworkInterface networkInterface = NetworkInterface.create("/subscriptions/SUBSCRIPTIONID"
|
||||
+ "/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/" + "windowsmachine167", null);
|
||||
List<NetworkInterface> networkInterfaces = new ArrayList<NetworkInterface>();
|
||||
networkInterfaces.add(networkInterface);
|
||||
NetworkProfile networkProfile = NetworkProfile.create(networkInterfaces);
|
||||
DiagnosticsProfile.BootDiagnostics bootDiagnostics = DiagnosticsProfile.BootDiagnostics.create(true,
|
||||
|
|
Loading…
Reference in New Issue