Create one resource group in each region

This commit is contained in:
Ignasi Barrera 2016-10-14 17:51:42 +02:00
parent cd16826dca
commit 00d9138864
15 changed files with 382 additions and 299 deletions

View File

@ -25,12 +25,13 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_P
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_AUTHENTICATE_SUDO;
import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_USER;
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER;
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_PREFIX;
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
@ -88,9 +89,10 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
properties.put(RESOURCE, "https://management.azure.com/");
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
properties.put(RESOURCE_GROUP_NAME, "jclouds");
properties.put(DEFAULT_VNET_ADDRESS_SPACE_PREFIX, "10.0.0.0/16");
properties.put(DEFAULT_SUBNET_ADDRESS_PREFIX, "10.0.0.0/24");
properties.put(RESOURCENAME_PREFIX, "jclouds");
properties.put(RESOURCENAME_DELIMITER, "-");
properties.put(DEFAULT_DATADISKSIZE, "100");
properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
// Default credentials for all images

View File

@ -30,11 +30,12 @@ import java.util.List;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azurecompute.arm.AzureComputeApi;
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.PublicIpAvailablePredicateFactory;
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
import org.jclouds.azurecompute.arm.domain.DataDisk;
import org.jclouds.azurecompute.arm.domain.HardwareProfile;
@ -51,6 +52,8 @@ import org.jclouds.azurecompute.arm.domain.OSProfile;
import org.jclouds.azurecompute.arm.domain.Offer;
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
import org.jclouds.azurecompute.arm.domain.RegionAndId;
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
import org.jclouds.azurecompute.arm.domain.SKU;
import org.jclouds.azurecompute.arm.domain.StorageProfile;
@ -86,38 +89,40 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
/**
* Defines the connection between the {@link AzureComputeApi} implementation and the jclouds
* {@link org.jclouds.compute.ComputeService}.
* Defines the connection between the {@link AzureComputeApi} implementation and
* the jclouds {@link org.jclouds.compute.ComputeService}.
*/
@Singleton
public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location> {
private final String azureGroup;
private final CleanupResources cleanupResources;
private final AzureComputeApi api;
private final AzureComputeConstants azureComputeConstants;
private final Supplier<Set<String>> regionIds;
private final Predicate<String> publicIpAvailable;
private final PublicIpAvailablePredicateFactory publicIpAvailable;
private final LocationToResourceGroupName locationToResourceGroupName;
@Inject
AzureComputeServiceAdapter(final AzureComputeApi api, final AzureComputeConstants azureComputeConstants,
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
@Named("PublicIpAvailable") Predicate<String> publicIpAvailable) {
PublicIpAvailablePredicateFactory publicIpAvailable, LocationToResourceGroupName locationToResourceGroupName) {
this.api = api;
this.azureComputeConstants = azureComputeConstants;
this.azureGroup = azureComputeConstants.azureResourceGroup();
this.cleanupResources = cleanupResources;
this.regionIds = regionIds;
this.publicIpAvailable = publicIpAvailable;
this.locationToResourceGroupName = locationToResourceGroupName;
}
@Override
public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(
final String group, final String name, final Template template) {
public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(final String group,
final String name, final Template template) {
AzureTemplateOptions templateOptions = template.getOptions().as(AzureTemplateOptions.class);
String azureGroup = locationToResourceGroupName.apply(template.getLocation().getId());
// TODO Store group apart from the name to be able to identify nodes with custom names in the configured group
// TODO Store group apart from the name to be able to identify nodes with
// custom names in the configured group
// TODO ARM specific options
// TODO user metadata and tags
// TODO network ids => create one nic in each network
@ -125,24 +130,26 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
String locationName = template.getLocation().getId();
String subnetId = templateOptions.getSubnetId();
NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName);
NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName, azureGroup);
StorageProfile storageProfile = createStorageProfile(name, template.getImage(), templateOptions.getBlob());
HardwareProfile hardwareProfile = HardwareProfile.builder().vmSize(template.getHardware().getId()).build();
OSProfile osProfile = createOsProfile(name, template);
NetworkProfile networkProfile = NetworkProfile.builder().networkInterfaces(ImmutableList.of(IdReference.create(nic.id()))).build();
NetworkProfile networkProfile = NetworkProfile.builder()
.networkInterfaces(ImmutableList.of(IdReference.create(nic.id()))).build();
VirtualMachineProperties virtualMachineProperties = VirtualMachineProperties.builder()
.licenseType(null) // TODO
.availabilitySet(null) // TODO
.hardwareProfile(hardwareProfile)
.storageProfile(storageProfile)
.osProfile(osProfile)
.networkProfile(networkProfile)
.build();
.hardwareProfile(hardwareProfile).storageProfile(storageProfile).osProfile(osProfile)
.networkProfile(networkProfile).build();
VirtualMachine virtualMachine = api.getVirtualMachineApi(azureGroup).create(name, template.getLocation().getId(), virtualMachineProperties);
VirtualMachine virtualMachine = api.getVirtualMachineApi(azureGroup).create(name, template.getLocation().getId(),
virtualMachineProperties);
// Safe to pass null credentials here, as jclouds will default populate the node with the default credentials from the image, or the ones in the options, if provided.
return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, name, null);
// Safe to pass null credentials here, as jclouds will default populate
// the node with the default credentials from the image, or the ones in
// the options, if provided.
RegionAndId regionAndId = RegionAndId.fromRegionAndId(template.getLocation().getId(), name);
return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, regionAndId.slashEncode(), null);
}
@Override
@ -151,14 +158,9 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
for (Location location : listLocations()) {
Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
for (VMSize vmSize : vmSizes) {
VMHardware hwProfile = VMHardware.create(
vmSize.name(),
vmSize.numberOfCores(),
vmSize.osDiskSizeInMB(),
vmSize.resourceDiskSizeInMB(),
vmSize.memoryInMB(),
vmSize.maxDataDiskCount(),
location.name(),
VMHardware hwProfile = VMHardware
.create(vmSize.name(), vmSize.numberOfCores(), vmSize.osDiskSizeInMB(),
vmSize.resourceDiskSizeInMB(), vmSize.memoryInMB(), vmSize.maxDataDiskCount(), location.name(),
false);
hwProfiles.add(hwProfile);
}
@ -188,7 +190,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
private List<VMImage> listImagesByLocation(String location) {
final List<VMImage> osImages = Lists.newArrayList();
Iterable<String> publishers = Splitter.on(',').trimResults().omitEmptyStrings().split(this.azureComputeConstants.azureImagePublishers());
Iterable<String> publishers = Splitter.on(',').trimResults().omitEmptyStrings()
.split(this.azureComputeConstants.azureImagePublishers());
for (String publisher : publishers) {
osImages.addAll(getImagesFromPublisher(publisher, location));
}
@ -202,8 +205,12 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
for (Location location : listLocations()) {
osImages.addAll(listImagesByLocation(location.name()));
}
// list custom images
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
String azureGroup = resourceGroup.name();
List<StorageService> storages = api.getStorageAccountApi(azureGroup).list();
for (StorageService storage : storages) {
String name = storage.name();
StorageService storageService = api.getStorageAccountApi(azureGroup).get(name);
@ -220,6 +227,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
}
}
}
}
return osImages;
}
@ -227,11 +235,14 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
@Override
public VMImage getImage(final String id) {
VMImage image = decodeFieldsFromUniqueId(id);
String azureGroup = locationToResourceGroupName.apply(image.location());
if (image.custom()) {
VMImage customImage = null;
StorageServiceKeys keys = api.getStorageAccountApi(azureGroup).getKeys(image.storage());
if (keys == null) {
// If the storage account for the image does not exist, it means the image was deleted
// If the storage account for the image does not exist, it means the
// image was deleted
return null;
}
@ -275,35 +286,33 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
public boolean apply(ResourceProviderMetaData input) {
return input.resourceType().equals("virtualMachines");
}
})
.transformAndConcat(new Function<ResourceProviderMetaData, Iterable<String>>() {
}).transformAndConcat(new Function<ResourceProviderMetaData, Iterable<String>>() {
@Override
public Iterable<String> apply(ResourceProviderMetaData resourceProviderMetaData) {
return resourceProviderMetaData.locations();
}
});
List<Location> locations = FluentIterable.from(api.getLocationApi().list())
.filter(new Predicate<Location>() {
List<Location> locations = FluentIterable.from(api.getLocationApi().list()).filter(new Predicate<Location>() {
@Override
public boolean apply(Location location) {
return Iterables.contains(vmLocations, location.displayName());
}
})
.filter(new Predicate<Location>() {
}).filter(new Predicate<Location>() {
@Override
public boolean apply(Location location) {
return regionIds.get().isEmpty() ? true : regionIds.get().contains(location.name());
}
})
.toList();
}).toList();
return locations;
}
@Override
public VirtualMachine getNode(final String id) {
return api.getVirtualMachineApi(azureGroup).get(id);
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
return api.getVirtualMachineApi(azureGroup).get(regionAndId.id());
}
@Override
@ -313,22 +322,32 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
@Override
public void rebootNode(final String id) {
api.getVirtualMachineApi(azureGroup).restart(id);
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
api.getVirtualMachineApi(azureGroup).restart(regionAndId.id());
}
@Override
public void resumeNode(final String id) {
api.getVirtualMachineApi(azureGroup).start(id);
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
api.getVirtualMachineApi(azureGroup).start(regionAndId.id());
}
@Override
public void suspendNode(final String id) {
api.getVirtualMachineApi(azureGroup).stop(id);
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String azureGroup = locationToResourceGroupName.apply(regionAndId.region());
api.getVirtualMachineApi(azureGroup).stop(regionAndId.id());
}
@Override
public Iterable<VirtualMachine> listNodes() {
return api.getVirtualMachineApi(azureGroup).list();
ImmutableList.Builder<VirtualMachine> nodes = ImmutableList.builder();
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
nodes.addAll(api.getVirtualMachineApi(resourceGroup.name()).list());
}
return nodes.build();
}
@Override
@ -341,59 +360,54 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
});
}
private OSProfile createOsProfile(String computerName, Template template) {
String defaultLoginUser = template.getImage().getDefaultCredentials().getUser();
String defaultLoginPassword = template.getImage().getDefaultCredentials().getOptionalPassword().get();
String adminUsername = Objects.firstNonNull(template.getOptions().getLoginUser(), defaultLoginUser);
String adminPassword = Objects.firstNonNull(template.getOptions().getLoginPassword(), defaultLoginPassword);
OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).computerName(computerName);
// prefer public key over password
if (template.getOptions().getPublicKey() != null) {
OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).adminPassword(adminPassword)
.computerName(computerName);
if (template.getOptions().getPublicKey() != null
&& OsFamily.WINDOWS != template.getImage().getOperatingSystem().getFamily()) {
OSProfile.LinuxConfiguration linuxConfiguration = OSProfile.LinuxConfiguration.create("true",
OSProfile.LinuxConfiguration.SSH.create(ImmutableList.of(
OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create(
String.format("/home/%s/.ssh/authorized_keys", adminUsername),
template.getOptions().getPublicKey())
))
);
OSProfile.LinuxConfiguration.SSH.create(ImmutableList.of(OSProfile.LinuxConfiguration.SSH.SSHPublicKey
.create(String.format("/home/%s/.ssh/authorized_keys", adminUsername), template.getOptions()
.getPublicKey()))));
builder.linuxConfiguration(linuxConfiguration);
} else {
builder.adminPassword(adminPassword);
}
return builder.build();
}
private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, String name, String locationName) {
private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, String name, String locationName,
String azureGroup) {
final PublicIPAddressApi ipApi = api.getPublicIPAddressApi(azureGroup);
PublicIPAddressProperties properties =
PublicIPAddressProperties.builder()
.publicIPAllocationMethod("Static")
.idleTimeoutInMinutes(4)
.build();
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);
PublicIPAddress ip = ipApi.createOrUpdate(publicIpAddressName, locationName, ImmutableMap.of("jclouds", name),
properties);
checkState(publicIpAvailable.apply(publicIpAddressName),
checkState(publicIpAvailable.create(azureGroup).apply(publicIpAddressName),
"Public IP was not provisioned in the configured timeout");
final NetworkInterfaceCardProperties networkInterfaceCardProperties =
NetworkInterfaceCardProperties.builder()
.ipConfigurations(ImmutableList.of(
IpConfiguration.builder()
final NetworkInterfaceCardProperties networkInterfaceCardProperties = NetworkInterfaceCardProperties
.builder()
.ipConfigurations(
ImmutableList.of(IpConfiguration
.builder()
.name("ipConfig-" + name)
.properties(IpConfigurationProperties.builder()
.privateIPAllocationMethod("Dynamic")
.publicIPAddress(IdReference.create(ip.id()))
.subnet(IdReference.create(subnetId))
.build())
.build()))
.build();
.properties(
IpConfigurationProperties.builder().privateIPAllocationMethod("Dynamic")
.publicIPAddress(IdReference.create(ip.id())).subnet(IdReference.create(subnetId))
.build()).build())).build();
String networkInterfaceCardName = "jc-nic-" + name;
return api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, ImmutableMap.of("jclouds", name));
return api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName,
networkInterfaceCardProperties, ImmutableMap.of("jclouds", name));
}
private StorageProfile createStorageProfile(String name, Image image, String blob) {
@ -403,12 +417,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
String osType = null;
if (!imageRef.custom()) {
imageReference = ImageReference.builder()
.publisher(image.getProviderId())
.offer(image.getName())
.sku(image.getVersion())
.version("latest")
.build();
imageReference = ImageReference.builder().publisher(image.getProviderId()).offer(image.getName())
.sku(image.getVersion()).version("latest").build();
} else {
sourceImage = VHD.create(image.getProviderId());

View File

@ -24,7 +24,6 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_P
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
@ -137,10 +136,6 @@ public class AzureComputeServiceContextModule
@Inject
private String tcpRuleRegexpProperty;
@Named(RESOURCE_GROUP_NAME)
@Inject
private String azureResourceGroupProperty;
@Named(IMAGE_PUBLISHERS)
@Inject
private String azureImagePublishersProperty;
@ -161,10 +156,6 @@ public class AzureComputeServiceContextModule
return Long.parseLong(operationTimeoutProperty);
}
public String azureResourceGroup() {
return azureResourceGroupProperty;
}
public String azureImagePublishers() {
return azureImagePublishersProperty;
}
@ -199,10 +190,10 @@ public class AzureComputeServiceContextModule
}
@Provides
@com.google.inject.name.Named(TIMEOUT_NODE_RUNNING)
protected Predicate<String> provideVirtualMachineRunningPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, Timeouts timeouts, PollPeriod pollPeriod) {
String azureGroup = azureComputeConstants.azureResourceGroup();
return retry(new VirtualMachineInStatePredicate(api, azureGroup, PowerState.RUNNING), timeouts.nodeRunning,
@Named(TIMEOUT_NODE_RUNNING)
protected VirtualMachineInStatePredicateFactory provideVirtualMachineRunningPredicate(final AzureComputeApi api,
Timeouts timeouts, PollPeriod pollPeriod) {
return new VirtualMachineInStatePredicateFactory(api, PowerState.RUNNING, timeouts.nodeRunning,
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
}
@ -229,19 +220,17 @@ public class AzureComputeServiceContextModule
@Provides
@Named(TIMEOUT_NODE_SUSPENDED)
protected Predicate<String> provideNodeSuspendedPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
protected VirtualMachineInStatePredicateFactory provideNodeSuspendedPredicate(final AzureComputeApi api,
Timeouts timeouts, PollPeriod pollPeriod) {
String azureGroup = azureComputeConstants.azureResourceGroup();
return retry(new VirtualMachineInStatePredicate(api, azureGroup, PowerState.STOPPED), timeouts.nodeTerminated,
return new VirtualMachineInStatePredicateFactory(api, PowerState.STOPPED, timeouts.nodeTerminated,
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
}
@Provides
@Named("PublicIpAvailable")
protected Predicate<String> providePublicIpAvailablePredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
Timeouts timeouts, PollPeriod pollPeriod) {
String azureGroup = azureComputeConstants.azureResourceGroup();
return retry(new PublicIpAvailablePredicate(api, azureGroup), azureComputeConstants.operationTimeout(),
protected PublicIpAvailablePredicateFactory providePublicIpAvailablePredicate(final AzureComputeApi api,
final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, Timeouts timeouts,
PollPeriod pollPeriod) {
return new PublicIpAvailablePredicateFactory(api, azureComputeConstants.operationTimeout(),
azureComputeConstants.operationPollInitialPeriod(), azureComputeConstants.operationPollMaxPeriod());
}
@ -280,39 +269,54 @@ public class AzureComputeServiceContextModule
}
}
@VisibleForTesting
static class VirtualMachineInStatePredicate implements Predicate<String> {
public static class VirtualMachineInStatePredicateFactory {
private final AzureComputeApi api;
private final String azureGroup;
private final PowerState powerState;
private final long timeout;
private final long period;
private final long maxPeriod;
public VirtualMachineInStatePredicate(AzureComputeApi api, String azureGroup, PowerState powerState) {
this.api = checkNotNull(api, "api must not be null");
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
this.powerState = checkNotNull(powerState, "powerState must not be null");
VirtualMachineInStatePredicateFactory(AzureComputeApi api, PowerState powerState, long timeout,
long period, long maxPeriod) {
this.api = checkNotNull(api, "api cannot be null");
this.powerState = checkNotNull(powerState, "powerState cannot be null");
this.timeout = timeout;
this.period = period;
this.maxPeriod = maxPeriod;
}
public Predicate<String> create(final String azureGroup) {
return retry(new Predicate<String>() {
@Override
public boolean apply(String name) {
checkNotNull(name, "name cannot be null");
VirtualMachineInstance vmInstance = api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
if (vmInstance == null) return false;
VirtualMachineInstance vmInstance = api.getVirtualMachineApi(azureGroup).getInstanceDetails(name);
if (vmInstance == null)
return false;
return powerState == vmInstance.powerState();
}
}, timeout, period, maxPeriod);
}
}
@VisibleForTesting
static class PublicIpAvailablePredicate implements Predicate<String> {
public static class PublicIpAvailablePredicateFactory {
private final AzureComputeApi api;
private final String azureGroup;
private final long timeout;
private final long period;
private final long maxPeriod;
public PublicIpAvailablePredicate(AzureComputeApi api, String azureGroup) {
this.api = checkNotNull(api, "api must not be null");
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
PublicIpAvailablePredicateFactory(AzureComputeApi api, long timeout,
long period, long maxPeriod) {
this.api = checkNotNull(api, "api cannot be null");
this.timeout = timeout;
this.period = period;
this.maxPeriod = maxPeriod;
}
public Predicate<String> create(final String azureGroup) {
return retry(new Predicate<String>() {
@Override
public boolean apply(String name) {
checkNotNull(name, "name cannot be null");
@ -320,6 +324,8 @@ public class AzureComputeServiceContextModule
if (publicIp == null) return false;
return publicIp.properties().provisioningState().equalsIgnoreCase("Succeeded");
}
}, timeout, period, maxPeriod);
}
}
}

View File

@ -31,8 +31,10 @@ import javax.annotation.Resource;
import org.jclouds.Constants;
import org.jclouds.azurecompute.arm.AzureComputeApi;
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.VirtualMachineInStatePredicateFactory;
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
import org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
import org.jclouds.azurecompute.arm.domain.RegionAndId;
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
import org.jclouds.azurecompute.arm.domain.VMImage;
@ -61,27 +63,27 @@ public class AzureComputeImageExtension implements ImageExtension {
protected Logger logger = Logger.NULL;
private final AzureComputeApi api;
private final String group;
private final ListeningExecutorService userExecutor;
private final Predicate<URI> imageAvailablePredicate;
private final Predicate<String> nodeSuspendedPredicate;
private final VirtualMachineInStatePredicateFactory nodeSuspendedPredicate;
private final ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage;
private final CleanupResources cleanupResources;
private final LocationToResourceGroupName locationToResourceGroupName;
@Inject
AzureComputeImageExtension(AzureComputeApi api,
@Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> imageAvailablePredicate,
@Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> nodeSuspendedPredicate,
AzureComputeConstants azureComputeConstants,
@Named(TIMEOUT_NODE_SUSPENDED) VirtualMachineInStatePredicateFactory nodeSuspendedPredicate,
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, CleanupResources cleanupResources) {
ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, CleanupResources cleanupResources,
LocationToResourceGroupName locationToResourceGroupName) {
this.api = api;
this.imageAvailablePredicate = imageAvailablePredicate;
this.nodeSuspendedPredicate = nodeSuspendedPredicate;
this.group = azureComputeConstants.azureResourceGroup();
this.userExecutor = userExecutor;
this.resourceDefinitionToImage = resourceDefinitionToImage;
this.cleanupResources = cleanupResources;
this.locationToResourceGroupName = locationToResourceGroupName;
}
@Override
@ -92,21 +94,23 @@ public class AzureComputeImageExtension implements ImageExtension {
@Override
public ListenableFuture<Image> createImage(ImageTemplate template) {
final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
final String id = cloneTemplate.getSourceNodeId();
final String name = cloneTemplate.getName();
logger.debug(">> stopping node %s...", id);
api.getVirtualMachineApi(group).stop(id);
checkState(nodeSuspendedPredicate.apply(id), "Node %s was not suspended within the configured time limit", id);
final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
final String group = locationToResourceGroupName.apply(regionAndId.region());
logger.debug(">> stopping node %s...", regionAndId.slashEncode());
api.getVirtualMachineApi(group).stop(regionAndId.id());
checkState(nodeSuspendedPredicate.create(group).apply(regionAndId.id()),
"Node %s was not suspended within the configured time limit", regionAndId.slashEncode());
return userExecutor.submit(new Callable<Image>() {
@Override
public Image call() throws Exception {
logger.debug(">> generalizing virtal machine %s...", id);
api.getVirtualMachineApi(group).generalize(id);
logger.debug(">> generalizing virtal machine %s...", regionAndId.id());
api.getVirtualMachineApi(group).generalize(regionAndId.id());
logger.debug(">> capturing virtual machine %s to container %s...", id, CONTAINER_NAME);
URI uri = api.getVirtualMachineApi(group).capture(id, cloneTemplate.getName(), CONTAINER_NAME);
logger.debug(">> capturing virtual machine %s to container %s...", regionAndId.id(), CONTAINER_NAME);
URI uri = api.getVirtualMachineApi(group).capture(regionAndId.id(), cloneTemplate.getName(), CONTAINER_NAME);
checkState(uri != null && imageAvailablePredicate.apply(uri),
"Image %s was not created within the configured time limit", cloneTemplate.getName());
@ -114,7 +118,8 @@ public class AzureComputeImageExtension implements ImageExtension {
checkState(definitions.size() == 1,
"Expected one resource definition after creating the image but %s were returned", definitions.size());
Image image = resourceDefinitionToImage.create(id, name).apply(definitions.get(0));
Image image = resourceDefinitionToImage.create(cloneTemplate.getSourceNodeId(), cloneTemplate.getName())
.apply(definitions.get(0));
logger.debug(">> created %s", image);
return image;
}

View File

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jclouds.azurecompute.arm.compute.functions;
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_DELIMITER;
import static org.jclouds.compute.config.ComputeServiceProperties.RESOURCENAME_PREFIX;
import javax.inject.Inject;
import javax.inject.Named;
import com.google.common.base.Function;
/**
* Returns the name of the resource group for the current location.
*/
public class LocationToResourceGroupName implements Function<String, String> {
private final String prefix;
private final char delimiter;
@Inject
LocationToResourceGroupName(@Named(RESOURCENAME_PREFIX) String prefix, @Named(RESOURCENAME_DELIMITER) char delimiter) {
this.prefix = prefix;
this.delimiter = delimiter;
}
@Override
public String apply(String input) {
return String.format("%s%s%s", prefix, delimiter, input);
}
}

View File

@ -23,7 +23,7 @@ import java.util.Map;
import javax.inject.Inject;
import org.jclouds.azurecompute.arm.AzureComputeApi;
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
import org.jclouds.azurecompute.arm.domain.RegionAndId;
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
import org.jclouds.azurecompute.arm.domain.VMImage;
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
@ -39,21 +39,24 @@ public class ResourceDefinitionToCustomImage implements Function<ResourceDefinit
ResourceDefinitionToCustomImage create(@Assisted("nodeId") String nodeId, @Assisted("imageName") String imageName);
}
private final String resourceGroup;
private final Function<VMImage, Image> vmImageToImage;
private final String imageName;
private final String storageAccountName;
private final VirtualMachine vm;
private final String resourceGroup;
@Inject
ResourceDefinitionToCustomImage(AzureComputeApi api, AzureComputeConstants azureComputeConstants,
ResourceDefinitionToCustomImage(AzureComputeApi api,
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
Function<VMImage, Image> vmImageToImage, @Assisted("nodeId") String nodeId,
Function<VMImage, Image> vmImageToImage, LocationToResourceGroupName locationToResourceGroupName,
@Assisted("nodeId") String nodeId,
@Assisted("imageName") String imageName) {
this.vmImageToImage = vmImageToImage;
this.resourceGroup = azureComputeConstants.azureResourceGroup();
this.imageName = imageName;
this.vm = api.getVirtualMachineApi(resourceGroup).get(nodeId);
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(nodeId);
this.resourceGroup = locationToResourceGroupName.apply(regionAndId.region());
this.vm = api.getVirtualMachineApi(this.resourceGroup).get(regionAndId.id());
this.storageAccountName = storageProfileToStorageAccountName.apply(vm.properties().storageProfile());
}

View File

@ -38,6 +38,7 @@ import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextMod
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.RegionAndId;
import org.jclouds.azurecompute.arm.domain.StorageProfile;
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
import org.jclouds.azurecompute.arm.domain.VMImage;
@ -110,7 +111,6 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
.put(PowerState.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).build(),
NodeMetadata.Status.UNRECOGNIZED);
private final String azureGroup;
private final AzureComputeApi api;
private final GroupNamingConvention nodeNamingConvention;
private final Supplier<Map<String, ? extends Image>> images;
@ -119,28 +119,32 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
private final Map<String, Credentials> credentialStore;
private final Function<VMImage, Image> vmImageToImge;
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
private final LocationToResourceGroupName locationToResourceGroupName;
@Inject
VirtualMachineToNodeMetadata(AzureComputeApi api, GroupNamingConvention.Factory namingConvention,
Supplier<Map<String, ? extends Image>> images, Supplier<Map<String, ? extends Hardware>> hardwares,
@Memoized Supplier<Set<? extends Location>> locations, Map<String, Credentials> credentialStore,
final AzureComputeConstants azureComputeConstants, Function<VMImage, Image> vmImageToImge,
StorageProfileToStorageAccountName storageProfileToStorageAccountName) {
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
LocationToResourceGroupName locationToResourceGroupName) {
this.api = api;
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
this.images = checkNotNull(images, "images cannot be null");
this.locations = checkNotNull(locations, "locations cannot be null");
this.hardwares = checkNotNull(hardwares, "hardwares cannot be null");
this.credentialStore = credentialStore;
this.azureGroup = azureComputeConstants.azureResourceGroup();
this.vmImageToImge = vmImageToImge;
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
this.locationToResourceGroupName = locationToResourceGroupName;
}
@Override
public NodeMetadata apply(VirtualMachine virtualMachine) {
String azureGroup = locationToResourceGroupName.apply(virtualMachine.location());
NodeMetadataBuilder builder = new NodeMetadataBuilder();
builder.id(virtualMachine.name());
builder.id(RegionAndId.fromRegionAndId(virtualMachine.location(), virtualMachine.name()).slashEncode());
builder.providerId(virtualMachine.id());
builder.name(virtualMachine.name());
builder.hostname(virtualMachine.name());
@ -180,7 +184,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
String locationName = virtualMachine.location();
builder.location(getLocation(locationName));
Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName);
Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName, azureGroup);
if (image.isPresent()) {
builder.imageId(image.get().getId());
builder.operatingSystem(image.get().getOperatingSystem());
@ -239,7 +243,7 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
}, null);
}
protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName) {
protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName, String azureGroup) {
if (storageProfile.imageReference() != null) {
return Optional.fromNullable(images.get().get(
encodeFieldsToUniqueId(false, locatioName, storageProfile.imageReference())));

View File

@ -35,6 +35,7 @@ import javax.inject.Singleton;
import org.jclouds.Constants;
import org.jclouds.azurecompute.arm.AzureComputeApi;
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
import org.jclouds.azurecompute.arm.domain.StorageService;
@ -73,6 +74,7 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
private final AzureComputeApi api;
private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
private final LocationToResourceGroupName locationToResourceGroupName;
@Inject
protected CreateResourceGroupThenCreateNodes(
@ -81,12 +83,14 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
GroupNamingConvention.Factory namingConvention,
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
AzureComputeApi api, AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
AzureComputeApi api, AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
LocationToResourceGroupName locationToResourceGroupName) {
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
this.api = checkNotNull(api, "api cannot be null");
checkNotNull(userExecutor, "userExecutor cannot be null");
this.azureComputeConstants = azureComputeConstants;
this.locationToResourceGroupName = locationToResourceGroupName;
}
@Override
@ -100,7 +104,7 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
logger.warn(">> a runScript was configured but no SSH key has been provided. " +
"Authentication will delegate to the ssh-agent");
}
String azureGroupName = this.azureComputeConstants.azureResourceGroup();
String azureGroupName = locationToResourceGroupName.apply(template.getLocation().getId());
AzureTemplateOptions options = template.getOptions().as(AzureTemplateOptions.class);
// create resource group for jclouds group if it does not already exist

View File

@ -34,8 +34,6 @@ public class AzureComputeProperties {
public static final String TCP_RULE_REGEXP = "jclouds.azurecompute.arm.tcp.rule.regexp";
public static final String RESOURCE_GROUP_NAME = "jclouds.azurecompute.arm.operation.resourcegroup";
public static final String IMAGE_PUBLISHERS = "jclouds.azurecompute.arm.publishers";
public static final String DEFAULT_IMAGE_LOGIN = "jclouds.azurecompute.arm.defaultimagelogin";

View File

@ -0,0 +1,50 @@
/*
* 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 com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.auto.value.AutoValue;
import com.google.common.base.Splitter;
import com.google.common.collect.Iterables;
@AutoValue
public abstract class RegionAndId {
public abstract String region();
public abstract String id();
RegionAndId() {
}
public static RegionAndId fromSlashEncoded(String id) {
Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id"));
checkArgument(Iterables.size(parts) == 2, "id must be in format regionId/id");
return new AutoValue_RegionAndId(Iterables.get(parts, 0), Iterables.get(parts, 1));
}
public static RegionAndId fromRegionAndId(String region, String id) {
return new AutoValue_RegionAndId(region, id);
}
public String slashEncode() {
return region() + "/" + id();
}
}

View File

@ -16,7 +16,6 @@
*/
package org.jclouds.azurecompute.arm.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Predicates.notNull;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
@ -25,7 +24,6 @@ import static org.jclouds.util.Closeables2.closeQuietly;
import java.net.URI;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.inject.Inject;
@ -33,10 +31,11 @@ import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.azurecompute.arm.AzureComputeApi;
import org.jclouds.azurecompute.arm.compute.functions.LocationToResourceGroupName;
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.ResourceGroup;
import org.jclouds.azurecompute.arm.domain.RegionAndId;
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
import org.jclouds.azurecompute.arm.util.BlobHelper;
@ -46,10 +45,8 @@ import org.jclouds.logging.Logger;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@Singleton
public class CleanupResources implements Function<String, Boolean> {
@ -61,28 +58,29 @@ public class CleanupResources implements Function<String, Boolean> {
protected final AzureComputeApi api;
private final Predicate<URI> resourceDeleted;
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
private final LocationToResourceGroupName locationToResourceGroupName;
@Inject
CleanupResources(AzureComputeApi azureComputeApi, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted,
StorageProfileToStorageAccountName storageProfileToStorageAccountName) {
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
LocationToResourceGroupName locationToResourceGroupName) {
this.api = azureComputeApi;
this.resourceDeleted = resourceDeleted;
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
this.locationToResourceGroupName = locationToResourceGroupName;
}
@Override
public Boolean apply(final String id) {
logger.debug(">> destroying %s ...", id);
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(id);
String group = locationToResourceGroupName.apply(regionAndId.region());
Map<String, VirtualMachine> resourceGroupNamesAndVirtualMachines = getResourceGroupNamesAndVirtualMachines(id);
if (resourceGroupNamesAndVirtualMachines.isEmpty())
VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(regionAndId.id());
if (virtualMachine == null) {
return true;
}
String group = checkNotNull(resourceGroupNamesAndVirtualMachines.entrySet().iterator().next().getKey(),
"resourceGroup name must not be null");
VirtualMachine virtualMachine = checkNotNull(resourceGroupNamesAndVirtualMachines.get(group),
"virtualMachine must not be null");
logger.debug(">> destroying %s ...", regionAndId.slashEncode());
boolean vmDeleted = deleteVirtualMachine(group, virtualMachine);
// We don't delete the network here, as it is global to the resource
@ -163,14 +161,4 @@ public class CleanupResources implements Function<String, Boolean> {
return resourceDeleted.apply(api.getVirtualMachineApi(group).delete(virtualMachine.name()));
}
private Map<String, VirtualMachine> getResourceGroupNamesAndVirtualMachines(String id) {
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
String group = resourceGroup.name();
VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(id);
if (virtualMachine != null) {
return ImmutableMap.of(group, virtualMachine);
}
}
return Maps.newHashMap();
}
}

View File

@ -16,19 +16,9 @@
*/
package org.jclouds.azurecompute.arm.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
@ -78,19 +68,8 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
@Override
protected Properties setupProperties() {
Properties properties = super.setupProperties();
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
properties.put(RESOURCE_GROUP_NAME, "jc");
properties.put(PROPERTY_REGIONS, "eastus");
properties.put(IMAGE_PUBLISHERS, "Canonical");
AzureLiveTestUtils.defaultProperties(properties);
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
return properties;
}

View File

@ -16,8 +16,6 @@
*/
package org.jclouds.azurecompute.arm.compute;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
@ -58,11 +56,8 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
@Override
protected Properties setupProperties() {
Properties properties = super.setupProperties();
properties.put(RESOURCE_GROUP_NAME, "jc");
AzureLiveTestUtils.defaultProperties(properties);
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
return properties;
}
@ -71,7 +66,8 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
public void testDefaultTemplateBuilder() throws IOException {
Template defaultTemplate = view.getComputeService().templateBuilder().build();
assertTrue(defaultTemplate.getImage().getOperatingSystem().getVersion().matches("1[45]\\.[01][04]\\.[0-9]-LTS"),
"Version mismatch, expected dd.dd.d-LTS, found: " + defaultTemplate.getImage().getOperatingSystem().getVersion());
"Version mismatch, expected dd.dd.d-LTS, found: "
+ defaultTemplate.getImage().getOperatingSystem().getVersion());
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);

View File

@ -16,20 +16,10 @@
*/
package org.jclouds.azurecompute.arm.compute.extensions;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
@ -63,19 +53,8 @@ public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTe
@Override
protected Properties setupProperties() {
Properties properties = super.setupProperties();
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
properties.put(RESOURCE_GROUP_NAME, "jc");
properties.put(PROPERTY_REGIONS, "eastus");
properties.put(IMAGE_PUBLISHERS, "Canonical");
AzureLiveTestUtils.defaultProperties(properties);
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
return properties;
}

View File

@ -16,21 +16,34 @@
*/
package org.jclouds.azurecompute.arm.internal;
import java.util.Properties;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class AzureLiveTestUtils {
public static Properties defaultProperties(Properties properties) {
properties = properties == null ? new Properties() : properties;
properties.put("oauth.identity", "foo");
properties.put("oauth.credential", "password");
properties.put("oauth.endpoint", "https://login.microsoftonline.com/oauth2/token");
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
properties.put(PROPERTY_REGIONS, "northeurope");
properties.put(PROPERTY_REGIONS, "eastus");
properties.put(IMAGE_PUBLISHERS, "Canonical");
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
return properties;
}
}