mirror of
https://github.com/apache/jclouds.git
synced 2025-02-10 20:16:01 +00:00
Update ImageExtension to work with Managed Disks
This commit is contained in:
parent
37dcb87dfa
commit
cc13cfeda1
@ -67,7 +67,11 @@
|
||||
<groupId>org.apache.jclouds.api</groupId>
|
||||
<artifactId>oauth</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-okhttp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds.api</groupId>
|
||||
@ -102,27 +106,11 @@
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-slf4j</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds.provider</groupId>
|
||||
<artifactId>azureblob</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-okhttp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
@ -135,20 +123,13 @@
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.jclouds</groupId>
|
||||
<artifactId>jclouds-blobstore</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
|
||||
<build>
|
||||
<defaultGoal>clean verify</defaultGoal>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
@ -17,7 +17,6 @@
|
||||
package org.jclouds.azurecompute.arm;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.azurecompute.arm.features.AvailabilitySetApi;
|
||||
@ -170,7 +169,7 @@ public interface AzureComputeApi extends Closeable {
|
||||
*/
|
||||
@Delegate
|
||||
LoadBalancerApi getLoadBalancerApi(@PathParam("resourcegroup") String resourcegroup);
|
||||
|
||||
|
||||
/**
|
||||
* The AvailabilitySet API includes operations for managing availability sets
|
||||
* within your subscription.
|
||||
|
@ -16,6 +16,23 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_MAX_RATE_LIMIT_WAIT;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
|
||||
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.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
|
||||
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.POLL_INITIAL_PERIOD;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.POLL_MAX_PERIOD;
|
||||
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;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
@ -44,24 +61,6 @@ import org.jclouds.providers.internal.BaseProviderMetadata;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_MAX_RATE_LIMIT_WAIT;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
|
||||
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.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
|
||||
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.POLL_INITIAL_PERIOD;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.POLL_MAX_PERIOD;
|
||||
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;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
|
||||
|
||||
@AutoService(ProviderMetadata.class)
|
||||
public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
||||
|
||||
@ -96,7 +95,7 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
||||
// Default credentials for all images
|
||||
properties.put(IMAGE_LOGIN_USER, "jclouds:Password12345!");
|
||||
properties.put(IMAGE_AUTHENTICATE_SUDO, "true");
|
||||
properties.put(TEMPLATE, "imageNameMatches=UbuntuServer,osVersionMatches=1[45]\\.[01][04]\\.[0-9]-LTS");
|
||||
properties.put(TEMPLATE, "imageNameMatches=UbuntuServer,osVersionMatches=1[456]\\.[01][04](\\.[0-9])?-LTS");
|
||||
// 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");
|
||||
@ -113,7 +112,7 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
||||
properties.put(API_VERSION_PREFIX + VMSizeApi.class.getSimpleName(), "2015-06-15");
|
||||
properties.put(API_VERSION_PREFIX + VirtualMachineApi.class.getSimpleName(), "2016-04-30-preview");
|
||||
properties.put(API_VERSION_PREFIX + LoadBalancerApi.class.getSimpleName(), "2016-03-30");
|
||||
properties.put(API_VERSION_PREFIX + AvailabilitySetApi.class.getSimpleName(), "2016-03-30");
|
||||
properties.put(API_VERSION_PREFIX + AvailabilitySetApi.class.getSimpleName(), "2016-04-30-preview");
|
||||
properties.put(API_VERSION_PREFIX + DiskApi.class.getSimpleName(), "2017-03-30");
|
||||
properties.put(API_VERSION_PREFIX + ImageApi.class.getSimpleName(), "2016-04-30-preview");
|
||||
|
||||
|
@ -16,6 +16,19 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.compute;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.ImmutableList.builder;
|
||||
import static com.google.common.collect.ImmutableList.of;
|
||||
import static com.google.common.collect.Iterables.contains;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
|
||||
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.util.VMImages.isCustom;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -27,6 +40,7 @@ import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.PublicIpAvailablePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.compute.strategy.CleanupResources;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
|
||||
@ -52,10 +66,8 @@ 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.StorageAccountType;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageService.Status;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VMHardware;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
import org.jclouds.azurecompute.arm.domain.VMSize;
|
||||
@ -64,7 +76,6 @@ import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||
import org.jclouds.azurecompute.arm.features.OSImageApi;
|
||||
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
|
||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
@ -86,23 +97,6 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.ImmutableList.builder;
|
||||
import static com.google.common.collect.ImmutableList.of;
|
||||
import static com.google.common.collect.Iterables.contains;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
|
||||
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueIdCustom;
|
||||
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.util.VMImages.isCustom;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
|
||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||
|
||||
/**
|
||||
* Defines the connection between the {@link AzureComputeApi} implementation and
|
||||
* the jclouds {@link org.jclouds.compute.ComputeService}.
|
||||
@ -122,17 +116,20 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
||||
private final Supplier<Set<String>> regionIds;
|
||||
private final PublicIpAvailablePredicateFactory publicIpAvailable;
|
||||
private final LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private final CustomImageToVMImage customImagetoVmImage;
|
||||
|
||||
@Inject
|
||||
AzureComputeServiceAdapter(final AzureComputeApi api, @Named(IMAGE_PUBLISHERS) String imagePublishers,
|
||||
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
|
||||
PublicIpAvailablePredicateFactory publicIpAvailable, LoadingCache<String, ResourceGroup> resourceGroupMap) {
|
||||
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
|
||||
PublicIpAvailablePredicateFactory publicIpAvailable, LoadingCache<String, ResourceGroup> resourceGroupMap,
|
||||
CustomImageToVMImage customImagetoVmImage) {
|
||||
this.api = api;
|
||||
this.imagePublishers = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(imagePublishers);
|
||||
this.cleanupResources = cleanupResources;
|
||||
this.regionIds = regionIds;
|
||||
this.publicIpAvailable = publicIpAvailable;
|
||||
this.resourceGroupMap = resourceGroupMap;
|
||||
this.customImagetoVmImage = customImagetoVmImage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -223,50 +220,30 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
||||
}
|
||||
return osImages;
|
||||
}
|
||||
|
||||
private List<VMImage> listCustomImagesByLocation(String location) {
|
||||
ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(location);
|
||||
List<org.jclouds.azurecompute.arm.domain.Image> customImages = api.getVirtualMachineImageApi(resourceGroup.name()).list();
|
||||
return Lists.transform(customImages, customImagetoVmImage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<VMImage> listImages() {
|
||||
final List<VMImage> osImages = Lists.newArrayList();
|
||||
|
||||
final List<String> availableLocationNames = FluentIterable.from(listLocations())
|
||||
.transform(new Function<Location, String>() {
|
||||
@Override public String apply(Location location) {
|
||||
return location.name();
|
||||
}
|
||||
}).toList();
|
||||
final ImmutableList.Builder<VMImage> osImages = ImmutableList.builder();
|
||||
|
||||
Iterable<String> availableLocationNames = transform(listLocations(), new Function<Location, String>() {
|
||||
@Override
|
||||
public String apply(Location location) {
|
||||
return location.name();
|
||||
}
|
||||
});
|
||||
|
||||
for (String locationName : availableLocationNames) {
|
||||
osImages.addAll(listImagesByLocation(locationName));
|
||||
osImages.addAll(listCustomImagesByLocation(locationName));
|
||||
}
|
||||
|
||||
// list custom images
|
||||
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
|
||||
String azureGroup = resourceGroup.name();
|
||||
List<StorageService> storages = api.getStorageAccountApi(azureGroup).list();
|
||||
|
||||
for (StorageService storage : storages) {
|
||||
try {
|
||||
String name = storage.name();
|
||||
StorageService storageService = api.getStorageAccountApi(azureGroup).get(name);
|
||||
if (storageService != null
|
||||
&& Status.Succeeded == storageService.storageServiceProperties().provisioningState()) {
|
||||
String key = api.getStorageAccountApi(azureGroup).getKeys(name).key1();
|
||||
BlobHelper blobHelper = new BlobHelper(storage.name(), key);
|
||||
try {
|
||||
List<VMImage> images = blobHelper.getImages(CONTAINER_NAME, azureGroup, CUSTOM_IMAGE_OFFER,
|
||||
storage.location());
|
||||
osImages.addAll(images);
|
||||
} finally {
|
||||
closeQuietly(blobHelper);
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
logger.warn("<< could not get custom images from storage account %s: %s", storage, ex.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return osImages;
|
||||
return osImages.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -275,30 +252,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
||||
ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(image.location());
|
||||
|
||||
if (image.custom()) {
|
||||
VMImage customImage = null;
|
||||
StorageServiceKeys keys = api.getStorageAccountApi(resourceGroup.name()).getKeys(image.storage());
|
||||
if (keys == null) {
|
||||
// If the storage account for the image does not exist, it means the
|
||||
// image was deleted
|
||||
return null;
|
||||
}
|
||||
|
||||
BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
|
||||
try {
|
||||
if (blobHelper.customImageExists()) {
|
||||
List<VMImage> customImagesInStorage = blobHelper.getImages(CONTAINER_NAME, resourceGroup.name(),
|
||||
CUSTOM_IMAGE_OFFER, image.location());
|
||||
customImage = find(customImagesInStorage, new Predicate<VMImage>() {
|
||||
@Override
|
||||
public boolean apply(VMImage input) {
|
||||
return id.equals(encodeFieldsToUniqueIdCustom(input));
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
} finally {
|
||||
closeQuietly(blobHelper);
|
||||
}
|
||||
return customImage;
|
||||
org.jclouds.azurecompute.arm.domain.Image vmImage = api.getVirtualMachineImageApi(resourceGroup.name()).get(image.name());
|
||||
return vmImage == null ? null : customImagetoVmImage.apply(vmImage);
|
||||
}
|
||||
|
||||
String location = image.location();
|
||||
@ -313,6 +268,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
||||
return VMImage.azureImage().publisher(publisher).offer(offer).sku(sku).version(version.name())
|
||||
.location(location).versionProperties(version.properties()).build();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -458,13 +414,9 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
||||
}
|
||||
|
||||
private ImageReference createImageReference(Image image) {
|
||||
return isCustom(image.getId()) ? ImageReference.builder().id(image.getId()).build() :
|
||||
ImageReference.builder()
|
||||
.publisher(image.getProviderId())
|
||||
.offer(image.getName())
|
||||
.sku(image.getVersion())
|
||||
.version("latest")
|
||||
.build();
|
||||
return isCustom(image.getId()) ? ImageReference.builder().customImageId(image.getProviderId()).build() : ImageReference
|
||||
.builder().publisher(image.getProviderId()).offer(image.getName()).sku(image.getVersion())
|
||||
.version("latest").build();
|
||||
}
|
||||
|
||||
private OSDisk createOSDisk(Image image) {
|
||||
@ -474,7 +426,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<Virtual
|
||||
.osType(osType)
|
||||
.caching(DataDisk.CachingTypes.READ_WRITE.toString())
|
||||
.createOption(CreationData.CreateOptions.FROM_IMAGE.toString())
|
||||
.managedDiskParameters(ManagedDiskParameters.create(null, ManagedDiskParameters.StorageAccountTypes.STANDARD_LRS.toString()))
|
||||
.managedDiskParameters(ManagedDiskParameters.create(null, StorageAccountType.STANDARD_LRS.toString()))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
@ -40,7 +40,6 @@ import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeSecurityGroup
|
||||
import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.NetworkSecurityGroupToSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.NetworkSecurityRuleToIpPermission;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToNodeMetadata;
|
||||
@ -48,6 +47,7 @@ import org.jclouds.azurecompute.arm.compute.loaders.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.azurecompute.arm.compute.loaders.ResourceGroupForLocation;
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes;
|
||||
import org.jclouds.azurecompute.arm.domain.Image;
|
||||
import org.jclouds.azurecompute.arm.domain.Location;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
|
||||
@ -86,7 +86,6 @@ import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||
|
||||
public class AzureComputeServiceContextModule extends
|
||||
ComputeServiceAdapterContextModule<VirtualMachine, VMHardware, VMImage, Location> {
|
||||
@ -115,8 +114,6 @@ public class AzureComputeServiceContextModule extends
|
||||
install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, VMHardware, VMImage, Location>() {
|
||||
});
|
||||
|
||||
install(new FactoryModuleBuilder().build(ResourceDefinitionToCustomImage.Factory.class));
|
||||
|
||||
bind(TemplateOptions.class).to(AzureTemplateOptions.class);
|
||||
bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class);
|
||||
bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class);
|
||||
@ -163,9 +160,9 @@ public class AzureComputeServiceContextModule extends
|
||||
|
||||
@Provides
|
||||
@Named(TIMEOUT_IMAGE_AVAILABLE)
|
||||
protected Predicate<URI> provideImageAvailablePredicate(final AzureComputeApi api, final Timeouts timeouts,
|
||||
protected Predicate<URI> provideImageCapturedPredicate(final AzureComputeApi api, final Timeouts timeouts,
|
||||
final PollPeriod pollPeriod) {
|
||||
return retry(new ImageDonePredicate(api), timeouts.imageAvailable, pollPeriod.pollInitialPeriod,
|
||||
return retry(new ImageCapturedPredicate(api), timeouts.imageAvailable, pollPeriod.pollInitialPeriod,
|
||||
pollPeriod.pollMaxPeriod);
|
||||
}
|
||||
|
||||
@ -196,6 +193,13 @@ public class AzureComputeServiceContextModule extends
|
||||
Predicate<Supplier<Provisionable>> resourceAvailable) {
|
||||
return new SecurityGroupAvailablePredicateFactory(api, resourceAvailable);
|
||||
}
|
||||
|
||||
@Provides
|
||||
protected ImageAvailablePredicateFactory provideImageAvailablePredicate(final AzureComputeApi api,
|
||||
Predicate<Supplier<Provisionable>> resourceAvailable, final Timeouts timeouts, final PollPeriod pollPeriod) {
|
||||
return new ImageAvailablePredicateFactory(api, retry(new ResourceInStatusPredicate("Succeeded"),
|
||||
timeouts.imageAvailable, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod));
|
||||
}
|
||||
|
||||
@Provides
|
||||
protected Predicate<Supplier<Provisionable>> provideResourceAvailablePredicate(final AzureComputeApi api,
|
||||
@ -231,11 +235,11 @@ public class AzureComputeServiceContextModule extends
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class ImageDonePredicate implements Predicate<URI> {
|
||||
static class ImageCapturedPredicate implements Predicate<URI> {
|
||||
|
||||
private final AzureComputeApi api;
|
||||
|
||||
public ImageDonePredicate(final AzureComputeApi api) {
|
||||
public ImageCapturedPredicate(final AzureComputeApi api) {
|
||||
this.api = checkNotNull(api, "api must not be null");
|
||||
}
|
||||
|
||||
@ -351,5 +355,33 @@ public class AzureComputeServiceContextModule extends
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class ImageAvailablePredicateFactory {
|
||||
private final AzureComputeApi api;
|
||||
private final Predicate<Supplier<Provisionable>> resourceAvailable;
|
||||
|
||||
ImageAvailablePredicateFactory(final AzureComputeApi api,
|
||||
Predicate<Supplier<Provisionable>> resourceAvailable) {
|
||||
this.api = checkNotNull(api, "api cannot be null");
|
||||
this.resourceAvailable = resourceAvailable;
|
||||
}
|
||||
|
||||
public Predicate<String> create(final String resourceGroup) {
|
||||
checkNotNull(resourceGroup, "resourceGroup cannot be null");
|
||||
return new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(final String name) {
|
||||
checkNotNull(name, "name cannot be null");
|
||||
return resourceAvailable.apply(new Supplier<Provisionable>() {
|
||||
@Override
|
||||
public Provisionable get() {
|
||||
Image img = api.getVirtualMachineImageApi(resourceGroup).get(name);
|
||||
return img == null ? null : img.properties();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,30 +16,29 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.compute.extensions;
|
||||
|
||||
import static com.google.common.base.Functions.compose;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.ImageAvailablePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.VirtualMachineInStatePredicateFactory;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
|
||||
import org.jclouds.azurecompute.arm.compute.strategy.CleanupResources;
|
||||
import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage;
|
||||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.ImageProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.compute.domain.CloneImageTemplate;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.ImageTemplate;
|
||||
@ -48,6 +47,7 @@ import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
@ -56,7 +56,6 @@ import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
|
||||
public class AzureComputeImageExtension implements ImageExtension {
|
||||
public static final String CONTAINER_NAME = "jclouds";
|
||||
public static final String CUSTOM_IMAGE_OFFER = "custom";
|
||||
|
||||
@Resource
|
||||
@ -65,26 +64,29 @@ public class AzureComputeImageExtension implements ImageExtension {
|
||||
|
||||
private final AzureComputeApi api;
|
||||
private final ListeningExecutorService userExecutor;
|
||||
private final Predicate<URI> imageAvailablePredicate;
|
||||
private final ImageAvailablePredicateFactory imageAvailablePredicate;
|
||||
private final VirtualMachineInStatePredicateFactory nodeSuspendedPredicate;
|
||||
private final ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage;
|
||||
private final CleanupResources cleanupResources;
|
||||
private final LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private final Function<VMImage, Image> vmImageToImage;
|
||||
private final Predicate<URI> resourceDeleted;
|
||||
private final CustomImageToVMImage customImagetoVmImage;
|
||||
|
||||
@Inject
|
||||
AzureComputeImageExtension(AzureComputeApi api,
|
||||
@Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> imageAvailablePredicate,
|
||||
ImageAvailablePredicateFactory imageAvailablePredicate,
|
||||
@Named(TIMEOUT_NODE_SUSPENDED) VirtualMachineInStatePredicateFactory nodeSuspendedPredicate,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, CleanupResources cleanupResources,
|
||||
LoadingCache<String, ResourceGroup> resourceGroupMap) {
|
||||
Function<VMImage, Image> vmImageToImage, LoadingCache<String, ResourceGroup> resourceGroupMap,
|
||||
@Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted,
|
||||
CustomImageToVMImage customImagetoVmImage) {
|
||||
this.api = api;
|
||||
this.imageAvailablePredicate = imageAvailablePredicate;
|
||||
this.nodeSuspendedPredicate = nodeSuspendedPredicate;
|
||||
this.userExecutor = userExecutor;
|
||||
this.resourceDefinitionToImage = resourceDefinitionToImage;
|
||||
this.cleanupResources = cleanupResources;
|
||||
this.vmImageToImage = vmImageToImage;
|
||||
this.resourceGroupMap = resourceGroupMap;
|
||||
this.resourceDeleted = resourceDeleted;
|
||||
this.customImagetoVmImage = customImagetoVmImage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -95,11 +97,13 @@ public class AzureComputeImageExtension implements ImageExtension {
|
||||
@Override
|
||||
public ListenableFuture<Image> createImage(ImageTemplate template) {
|
||||
final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
|
||||
|
||||
final RegionAndId regionAndId = RegionAndId.fromSlashEncoded(cloneTemplate.getSourceNodeId());
|
||||
ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region());
|
||||
final String resourceGroupName = resourceGroup.name();
|
||||
|
||||
final VirtualMachine vm = api.getVirtualMachineApi(resourceGroupName).get(regionAndId.id());
|
||||
final IdReference vmIdRef = IdReference.create(vm.id());
|
||||
|
||||
logger.debug(">> stopping node %s...", regionAndId.slashEncode());
|
||||
api.getVirtualMachineApi(resourceGroupName).stop(regionAndId.id());
|
||||
checkState(nodeSuspendedPredicate.create(resourceGroupName).apply(regionAndId.id()),
|
||||
@ -109,23 +113,17 @@ public class AzureComputeImageExtension implements ImageExtension {
|
||||
@Override
|
||||
public Image call() throws Exception {
|
||||
logger.debug(">> generalizing virtal machine %s...", regionAndId.id());
|
||||
|
||||
api.getVirtualMachineApi(resourceGroupName).generalize(regionAndId.id());
|
||||
|
||||
logger.debug(">> capturing virtual machine %s to container %s...", regionAndId.id(), CONTAINER_NAME);
|
||||
URI uri = api.getVirtualMachineApi(resourceGroupName)
|
||||
.capture(regionAndId.id(), cloneTemplate.getName(), CONTAINER_NAME);
|
||||
checkState(uri != null && imageAvailablePredicate.apply(uri),
|
||||
org.jclouds.azurecompute.arm.domain.Image imageFromVM = api.getVirtualMachineImageApi(resourceGroupName)
|
||||
.createOrUpdate(cloneTemplate.getName(), regionAndId.region(),
|
||||
ImageProperties.builder().sourceVirtualMachine(vmIdRef).build());
|
||||
|
||||
checkState(imageAvailablePredicate.create(resourceGroupName).apply(imageFromVM.name()),
|
||||
"Image for node %s was not created within the configured time limit", cloneTemplate.getName());
|
||||
|
||||
List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
|
||||
checkState(definitions.size() == 1,
|
||||
"Expected one resource definition after creating the image but %s were returned", definitions.size());
|
||||
|
||||
Image image = resourceDefinitionToImage.create(cloneTemplate.getSourceNodeId(), cloneTemplate.getName())
|
||||
.apply(definitions.get(0));
|
||||
checkState(image != null, "Image for node %s was not created", cloneTemplate.getSourceNodeId());
|
||||
logger.debug(">> created %s", image);
|
||||
return image;
|
||||
return compose(vmImageToImage, customImagetoVmImage).apply(imageFromVM);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -137,25 +135,8 @@ public class AzureComputeImageExtension implements ImageExtension {
|
||||
|
||||
logger.debug(">> deleting image %s", id);
|
||||
|
||||
StorageServiceKeys keys = api.getStorageAccountApi(image.group()).getKeys(image.storage());
|
||||
BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
|
||||
|
||||
try {
|
||||
// This removes now all the images in this storage. At least in theory,
|
||||
// there should be just one and if there is
|
||||
// more, they should be copies of each other.
|
||||
blobHelper.deleteContainerIfExists("system");
|
||||
boolean result = !blobHelper.customImageExists();
|
||||
|
||||
if (!blobHelper.hasContainers()) {
|
||||
logger.debug(">> storage account is empty after deleting the custom image. Deleting the storage account...");
|
||||
api.getStorageAccountApi(image.group()).delete(image.storage());
|
||||
cleanupResources.deleteResourceGroupIfEmpty(image.group());
|
||||
}
|
||||
|
||||
return result;
|
||||
} finally {
|
||||
closeQuietly(blobHelper);
|
||||
}
|
||||
ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(image.location());
|
||||
URI uri = api.getVirtualMachineImageApi(resourceGroup.name()).delete(image.name());
|
||||
return resourceDeleted.apply(uri);
|
||||
}
|
||||
}
|
||||
|
@ -14,25 +14,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.functions;
|
||||
package org.jclouds.azurecompute.arm.compute.functions;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.Image;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
* Returns the storage account name for a given storage profile.
|
||||
*/
|
||||
public class StorageProfileToStorageAccountName implements Function<StorageProfile, String> {
|
||||
public class CustomImageToVMImage implements Function<Image, VMImage> {
|
||||
|
||||
@Override
|
||||
public String apply(StorageProfile input) {
|
||||
String storageAccountNameURI = input.osDisk().vhd().uri();
|
||||
return Iterables.get(Splitter.on(".").split(URI.create(storageAccountNameURI).getHost()), 0);
|
||||
public VMImage apply(Image input) {
|
||||
return VMImage.customImage().customImageId(input.id()).location(input.location()).name(input.name())
|
||||
.offer(input.properties().storageProfile().osDisk().osType()).build();
|
||||
}
|
||||
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
* 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.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
public class ResourceDefinitionToCustomImage implements Function<ResourceDefinition, Image> {
|
||||
|
||||
public interface Factory {
|
||||
ResourceDefinitionToCustomImage create(@Assisted("nodeId") String nodeId, @Assisted("imageName") String imageName);
|
||||
}
|
||||
|
||||
private final Function<VMImage, Image> vmImageToImage;
|
||||
private final String imageName;
|
||||
private final String nodeId;
|
||||
private final AzureComputeApi api;
|
||||
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||
private final LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
|
||||
@Inject
|
||||
ResourceDefinitionToCustomImage(AzureComputeApi api,
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||
Function<VMImage, Image> vmImageToImage, LoadingCache<String, ResourceGroup> resourceGroupMap,
|
||||
@Assisted("nodeId") String nodeId, @Assisted("imageName") String imageName) {
|
||||
this.api = api;
|
||||
this.vmImageToImage = vmImageToImage;
|
||||
this.nodeId = nodeId;
|
||||
this.imageName = imageName;
|
||||
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||
this.resourceGroupMap = resourceGroupMap;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Image apply(ResourceDefinition input) {
|
||||
RegionAndId regionAndId = RegionAndId.fromSlashEncoded(nodeId);
|
||||
ResourceGroup resourceGroup = resourceGroupMap.getUnchecked(regionAndId.region());
|
||||
|
||||
VirtualMachine vm = api.getVirtualMachineApi(resourceGroup.name()).get(regionAndId.id());
|
||||
if (vm == null) {
|
||||
return null;
|
||||
}
|
||||
String storageAccountName = storageProfileToStorageAccountName.apply(vm.properties().storageProfile());
|
||||
|
||||
VMImage.Builder builder = VMImage.customImage().group(resourceGroup.name()).storage(storageAccountName)
|
||||
.name(imageName).offer(CUSTOM_IMAGE_OFFER).location(vm.location());
|
||||
|
||||
Map<String, String> properties = (Map<String, String>) input.properties();
|
||||
|
||||
Object storageObject = properties.get("storageProfile");
|
||||
Map<String, String> storageProperties = (Map<String, String>) storageObject;
|
||||
|
||||
Object osDiskObject = storageProperties.get("osDisk");
|
||||
Map<String, String> osProperties = (Map<String, String>) osDiskObject;
|
||||
builder.vhd1(osProperties.get("name"));
|
||||
|
||||
return vmImageToImage.apply(builder.build());
|
||||
}
|
||||
|
||||
}
|
@ -87,7 +87,8 @@ public class TemplateToAvailabilitySet implements Function<Template, Availabilit
|
||||
logger.debug(">> creating availability set [%s]", options.getAvailabilitySet().name());
|
||||
|
||||
availabilitySet = api.getAvailabilitySetApi(resourceGroup).createOrUpdate(
|
||||
options.getAvailabilitySet().name(), location, tags, options.getAvailabilitySet().properties());
|
||||
options.getAvailabilitySet().name(), options.getAvailabilitySet().sku(), location, tags,
|
||||
options.getAvailabilitySet().properties());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ package org.jclouds.azurecompute.arm.compute.functions;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension;
|
||||
import org.jclouds.azurecompute.arm.domain.ImageReference;
|
||||
import org.jclouds.azurecompute.arm.domain.Plan;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
@ -55,20 +56,25 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||
|
||||
private final Supplier<Set<? extends org.jclouds.domain.Location>> locations;
|
||||
|
||||
public static String encodeFieldsToUniqueId(boolean globallyAvailable, String locatioName,
|
||||
public static String encodeFieldsToUniqueId(boolean globallyAvailable, String locationName,
|
||||
ImageReference imageReference) {
|
||||
return (globallyAvailable ? "global" : locatioName) + "/" + imageReference.publisher() + "/"
|
||||
return (globallyAvailable ? "global" : locationName) + "/" + imageReference.publisher() + "/"
|
||||
+ imageReference.offer() + "/" + imageReference.sku();
|
||||
}
|
||||
|
||||
public static String encodeFieldsToUniqueIdCustom(boolean globallyAvailable, String locationName,
|
||||
ImageReference imageReference) {
|
||||
return (globallyAvailable ? "global" : locationName) + "/" + imageReference.customImageId()
|
||||
.substring(imageReference.customImageId().lastIndexOf("/") + 1);
|
||||
}
|
||||
|
||||
public static String encodeFieldsToUniqueId(VMImage imageReference) {
|
||||
return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/"
|
||||
+ imageReference.publisher() + "/" + imageReference.offer() + "/" + imageReference.sku();
|
||||
}
|
||||
|
||||
public static String encodeFieldsToUniqueIdCustom(VMImage imageReference) {
|
||||
return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.group()
|
||||
+ "/" + imageReference.storage() + "/" + imageReference.offer() + "/" + imageReference.name();
|
||||
return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.name();
|
||||
}
|
||||
|
||||
public static VMImage decodeFieldsFromUniqueId(final String id) {
|
||||
@ -76,17 +82,13 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||
String[] fields = checkNotNull(id, "id").split("/");
|
||||
if (isCustom(id)) {
|
||||
/* id fields indexes
|
||||
0: imageReference.location) + "/" +
|
||||
1: imageReference.group + "/" +
|
||||
2: imageReference.storage + "/" +
|
||||
3: imageReference.offer + "/" +
|
||||
4: imageReference.name
|
||||
0: imageReference.location + "/" +
|
||||
1: imageReference.name
|
||||
*/
|
||||
vmImage = VMImage.customImage().location(fields[0]).group(fields[1]).storage(fields[2]).vhd1(fields[3])
|
||||
.offer(fields[4]).build();
|
||||
vmImage = VMImage.customImage().location(fields[0]).name(fields[1]).build();
|
||||
} else {
|
||||
/* id fields indexes
|
||||
0: imageReference.location) + "/" +
|
||||
0: imageReference.location + "/" +
|
||||
1: imageReference.publisher + "/" +
|
||||
2: imageReference.offer + "/" +
|
||||
3: imageReference.sku + "/" +
|
||||
@ -98,7 +100,7 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||
}
|
||||
|
||||
@Inject
|
||||
VMImageToImage(@Memoized final Supplier<Set<? extends Location>> locations) {
|
||||
VMImageToImage(@Memoized Supplier<Set<? extends Location>> locations) {
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
@ -110,7 +112,7 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||
builder.location(
|
||||
FluentIterable.from(locations.get()).firstMatch(LocationPredicates.idEquals(image.location()))
|
||||
.get()).name(image.name()).description(image.group()).status(Image.Status.AVAILABLE)
|
||||
.version("latest").providerId(image.vhd1()).id(encodeFieldsToUniqueIdCustom(image));
|
||||
.version("latest").providerId(image.customImageId()).id(encodeFieldsToUniqueIdCustom(image));
|
||||
|
||||
final OperatingSystem.Builder osBuilder = osFamily().apply(image);
|
||||
builder.operatingSystem(osBuilder.build());
|
||||
@ -165,7 +167,7 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||
|
||||
// only 64bit OS images are supported by Azure ARM
|
||||
return OperatingSystem.builder().family(family).is64Bit(true)
|
||||
.description(image.custom() ? image.vhd1() : image.sku())
|
||||
.description(image.custom() ? AzureComputeImageExtension.CUSTOM_IMAGE_OFFER : image.sku())
|
||||
.version(image.custom() ? "latest" : image.sku());
|
||||
}
|
||||
};
|
||||
|
@ -16,6 +16,15 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.compute.functions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
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.functions.VMImageToImage.encodeFieldsToUniqueId;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueIdCustom;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromCommaDelimitedValue;
|
||||
import static org.jclouds.location.predicates.LocationPredicates.idEquals;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -33,11 +42,7 @@ import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
|
||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
@ -59,18 +64,6 @@ import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Strings.nullToEmpty;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Iterables.tryFind;
|
||||
import static org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter.GROUP_KEY;
|
||||
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
|
||||
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
|
||||
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueId;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromCommaDelimitedValue;
|
||||
import static org.jclouds.location.predicates.LocationPredicates.idEquals;
|
||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||
|
||||
public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> {
|
||||
|
||||
@Resource
|
||||
@ -81,8 +74,6 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
||||
private final GroupNamingConvention nodeNamingConvention;
|
||||
private final Supplier<Set<? extends Location>> locations;
|
||||
private final Supplier<Map<String, ? extends Hardware>> hardwares;
|
||||
private final Function<VMImage, Image> vmImageToImge;
|
||||
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||
private final LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private final ImageCacheSupplier imageCache;
|
||||
private final VirtualMachineToStatus virtualMachineToStatus;
|
||||
@ -90,16 +81,12 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
||||
@Inject
|
||||
VirtualMachineToNodeMetadata(AzureComputeApi api, GroupNamingConvention.Factory namingConvention,
|
||||
Supplier<Map<String, ? extends Hardware>> hardwares, @Memoized Supplier<Set<? extends Location>> locations,
|
||||
Map<String, Credentials> credentialStore, Function<VMImage, Image> vmImageToImge,
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||
LoadingCache<String, ResourceGroup> resourceGroupMap, @Memoized Supplier<Set<? extends Image>> imageCache,
|
||||
VirtualMachineToStatus virtualMachineToStatus) {
|
||||
Map<String, Credentials> credentialStore, LoadingCache<String, ResourceGroup> resourceGroupMap,
|
||||
@Memoized Supplier<Set<? extends Image>> imageCache, VirtualMachineToStatus virtualMachineToStatus) {
|
||||
this.api = api;
|
||||
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
|
||||
this.locations = locations;
|
||||
this.hardwares = hardwares;
|
||||
this.vmImageToImge = vmImageToImge;
|
||||
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||
this.resourceGroupMap = resourceGroupMap;
|
||||
this.virtualMachineToStatus = virtualMachineToStatus;
|
||||
checkArgument(imageCache instanceof ImageCacheSupplier,
|
||||
@ -207,29 +194,14 @@ public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, No
|
||||
protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName,
|
||||
String azureGroup) {
|
||||
if (storageProfile.imageReference() != null) {
|
||||
String imageId = encodeFieldsToUniqueId(false, locatioName, storageProfile.imageReference());
|
||||
// FIXME check this condition
|
||||
String imageId = storageProfile.imageReference().customImageId() != null ?
|
||||
encodeFieldsToUniqueIdCustom(false, locatioName, storageProfile.imageReference()) :
|
||||
encodeFieldsToUniqueId(false, locatioName, storageProfile.imageReference());
|
||||
return imageCache.get(imageId);
|
||||
} else {
|
||||
String storageAccountName = storageProfileToStorageAccountName.apply(storageProfile);
|
||||
StorageServiceKeys keys = api.getStorageAccountApi(azureGroup).getKeys(storageAccountName);
|
||||
BlobHelper blobHelper = new BlobHelper(storageAccountName, keys.key1());
|
||||
|
||||
try {
|
||||
// Custom image. Let's find it by uri
|
||||
List<VMImage> customImagesInStorage = blobHelper.getImages(CONTAINER_NAME, azureGroup, CUSTOM_IMAGE_OFFER,
|
||||
locatioName);
|
||||
Optional<VMImage> customImage = tryFind(customImagesInStorage, new Predicate<VMImage>() {
|
||||
@Override
|
||||
public boolean apply(VMImage input) {
|
||||
return input.vhd1().equals(storageProfile.osDisk().image().uri());
|
||||
}
|
||||
});
|
||||
|
||||
return customImage.isPresent() ? Optional.of(vmImageToImge.apply(customImage.get())) : Optional
|
||||
.<Image> absent();
|
||||
} finally {
|
||||
closeQuietly(blobHelper);
|
||||
}
|
||||
logger.warn("could not find image for storage profile %s", storageProfile);
|
||||
return Optional.absent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,11 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.compute.strategy;
|
||||
|
||||
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 org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
@ -32,11 +37,8 @@ import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.RegionAndId;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
|
||||
import org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
|
||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
@ -48,12 +50,6 @@ import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
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 org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||
|
||||
@Singleton
|
||||
public class CleanupResources {
|
||||
|
||||
@ -63,17 +59,14 @@ public class CleanupResources {
|
||||
|
||||
private final AzureComputeApi api;
|
||||
private final Predicate<URI> resourceDeleted;
|
||||
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||
private final LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private final GroupNamingConvention.Factory namingConvention;
|
||||
|
||||
@Inject
|
||||
CleanupResources(AzureComputeApi azureComputeApi, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted,
|
||||
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||
LoadingCache<String, ResourceGroup> resourceGroupMap, GroupNamingConvention.Factory namingConvention) {
|
||||
this.api = azureComputeApi;
|
||||
this.resourceDeleted = resourceDeleted;
|
||||
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||
this.resourceGroupMap = resourceGroupMap;
|
||||
this.namingConvention = namingConvention;
|
||||
}
|
||||
@ -95,7 +88,6 @@ public class CleanupResources {
|
||||
// group. It will be deleted when the resource group is deleted
|
||||
|
||||
cleanupVirtualMachineNICs(resourceGroupName, virtualMachine);
|
||||
cleanupVirtualMachineStorage(resourceGroupName, virtualMachine);
|
||||
cleanupAvailabilitySetIfOrphaned(resourceGroupName, virtualMachine);
|
||||
|
||||
return vmDeleted;
|
||||
@ -117,28 +109,6 @@ public class CleanupResources {
|
||||
}
|
||||
}
|
||||
|
||||
public void cleanupVirtualMachineStorage(String group, VirtualMachine virtualMachine) {
|
||||
String storageAccountName = storageProfileToStorageAccountName
|
||||
.apply(virtualMachine.properties().storageProfile());
|
||||
StorageServiceKeys keys = api.getStorageAccountApi(group).getKeys(storageAccountName);
|
||||
|
||||
// Remove the virtual machine files
|
||||
logger.debug(">> deleting virtual machine disk storage...");
|
||||
BlobHelper blobHelper = new BlobHelper(storageAccountName, keys.key1());
|
||||
try {
|
||||
blobHelper.deleteContainerIfExists("vhds");
|
||||
|
||||
if (!blobHelper.customImageExists()) {
|
||||
logger.debug(">> deleting storage account %s...", storageAccountName);
|
||||
api.getStorageAccountApi(group).delete(storageAccountName);
|
||||
} else {
|
||||
logger.debug(">> the storage account contains custom images. Will not delete it!");
|
||||
}
|
||||
} finally {
|
||||
closeQuietly(blobHelper);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean cleanupSecurityGroupIfOrphaned(String resourceGroup, String group) {
|
||||
String name = namingConvention.create().sharedNameForGroup(group);
|
||||
NetworkSecurityGroupApi sgapi = api.getNetworkSecurityGroupApi(resourceGroup);
|
||||
|
@ -90,6 +90,47 @@ public abstract class AvailabilitySet {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static enum AvailabilitySetType {
|
||||
MANAGED("Aligned"),
|
||||
CLASSIC("Classic");
|
||||
|
||||
private final String value;
|
||||
|
||||
AvailabilitySetType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static AvailabilitySetType fromString(String value) {
|
||||
AvailabilitySetType[] items = AvailabilitySetType.values();
|
||||
for (AvailabilitySetType item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unexpected type: " + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
@AutoValue
|
||||
public abstract static class SKU {
|
||||
|
||||
public abstract AvailabilitySetType type();
|
||||
|
||||
@SerializedNames({ "name" })
|
||||
public static SKU create(final String type) {
|
||||
return create(AvailabilitySetType.fromString(type));
|
||||
}
|
||||
|
||||
public static SKU create(AvailabilitySetType type) {
|
||||
return new AutoValue_AvailabilitySet_SKU(type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the availability set
|
||||
@ -115,31 +156,45 @@ public abstract class AvailabilitySet {
|
||||
@Nullable
|
||||
public abstract String location();
|
||||
|
||||
/**
|
||||
* Specifies the type of the availability set
|
||||
*/
|
||||
@Nullable
|
||||
public abstract SKU sku();
|
||||
|
||||
/**
|
||||
* Specifies the tags of the availability set
|
||||
*/
|
||||
@Nullable
|
||||
public abstract Map<String, String> tags();
|
||||
|
||||
|
||||
/**
|
||||
* Specifies the properties of the availability set
|
||||
*/
|
||||
@Nullable
|
||||
public abstract AvailabilitySetProperties properties();
|
||||
|
||||
|
||||
@SerializedNames({"id", "name", "type", "location", "tags", "properties"})
|
||||
@SerializedNames({ "id", "name", "type", "location", "sku", "tags", "properties" })
|
||||
public static AvailabilitySet create(final String id, final String name, final String type, final String location,
|
||||
final Map<String, String> tags, AvailabilitySetProperties properties) {
|
||||
return builder().id(id).name(name).type(type).location(location).tags(tags).properties(properties).build();
|
||||
SKU sku, final Map<String, String> tags, AvailabilitySetProperties properties) {
|
||||
return builder().id(id).name(name).type(type).location(location).sku(sku).tags(tags).properties(properties)
|
||||
.build();
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
private static Builder builder() {
|
||||
return new AutoValue_AvailabilitySet.Builder();
|
||||
}
|
||||
|
||||
public static Builder managed() {
|
||||
return builder().managed();
|
||||
}
|
||||
|
||||
public static Builder classic() {
|
||||
return builder().classic();
|
||||
}
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder id(String id);
|
||||
@ -149,6 +204,14 @@ public abstract class AvailabilitySet {
|
||||
public abstract Builder tags(Map<String, String> tags);
|
||||
public abstract Builder properties(AvailabilitySetProperties properties);
|
||||
|
||||
abstract Builder sku(SKU sku);
|
||||
public Builder managed() {
|
||||
return sku(SKU.create(AvailabilitySetType.MANAGED));
|
||||
}
|
||||
public Builder classic() {
|
||||
return sku(SKU.create(AvailabilitySetType.CLASSIC));
|
||||
}
|
||||
|
||||
abstract Map<String, String> tags();
|
||||
abstract AvailabilitySet autoBuild();
|
||||
|
||||
|
@ -26,6 +26,18 @@ import com.google.common.collect.ImmutableMap;
|
||||
|
||||
@AutoValue
|
||||
public abstract class Image {
|
||||
|
||||
/**
|
||||
* The id of the image
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String id();
|
||||
|
||||
/**
|
||||
* The name of the image
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String name();
|
||||
|
||||
/**
|
||||
* The location of the image
|
||||
@ -42,9 +54,10 @@ public abstract class Image {
|
||||
*/
|
||||
@Nullable public abstract Map<String, String> tags();
|
||||
|
||||
@SerializedNames({"location", "properties", "tags"})
|
||||
public static Image create(final String location, final ImageProperties properties, final Map<String, String> tags) {
|
||||
return builder().location(location).properties(properties).tags(tags).build();
|
||||
@SerializedNames({"id", "name", "location", "properties", "tags"})
|
||||
public static Image create(final String id, final String name, final String location,
|
||||
final ImageProperties properties, final Map<String, String> tags) {
|
||||
return builder().id(id).name(name).location(location).properties(properties).tags(tags).build();
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
@ -55,10 +68,10 @@ public abstract class Image {
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder id(String id);
|
||||
public abstract Builder name(String name);
|
||||
public abstract Builder location(String location);
|
||||
|
||||
public abstract Builder properties(ImageProperties properties);
|
||||
|
||||
public abstract Builder tags(Map<String, String> tags);
|
||||
|
||||
abstract Map<String, String> tags();
|
||||
|
@ -24,17 +24,8 @@ import com.google.auto.value.AutoValue;
|
||||
@AutoValue
|
||||
public abstract class ImageProperties implements Provisionable {
|
||||
|
||||
@AutoValue
|
||||
public abstract static class SourceVirtualMachine {
|
||||
public abstract String id();
|
||||
|
||||
@SerializedNames({"id"})
|
||||
public static SourceVirtualMachine create(final String id) {
|
||||
return new AutoValue_ImageProperties_SourceVirtualMachine(id);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract SourceVirtualMachine sourceVirtualMachine();
|
||||
@Nullable
|
||||
public abstract IdReference sourceVirtualMachine();
|
||||
|
||||
@Nullable
|
||||
public abstract StorageProfile storageProfile();
|
||||
@ -43,7 +34,7 @@ public abstract class ImageProperties implements Provisionable {
|
||||
public abstract String provisioningState();
|
||||
|
||||
@SerializedNames({ "sourceVirtualMachine", "storageProfile", "provisioningState"})
|
||||
public static ImageProperties create(final SourceVirtualMachine sourceVirtualMachine,
|
||||
public static ImageProperties create(final IdReference sourceVirtualMachine,
|
||||
final StorageProfile storageProfile,
|
||||
final String provisioningState) {
|
||||
return builder()
|
||||
@ -61,7 +52,7 @@ public abstract class ImageProperties implements Provisionable {
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder sourceVirtualMachine(SourceVirtualMachine sourceVirtualMachine);
|
||||
public abstract Builder sourceVirtualMachine(IdReference sourceVirtualMachine);
|
||||
public abstract Builder storageProfile(StorageProfile storageProfile);
|
||||
public abstract Builder provisioningState(String provisioningState);
|
||||
public abstract ImageProperties build();
|
||||
|
@ -25,11 +25,12 @@ import com.google.auto.value.AutoValue;
|
||||
public abstract class ImageReference {
|
||||
|
||||
/**
|
||||
* The id of the image reference.
|
||||
* Specifies the resource identifier of a virtual machine image in your subscription. This element is only used
|
||||
* for virtual machine images, not platform images or marketplace images.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String id();
|
||||
|
||||
public abstract String customImageId();
|
||||
|
||||
/**
|
||||
* The publisher of the image reference.
|
||||
*/
|
||||
@ -53,6 +54,10 @@ public abstract class ImageReference {
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String version();
|
||||
|
||||
ImageReference() {
|
||||
|
||||
}
|
||||
|
||||
@SerializedNames({"id", "publisher", "offer", "sku", "version"})
|
||||
public static ImageReference create(final String id,
|
||||
@ -61,8 +66,7 @@ public abstract class ImageReference {
|
||||
final String sku,
|
||||
final String version) {
|
||||
|
||||
return builder()
|
||||
.id(id)
|
||||
return builder().customImageId(id)
|
||||
.publisher(publisher)
|
||||
.offer(offer)
|
||||
.sku(sku)
|
||||
@ -78,7 +82,7 @@ public abstract class ImageReference {
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
public abstract Builder id(String id);
|
||||
public abstract Builder customImageId(String ids);
|
||||
public abstract Builder publisher(String publisher);
|
||||
public abstract Builder offer(String offer);
|
||||
public abstract Builder sku(String sku);
|
||||
|
@ -24,42 +24,13 @@ import com.google.auto.value.AutoValue;
|
||||
@AutoValue
|
||||
public abstract class ManagedDiskParameters {
|
||||
|
||||
public enum StorageAccountTypes {
|
||||
/** Enum value Standard_LRS. */
|
||||
STANDARD_LRS("Standard_LRS"),
|
||||
|
||||
/** Enum value Premium_LRS. */
|
||||
PREMIUM_LRS("Premium_LRS");
|
||||
|
||||
/** The actual serialized value for a StorageAccountTypes instance. */
|
||||
private String value;
|
||||
|
||||
StorageAccountTypes(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static StorageAccountTypes fromString(String value) {
|
||||
StorageAccountTypes[] items = StorageAccountTypes.values();
|
||||
for (StorageAccountTypes item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable public abstract String id();
|
||||
|
||||
public abstract StorageAccountTypes storageAccountType();
|
||||
// Might be null in custom images. In that case the API returns it in the OSDisk object.
|
||||
@Nullable public abstract StorageAccountType storageAccountType();
|
||||
|
||||
@SerializedNames({"id", "storageAccountType"})
|
||||
public static ManagedDiskParameters create(final String id, final String storageAccountType) {
|
||||
return new AutoValue_ManagedDiskParameters(id, StorageAccountTypes.fromString(storageAccountType));
|
||||
return new AutoValue_ManagedDiskParameters(id, StorageAccountType.fromString(storageAccountType));
|
||||
}
|
||||
}
|
||||
|
@ -64,21 +64,20 @@ public abstract class OSDisk {
|
||||
*/
|
||||
@Nullable public abstract ManagedDiskParameters managedDiskParameters();
|
||||
|
||||
@SerializedNames({"osType", "name", "vhd", "caching", "createOption", "image", "managedDisk"})
|
||||
public static OSDisk create(final String osType, final String name, final VHD vhd,
|
||||
final String caching, final String createOption, final VHD image,
|
||||
final ManagedDiskParameters managedDiskParamenters) {
|
||||
return builder()
|
||||
.osType(osType)
|
||||
.name(name)
|
||||
.vhd(vhd)
|
||||
.caching(caching)
|
||||
.createOption(createOption)
|
||||
.image(image)
|
||||
.managedDiskParameters(managedDiskParamenters)
|
||||
.build();
|
||||
/**
|
||||
* The storage account type. This field is returned in custom images.
|
||||
*/
|
||||
@Nullable public abstract StorageAccountType storageAccountType();
|
||||
|
||||
@SerializedNames({ "osType", "name", "vhd", "caching", "createOption", "image", "managedDisk", "storageAccountType" })
|
||||
public static OSDisk create(final String osType, final String name, final VHD vhd, final String caching,
|
||||
final String createOption, final VHD image, final ManagedDiskParameters managedDiskParamenters,
|
||||
final String storageAccountType) {
|
||||
return builder().osType(osType).name(name).vhd(vhd).caching(caching).createOption(createOption).image(image)
|
||||
.managedDiskParameters(managedDiskParamenters)
|
||||
.storageAccountType(StorageAccountType.fromString(storageAccountType)).build();
|
||||
}
|
||||
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
public static Builder builder() {
|
||||
@ -94,6 +93,7 @@ public abstract class OSDisk {
|
||||
public abstract Builder vhd(VHD vhd);
|
||||
public abstract Builder image(VHD image);
|
||||
public abstract Builder managedDiskParameters(ManagedDiskParameters managedDiskParameters);
|
||||
public abstract Builder storageAccountType(StorageAccountType storageAccountType);
|
||||
public abstract OSDisk build();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
public enum StorageAccountType {
|
||||
/** Enum value Standard_LRS. */
|
||||
STANDARD_LRS("Standard_LRS"),
|
||||
|
||||
/** Enum value Premium_LRS. */
|
||||
PREMIUM_LRS("Premium_LRS");
|
||||
|
||||
/** The actual serialized value for a StorageAccountTypes instance. */
|
||||
private String value;
|
||||
|
||||
StorageAccountType(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static StorageAccountType fromString(String value) {
|
||||
StorageAccountType[] items = StorageAccountType.values();
|
||||
for (StorageAccountType item : items) {
|
||||
if (item.toString().equalsIgnoreCase(value)) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.value;
|
||||
}
|
||||
}
|
@ -87,12 +87,18 @@ public abstract class VMImage {
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String name();
|
||||
|
||||
|
||||
/**
|
||||
* True if custom image
|
||||
*/
|
||||
public abstract boolean custom();
|
||||
|
||||
|
||||
/**
|
||||
* The id of the custom image template.
|
||||
*/
|
||||
@Nullable
|
||||
public abstract String customImageId();
|
||||
|
||||
/**
|
||||
* Extended version properties.
|
||||
*/
|
||||
@ -104,18 +110,23 @@ public abstract class VMImage {
|
||||
}
|
||||
|
||||
public static Builder azureImage() {
|
||||
return new AutoValue_VMImage.Builder().globallyAvailable(false).custom(false);
|
||||
return builder().globallyAvailable(false).custom(false);
|
||||
}
|
||||
|
||||
public static Builder customImage() {
|
||||
return new AutoValue_VMImage.Builder().globallyAvailable(false).custom(true);
|
||||
return builder().globallyAvailable(false).custom(true);
|
||||
}
|
||||
|
||||
VMImage() {
|
||||
|
||||
}
|
||||
|
||||
public abstract Builder toBuilder();
|
||||
|
||||
@AutoValue.Builder
|
||||
public abstract static class Builder {
|
||||
|
||||
|
||||
public abstract Builder customImageId(String id);
|
||||
public abstract Builder publisher(String published);
|
||||
public abstract Builder offer(String offer);
|
||||
public abstract Builder sku(String sku);
|
||||
|
@ -28,13 +28,13 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet.AvailabilitySetProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet.SKU;
|
||||
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
@ -65,12 +65,13 @@ public interface AvailabilitySetApi extends Closeable {
|
||||
AvailabilitySet get(@PathParam("name") String name);
|
||||
|
||||
@Named("availabilityset:createOrUpdate")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Path("/{name}")
|
||||
@PUT
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
AvailabilitySet createOrUpdate(@PathParam("name") String name,
|
||||
@PayloadParam("location") String location, @Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||
@Nullable @PayloadParam("sku") SKU sku,
|
||||
@PayloadParam("location") String location,
|
||||
@Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||
@PayloadParam("properties") AvailabilitySetProperties properties);
|
||||
|
||||
@Named("availabilityset:delete")
|
||||
|
@ -60,11 +60,11 @@ public interface DeploymentApi {
|
||||
*/
|
||||
@Named("deployment:create")
|
||||
@Path("/{deploymentname}")
|
||||
@Payload("{properties}")
|
||||
@Payload("{template}")
|
||||
@PUT
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Deployment create(@PathParam("deploymentname") String deploymentname,
|
||||
@PayloadParam("properties") String properties);
|
||||
@PayloadParam("template") String template);
|
||||
|
||||
/**
|
||||
* Get Deployment Information returns information about the specified deployment.
|
||||
@ -80,11 +80,11 @@ public interface DeploymentApi {
|
||||
*/
|
||||
@Named("deployment:validate")
|
||||
@Path("/{deploymentname}/validate")
|
||||
@Payload("{properties}")
|
||||
@Payload("{template}")
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Deployment validate(@PathParam("deploymentname") String deploymentname,
|
||||
@PayloadParam("properties") String properties);
|
||||
@PayloadParam("template") String template);
|
||||
|
||||
/**
|
||||
* List all deployments in a resource group
|
||||
|
@ -26,7 +26,6 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
@ -38,7 +37,6 @@ import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
@ -58,10 +56,8 @@ public interface DiskApi {
|
||||
|
||||
@Named("disk:create_or_update")
|
||||
@PUT
|
||||
@Payload("%7B\"location\":\"{location}\",\"properties\":{properties}%7D")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Path("/{diskName}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Disk createOrUpdate(@PathParam("diskName") String diskName,
|
||||
@PayloadParam("location") String location,
|
||||
@PayloadParam("properties") DiskProperties properties);
|
||||
|
@ -26,7 +26,6 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
@ -38,7 +37,6 @@ import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
@ -58,10 +56,8 @@ public interface ImageApi {
|
||||
|
||||
@Named("image:create_or_update")
|
||||
@PUT
|
||||
@Payload("%7B\"location\":\"{location}\",\"properties\":{properties}%7D")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Path("/{imageName}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Image createOrUpdate(@PathParam("imageName") String imageName,
|
||||
@PayloadParam("location") String location,
|
||||
@PayloadParam("properties") ImageProperties properties);
|
||||
|
@ -40,7 +40,8 @@ import org.jclouds.rest.annotations.SelectJson;
|
||||
|
||||
@RequestFilters(OAuthFilter.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface JobApi extends Closeable{
|
||||
public interface JobApi extends Closeable {
|
||||
|
||||
@GET
|
||||
@ResponseParser(ParseJobStatus.class)
|
||||
JobStatus jobStatus(@EndpointParam URI jobURI);
|
||||
|
@ -27,7 +27,6 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
@ -67,7 +66,6 @@ public interface LoadBalancerApi {
|
||||
@Path("/{loadbalancername}")
|
||||
@PUT
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
LoadBalancer createOrUpdate(@PathParam("loadbalancername") String lbName,
|
||||
@PayloadParam("location") String location, @Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||
@PayloadParam("properties") LoadBalancerProperties properties);
|
||||
|
@ -27,7 +27,6 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
@ -68,7 +67,6 @@ public interface NetworkSecurityGroupApi {
|
||||
@Path("/{networksecuritygroupname}")
|
||||
@PUT
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
NetworkSecurityGroup createOrUpdate(@PathParam("networksecuritygroupname") String nsgName,
|
||||
@PayloadParam("location") String location, @Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||
@PayloadParam("properties") NetworkSecurityGroupProperties properties);
|
||||
|
@ -26,7 +26,6 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
@ -48,11 +47,11 @@ import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface NetworkSecurityRuleApi {
|
||||
|
||||
@Named("networksecurityrule:createOrUpdate")
|
||||
@Path("/securityRules/{networksecurityrulename}")
|
||||
@PUT
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
NetworkSecurityRule createOrUpdate(@PathParam("networksecurityrulename") String ruleName,
|
||||
@PayloadParam("properties") NetworkSecurityRuleProperties properties);
|
||||
|
||||
|
@ -28,7 +28,6 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||
@ -67,7 +66,6 @@ public interface ResourceGroupApi extends Closeable{
|
||||
@Named("resourcegroup:create")
|
||||
@PUT
|
||||
@Path("/{name}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ResourceGroup create(@PathParam("name") String name, @PayloadParam("location") String location, @Nullable @PayloadParam("tags") Map<String, String> tags);
|
||||
|
||||
@ -87,7 +85,6 @@ public interface ResourceGroupApi extends Closeable{
|
||||
|
||||
@Named("resourcegroup:update")
|
||||
@PATCH
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/{name}")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
ResourceGroup update(@PathParam("name") String name, @Nullable @PayloadParam("tags") Map<String, String> tags);
|
||||
|
@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.features;
|
||||
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -79,9 +79,7 @@ public interface StorageAccountApi {
|
||||
* PUT
|
||||
*/
|
||||
@Named("storageaccount:create")
|
||||
@Payload("%7B\"location\":\"{location}\",\"tags\":{tags},\"properties\":{properties}%7D")
|
||||
@Path("/resourcegroups/{resourceGroup}/providers/Microsoft.Storage/storageAccounts/{storageAccountName}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ResponseParser(URIParser.class)
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@PUT
|
||||
@ -120,7 +118,6 @@ public interface StorageAccountApi {
|
||||
@Named("storageaccountkey:get")
|
||||
@POST
|
||||
@Path("/resourcegroups/{resourceGroup}/providers/Microsoft.Storage/storageAccounts/{storageAccountName}/listKeys")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
|
||||
StorageServiceKeys getKeys(@PathParam("storageAccountName") String storageAccountName);
|
||||
|
||||
@ -143,10 +140,8 @@ public interface StorageAccountApi {
|
||||
*/
|
||||
@Named("storageaccount:update")
|
||||
@PATCH
|
||||
@Payload("%7B\"tags\":{tags},\"properties\":{properties}%7D")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Path("/resourcegroups/{resourceGroup}/providers/Microsoft.Storage/storageAccounts/{storageAccountName}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
StorageServiceUpdateParams update(
|
||||
@PathParam("storageAccountName") String storageAccountName,
|
||||
@Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||
|
@ -77,11 +77,9 @@ public interface VirtualMachineApi {
|
||||
|
||||
@Named("CreateOrUpdateVirtualMachine")
|
||||
@PUT
|
||||
@Payload("%7B\"location\":\"{location}\",\"tags\":{tags},\"properties\":{properties},\"plan\":{plan}%7D")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Path("/{vmname}")
|
||||
@QueryParams(keys = "validating", values = "false")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
VirtualMachine createOrUpdate(@PathParam("vmname") String vmname,
|
||||
@PayloadParam("location") String location,
|
||||
@PayloadParam("properties") VirtualMachineProperties properties,
|
||||
@ -130,10 +128,10 @@ public interface VirtualMachineApi {
|
||||
@Named("capture")
|
||||
@POST
|
||||
@Payload("%7B\"vhdPrefix\":\"{vhdPrefix}\",\"destinationContainerName\":\"{destinationContainerName}\",\"overwriteVhds\":\"true\"%7D")
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
@Path("/{name}/capture")
|
||||
@ResponseParser(URIParser.class)
|
||||
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
URI capture(@PathParam("name") String name,
|
||||
@PayloadParam("vhdPrefix") String vhdPrefix,
|
||||
@PayloadParam("destinationContainerName") String destinationContainerName);
|
||||
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.ContextBuilder;
|
||||
import org.jclouds.azureblob.AzureBlobClient;
|
||||
import org.jclouds.azureblob.domain.BlobProperties;
|
||||
import org.jclouds.azureblob.domain.ContainerProperties;
|
||||
import org.jclouds.azureblob.domain.ListBlobsResponse;
|
||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||
|
||||
public class BlobHelper implements Closeable {
|
||||
|
||||
private final String storageAccount;
|
||||
private final AzureBlobClient azureBlob;
|
||||
|
||||
public BlobHelper(String storageAccount, String key) {
|
||||
this.storageAccount = storageAccount;
|
||||
this.azureBlob = ContextBuilder.newBuilder("azureblob").credentials(storageAccount, key)
|
||||
.buildApi(AzureBlobClient.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
closeQuietly(azureBlob);
|
||||
}
|
||||
|
||||
public void deleteContainerIfExists(String containerName) {
|
||||
azureBlob.deleteContainer(containerName);
|
||||
}
|
||||
|
||||
public boolean hasContainers() {
|
||||
return !azureBlob.listContainers().isEmpty();
|
||||
}
|
||||
|
||||
public boolean customImageExists() {
|
||||
return azureBlob.containerExists("system");
|
||||
}
|
||||
|
||||
public List<VMImage> getImages(String containerName, String group, String offer, String location) {
|
||||
List<VMImage> list = new ArrayList<VMImage>();
|
||||
|
||||
ContainerProperties systemContainer = azureBlob.getContainerProperties("system");
|
||||
if (systemContainer != null) {
|
||||
ListBlobsResponse blobList = azureBlob.listBlobs(systemContainer.getName());
|
||||
for (BlobProperties blob : blobList) {
|
||||
String name = blob.getName();
|
||||
|
||||
if (name.contains("-osDisk")) {
|
||||
String imageName = name.substring(name.lastIndexOf('/') + 1, name.indexOf("-osDisk"));
|
||||
String imageUrl = blob.getUrl().toString();
|
||||
|
||||
list.add(VMImage.customImage().group(group).storage(storageAccount).vhd1(imageUrl).name(imageName)
|
||||
.offer(offer).location(location).build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
@ -21,7 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class VMImages {
|
||||
|
||||
public static boolean isCustom(String imageId) {
|
||||
return checkNotNull(imageId, "id").split("/").length == 5;
|
||||
return checkNotNull(imageId, "id").split("/").length == 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,8 +16,11 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.compute;
|
||||
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
@ -38,10 +41,12 @@ import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* Live tests for the {@link org.jclouds.compute.ComputeService} integration.
|
||||
@ -50,6 +55,7 @@ import com.google.inject.TypeLiteral;
|
||||
public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
|
||||
private LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private Predicate<URI> resourceDeleted;
|
||||
|
||||
public AzureComputeServiceLiveTest() {
|
||||
provider = "azurecompute-arm";
|
||||
@ -61,6 +67,8 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
resourceGroupMap = context.utils().injector()
|
||||
.getInstance(Key.get(new TypeLiteral<LoadingCache<String, ResourceGroup>>() {
|
||||
}));
|
||||
resourceDeleted = context.utils().injector().getInstance(Key.get(new TypeLiteral<Predicate<URI>>() {
|
||||
}, Names.named(TIMEOUT_RESOURCE_DELETED)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,7 +79,11 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
ResourceGroup rg = resourceGroupMap.getIfPresent(template.getLocation().getId());
|
||||
if (rg != null) {
|
||||
AzureComputeApi api = view.unwrapApi(AzureComputeApi.class);
|
||||
api.getResourceGroupApi().delete(rg.name());
|
||||
URI uri = api.getResourceGroupApi().delete(rg.name());
|
||||
if (uri != null) {
|
||||
assertTrue(resourceDeleted.apply(uri),
|
||||
String.format("Resource %s was not terminated in the configured timeout", uri));
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@ -97,7 +109,7 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
AzureLiveTestUtils.defaultProperties(properties, getClass().getSimpleName().toLowerCase());
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
AzureLiveTestUtils.defaultProperties(properties, getClass().getSimpleName().toLowerCase());
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
@ -65,8 +65,8 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||
@Test
|
||||
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: "
|
||||
assertTrue(defaultTemplate.getImage().getOperatingSystem().getVersion().matches("1[456]\\.[01][04](\\.[0-9])?-LTS"),
|
||||
"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);
|
||||
|
@ -17,7 +17,12 @@
|
||||
package org.jclouds.azurecompute.arm.compute.extensions;
|
||||
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.compute.options.RunScriptOptions.Builder.wrapInInitScript;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
@ -26,18 +31,23 @@ import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||
import org.jclouds.compute.ComputeTestUtils;
|
||||
import org.jclouds.compute.domain.ExecResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.internal.BaseImageExtensionLiveTest;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.providers.ProviderMetadata;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* Live tests for the {@link org.jclouds.compute.extensions.ImageExtension}
|
||||
@ -45,38 +55,51 @@ import com.google.inject.TypeLiteral;
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true, testName = "AzureComputeImageExtensionLiveTest")
|
||||
public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTest {
|
||||
|
||||
public static final String NAME_PREFIX = "%s";
|
||||
|
||||
private LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
|
||||
private LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private Predicate<URI> resourceDeleted;
|
||||
private ResourceGroup testResourceGroup;
|
||||
|
||||
public AzureComputeImageExtensionLiveTest() {
|
||||
provider = "azurecompute-arm";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeContext() {
|
||||
super.initializeContext();
|
||||
|
||||
@BeforeClass(groups = { "integration", "live" })
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
resourceGroupMap = context.utils().injector()
|
||||
.getInstance(Key.get(new TypeLiteral<LoadingCache<String, ResourceGroup>>() {
|
||||
}));
|
||||
resourceDeleted = context.utils().injector().getInstance(Key.get(new TypeLiteral<Predicate<URI>>() {
|
||||
}, Names.named(TIMEOUT_RESOURCE_DELETED)));
|
||||
createResourceGroup();
|
||||
}
|
||||
|
||||
|
||||
@AfterClass(groups = { "integration", "live" })
|
||||
@Override
|
||||
@AfterClass(groups = "live", alwaysRun = true)
|
||||
protected void tearDownContext() {
|
||||
try {
|
||||
Location location = getNodeTemplate().build().getLocation();
|
||||
ResourceGroup rg = resourceGroupMap.getIfPresent(location.getId());
|
||||
if (rg != null) {
|
||||
AzureComputeApi api = view.unwrapApi(AzureComputeApi.class);
|
||||
api.getResourceGroupApi().delete(rg.name());
|
||||
URI uri = view.unwrapApi(AzureComputeApi.class).getResourceGroupApi().delete(testResourceGroup.name());
|
||||
if (uri != null) {
|
||||
assertTrue(resourceDeleted.apply(uri),
|
||||
String.format("Resource %s was not terminated in the configured timeout", uri));
|
||||
}
|
||||
} finally {
|
||||
super.tearDownContext();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void prepareNodeBeforeCreatingImage(NodeMetadata node) {
|
||||
// Don't wrap in the init-script, since the comand will clear the user
|
||||
// config, and jclouds won't be able to execute more than one command
|
||||
// (won't be able to poll for the execution status of the command when
|
||||
// running with the init-script)
|
||||
ExecResponse result = view.getComputeService().runScriptOnNode(node.getId(), "waagent -deprovision+user -force",
|
||||
wrapInInitScript(false));
|
||||
assertEquals(result.getExitStatus(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module getSshModule() {
|
||||
return new SshjSshClientModule();
|
||||
@ -85,7 +108,7 @@ public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTe
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
AzureLiveTestUtils.defaultProperties(properties, getClass().getSimpleName().toLowerCase());
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
@ -99,9 +122,11 @@ public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTe
|
||||
public TemplateBuilder getNodeTemplate() {
|
||||
Map<String, String> keyPair = ComputeTestUtils.setupKeyPair();
|
||||
return super.getNodeTemplate().options(
|
||||
authorizePublicKey(keyPair.get("public"))
|
||||
.overrideLoginPrivateKey(keyPair.get("private")));
|
||||
authorizePublicKey(keyPair.get("public")).overrideLoginPrivateKey(keyPair.get("private")));
|
||||
}
|
||||
|
||||
|
||||
private void createResourceGroup() {
|
||||
Location location = getNodeTemplate().build().getLocation();
|
||||
testResourceGroup = resourceGroupMap.getUnchecked(location.getId());
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ package org.jclouds.azurecompute.arm.compute.extensions;
|
||||
|
||||
import static com.google.common.collect.Iterables.get;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.inboundPorts;
|
||||
import static org.jclouds.compute.options.TemplateOptions.Builder.securityGroups;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
|
||||
@ -26,6 +27,7 @@ import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@ -49,9 +51,11 @@ import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
/**
|
||||
* Live test for AzureCompute
|
||||
@ -61,6 +65,7 @@ import com.google.inject.TypeLiteral;
|
||||
public class AzureComputeSecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
|
||||
|
||||
private LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private Predicate<URI> resourceDeleted;
|
||||
private ResourceGroup testResourceGroup;
|
||||
|
||||
public AzureComputeSecurityGroupExtensionLiveTest() {
|
||||
@ -73,6 +78,8 @@ public class AzureComputeSecurityGroupExtensionLiveTest extends BaseSecurityGrou
|
||||
resourceGroupMap = context.utils().injector()
|
||||
.getInstance(Key.get(new TypeLiteral<LoadingCache<String, ResourceGroup>>() {
|
||||
}));
|
||||
resourceDeleted = context.utils().injector().getInstance(Key.get(new TypeLiteral<Predicate<URI>>() {
|
||||
}, Names.named(TIMEOUT_RESOURCE_DELETED)));
|
||||
createResourceGroup();
|
||||
}
|
||||
|
||||
@ -134,7 +141,11 @@ public class AzureComputeSecurityGroupExtensionLiveTest extends BaseSecurityGrou
|
||||
@Override
|
||||
protected void tearDownContext() {
|
||||
try {
|
||||
view.unwrapApi(AzureComputeApi.class).getResourceGroupApi().delete(testResourceGroup.name());
|
||||
URI uri = view.unwrapApi(AzureComputeApi.class).getResourceGroupApi().delete(testResourceGroup.name());
|
||||
if (uri != null) {
|
||||
assertTrue(resourceDeleted.apply(uri),
|
||||
String.format("Resource %s was not terminated in the configured timeout", uri));
|
||||
}
|
||||
} finally {
|
||||
super.tearDownContext();
|
||||
}
|
||||
@ -143,7 +154,7 @@ public class AzureComputeSecurityGroupExtensionLiveTest extends BaseSecurityGrou
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
AzureLiveTestUtils.defaultProperties(properties, "sgelivetest");
|
||||
setIfTestSystemPropertyPresent(properties, "oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.jclouds.azurecompute.arm.features;
|
||||
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static org.jclouds.azurecompute.arm.domain.AvailabilitySet.AvailabilitySetType.MANAGED;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
@ -27,6 +28,7 @@ import java.util.UUID;
|
||||
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet.AvailabilitySetProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet.SKU;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
@ -56,10 +58,13 @@ public class AvailabilitySetApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
public void createAvailabilitySet() {
|
||||
AvailabilitySetProperties props = AvailabilitySetProperties.builder().platformUpdateDomainCount(2)
|
||||
.platformFaultDomainCount(3).build();
|
||||
AvailabilitySet as = api().createOrUpdate(asName, LOCATION, null, props);
|
||||
AvailabilitySet as = api().createOrUpdate(asName, SKU.create(MANAGED), LOCATION, null, props);
|
||||
|
||||
assertNotNull(as);
|
||||
assertEquals(as.name(), asName);
|
||||
|
||||
assertNotNull(as.sku());
|
||||
assertEquals(as.sku().type(), MANAGED);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "createAvailabilitySet")
|
||||
@ -80,7 +85,7 @@ public class AvailabilitySetApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
@Test(dependsOnMethods = "createAvailabilitySet")
|
||||
public void updateAvailabilitySet() {
|
||||
AvailabilitySet as = api().get(asName);
|
||||
as = api().createOrUpdate(asName, LOCATION, ImmutableMap.of("foo", "bar"), as.properties());
|
||||
as = api().createOrUpdate(asName, SKU.create(MANAGED), LOCATION, ImmutableMap.of("foo", "bar"), as.properties());
|
||||
|
||||
assertNotNull(as);
|
||||
assertTrue(as.tags().containsKey("foo"));
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.jclouds.azurecompute.arm.features;
|
||||
|
||||
import static com.google.common.collect.Iterables.isEmpty;
|
||||
import static org.jclouds.azurecompute.arm.domain.AvailabilitySet.AvailabilitySetType.MANAGED;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
@ -27,6 +28,7 @@ import java.util.List;
|
||||
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet.AvailabilitySetProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.AvailabilitySet.SKU;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@ -36,7 +38,7 @@ public class AvailabilitySetApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
private final String subscriptionid = "SUBSCRIPTIONID";
|
||||
private final String resourcegroup = "myresourcegroup";
|
||||
private final String asName = "myas";
|
||||
private final String apiVersion = "api-version=2016-03-30";
|
||||
private final String apiVersion = "api-version=2016-04-30-preview";
|
||||
|
||||
public void createAvailabilitySet() throws InterruptedException {
|
||||
|
||||
@ -46,12 +48,12 @@ public class AvailabilitySetApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
|
||||
AvailabilitySetProperties props = AvailabilitySetProperties.builder().platformUpdateDomainCount(2)
|
||||
.platformFaultDomainCount(3).build();
|
||||
AvailabilitySet as = asApi.createOrUpdate(asName, "westeurope", null, props);
|
||||
AvailabilitySet as = asApi.createOrUpdate(asName, SKU.create(MANAGED), "westeurope", null, props);
|
||||
|
||||
String path = String.format(
|
||||
"/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Compute/availabilitySets/%s?%s", subscriptionid,
|
||||
resourcegroup, asName, apiVersion);
|
||||
String json = "{\"location\":\"westeurope\",\"properties\":{\"platformUpdateDomainCount\":2,\"platformFaultDomainCount\":3}}";
|
||||
String json = "{\"location\":\"westeurope\",\"properties\":{\"platformUpdateDomainCount\":2,\"platformFaultDomainCount\":3},\"sku\":{\"name\":\"Aligned\"}}";
|
||||
assertSent(server, "PUT", path, json);
|
||||
|
||||
assertEquals(as.name(), asName);
|
||||
|
@ -23,11 +23,8 @@ import static org.testng.Assert.assertTrue;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||
import org.jclouds.azurecompute.arm.domain.Deployment;
|
||||
import org.jclouds.azurecompute.arm.domain.Deployment.ProvisioningState;
|
||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||
import org.jclouds.util.Predicates2;
|
||||
import org.testng.Assert;
|
||||
@ -37,12 +34,10 @@ import org.testng.annotations.Test;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.net.UrlEscapers;
|
||||
|
||||
@Test(testName = "DeploymentApiLiveTest", singleThreaded = true)
|
||||
@Test(groups = "live", testName = "DeploymentApiLiveTest", singleThreaded = true)
|
||||
public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
|
||||
private String deploymentName;
|
||||
private String subnetId;
|
||||
|
||||
private String properties;
|
||||
private String badProperties;
|
||||
|
||||
@ -52,7 +47,6 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
super.setup();
|
||||
createTestResourceGroup();
|
||||
deploymentName = "jc" + System.currentTimeMillis();
|
||||
String virtualNetworkName = String.format("vn-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
|
||||
String storageAccountName = String.format("st%s%s", System.getProperty("user.name"), RAND);
|
||||
|
||||
String rawtemplate = "{\"$schema\":\"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#\",\"contentVersion\":\"1.0.0.0\",\"parameters\":{\"newStorageAccountName\":{\"type\":\"string\",\"metadata\":{\"description\":\"Name of the Storage Account\"}},\"storageAccountType\":{\"type\":\"string\",\"defaultValue\":\"Standard_LRS\",\"allowedValues\":[\"Standard_LRS\",\"Standard_GRS\",\"Standard_ZRS\"],\"metadata\":{\"description\":\"Storage Account type\"}},\"location\":{\"type\":\"string\",\"allowedValues\":[\"East US\",\"West US\",\"West Europe\",\"East Asia\",\"Southeast Asia\"],\"metadata\":{\"description\":\"Location of storage account\"}}},\"resources\":[{\"type\":\"Microsoft.Storage/storageAccounts\",\"name\":\"[parameters('newStorageAccountName')]\",\"apiVersion\":\"2015-05-01-preview\",\"location\":\"[parameters('location')]\",\"properties\":{\"accountType\":\"[parameters('storageAccountType')]\"}}]}";
|
||||
@ -61,17 +55,6 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
|
||||
properties = getPutBody(rawtemplate, "Incremental", rawparameters);
|
||||
badProperties = getPutBody(rawtemplate, "Incremental", rawbadParameters);
|
||||
|
||||
//Subnets belong to a virtual network so that needs to be created first
|
||||
VirtualNetwork vn = createDefaultVirtualNetwork(resourceGroupName, virtualNetworkName, "10.3.0.0/16", LOCATION);
|
||||
assertNotNull(vn);
|
||||
|
||||
//Subnet needs to be up & running before NIC can be created
|
||||
String subnetName = String.format("s-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
|
||||
Subnet subnet = createDefaultSubnet(resourceGroupName, subnetName, virtualNetworkName, "10.3.0.0/23");
|
||||
assertNotNull(subnet);
|
||||
assertNotNull(subnet.id());
|
||||
subnetId = subnet.id();
|
||||
}
|
||||
|
||||
private String getPutBody(String template, String mode, String parameters) {
|
||||
@ -104,48 +87,10 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
}
|
||||
assertNotNull(deploymentValid);
|
||||
}
|
||||
@Test
|
||||
|
||||
@Test(dependsOnMethods = "testValidate")
|
||||
public void testCreate() {
|
||||
String rsakey = new String("ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAmfk/QSF0pvnrpdz+Ah2KulGruKU+8FFBdlw938MpOysRdmp7uwpH6Z7+5VNGNdxFIAyc/W3UaZXF9hTsU8+78TlwkZpsr2mzU+ycu37XLAQ8Uv7hjsAN0DkKKPrZ9lgUUfZVKV/8E/JIAs03gIbL6zO3y7eYJQ5fNeZb+nji7tQT+YLpGq/FDegvraPKVMQbCSCZhsHyWhdPLyFlu9/30npZ0ahYOPI/KyZxFDtM/pHp88+ZAk9Icq5owaLRWcJQqrBGWqjbZnHtjdDqvHZ+C0wPhdJZPyfkHOrSYTwSQBXfX4JLRRCz3J1jf62MbQWT1o6Y4JEs1ZP1Skxu6zR96Q== mocktest");
|
||||
|
||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||
options.authorizePublicKey(rsakey);
|
||||
options.subnetId(subnetId);
|
||||
|
||||
String deploymentTemplate = "{\n" +
|
||||
" \"id\": \"/subscriptions/04f7ec88-8e28-41ed-8537-5e17766001f5/resourceGroups/jims216group/providers/Microsoft.Resources/deployments/jcdep1458344383064\",\n" +
|
||||
" \"name\": \"jcdep1458344383064\",\n" +
|
||||
" \"properties\": {\n" +
|
||||
" \"parameters\": {\n" +
|
||||
" \"newStorageAccountName\": {\n" +
|
||||
" \"type\": \"String\",\n" +
|
||||
" \"value\": \"jcres1458344383064\"\n" +
|
||||
" },\n" +
|
||||
" \"storageAccountType\": {\n" +
|
||||
" \"type\": \"String\",\n" +
|
||||
" \"value\": \"Standard_LRS\"\n" +
|
||||
" },\n" +
|
||||
" \"location\": {\n" +
|
||||
" \"type\": \"String\",\n" +
|
||||
" \"value\": \"West US\"\n" +
|
||||
" }\n" +
|
||||
" },\n" +
|
||||
" \"mode\": \"Incremental\",\n" +
|
||||
" \"provisioningState\": \"Accepted\",\n" +
|
||||
" \"timestamp\": \"2016-03-18T23:39:47.3048037Z\",\n" +
|
||||
" \"duration\": \"PT2.4433028S\",\n" +
|
||||
" \"correlationId\": \"8dee9711-8632-4948-9fe6-368bb75e6438\",\n" +
|
||||
" \"providers\": [{\n" +
|
||||
" \"namespace\": \"Microsoft.Storage\",\n" +
|
||||
" \"resourceTypes\": [{\n" +
|
||||
" \"resourceType\": \"storageAccounts\",\n" +
|
||||
" \"locations\": [\"westus\"]\n" +
|
||||
" }]\n" +
|
||||
" }],\n" +
|
||||
" \"dependencies\": []\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplate);
|
||||
String deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(properties);
|
||||
|
||||
Deployment deploymentValid = api().validate(deploymentName, deploymentTemplate);
|
||||
assertNotNull(deploymentValid);
|
||||
|
@ -36,10 +36,10 @@ import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
@Test(groups = "live", singleThreaded = true)
|
||||
@Test(groups = "live", testName = "DiskApiLiveTest", singleThreaded = true)
|
||||
public class DiskApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
|
||||
public static final String JCLOUDS_IMAGE_PREFIX = "jclouds-";
|
||||
public static final String JCLOUDS_DISK_PREFIX = "jclouds-";
|
||||
private String diskName;
|
||||
|
||||
@BeforeClass
|
||||
@ -47,12 +47,12 @@ public class DiskApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
public void setup() {
|
||||
super.setup();
|
||||
createTestResourceGroup();
|
||||
diskName = JCLOUDS_IMAGE_PREFIX + RAND;
|
||||
diskName = JCLOUDS_DISK_PREFIX + RAND;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteDiskResourceDoesNotExist() {
|
||||
assertNull(api().delete(JCLOUDS_IMAGE_PREFIX + UUID.randomUUID()));
|
||||
assertNull(api().delete(JCLOUDS_DISK_PREFIX + UUID.randomUUID()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -16,90 +16,154 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.features;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.jclouds.azurecompute.arm.domain.Image;
|
||||
import org.jclouds.azurecompute.arm.domain.ImageProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.Provisionable;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.any;
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
@Test(groups = "live", singleThreaded = true)
|
||||
public class ImageApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
public static final String JCLOUDS_VM_IMAGE_PREFIX = "jclouds-vm-image-";
|
||||
private String imageName;
|
||||
private VirtualMachine virtualMachine;
|
||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.Image;
|
||||
import org.jclouds.azurecompute.arm.domain.ImageProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.name.Names;
|
||||
|
||||
// We extend the BaseComputeServiceContextLiveTest to create nodes using the abstraction, which is much easier
|
||||
@Test(groups = "live", singleThreaded = true, testName = "ImageApiLiveTest")
|
||||
public class ImageApiLiveTest extends BaseComputeServiceContextLiveTest {
|
||||
|
||||
private static final String imageName = "imageFromRest";
|
||||
|
||||
private LoadingCache<String, ResourceGroup> resourceGroupMap;
|
||||
private Predicate<URI> resourceDeleted;
|
||||
private AzureComputeApi api;
|
||||
|
||||
private String resourceGroupName;
|
||||
private String location;
|
||||
private ImageApi imageApi;
|
||||
private Image image;
|
||||
|
||||
private String group;
|
||||
|
||||
public ImageApiLiveTest() {
|
||||
provider = "azurecompute-arm";
|
||||
group = getClass().getSimpleName().toLowerCase();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
@Override
|
||||
public void setup() {
|
||||
super.setup();
|
||||
createTestResourceGroup();
|
||||
imageName = JCLOUDS_VM_IMAGE_PREFIX + RAND;
|
||||
String vmName = "jclouds-vm-" + RAND;
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
AzureLiveTestUtils.defaultProperties(properties, getClass().getSimpleName().toLowerCase());
|
||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
|
||||
virtualMachine = api.getVirtualMachineApi(resourceGroupName).createOrUpdate(vmName, LOCATION, VirtualMachineProperties.builder().build(),
|
||||
Collections.<String, String> emptyMap(), null);
|
||||
@Override
|
||||
protected void initializeContext() {
|
||||
super.initializeContext();
|
||||
resourceDeleted = context.utils().injector().getInstance(Key.get(new TypeLiteral<Predicate<URI>>() {
|
||||
}, Names.named(TIMEOUT_RESOURCE_DELETED)));
|
||||
resourceGroupMap = context.utils().injector()
|
||||
.getInstance(Key.get(new TypeLiteral<LoadingCache<String, ResourceGroup>>() {
|
||||
}));
|
||||
api = view.unwrapApi(AzureComputeApi.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@BeforeClass
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
// Use the resource name conventions used in the abstraction
|
||||
ResourceGroup resourceGroup = createResourceGroup();
|
||||
resourceGroupName = resourceGroup.name();
|
||||
location = resourceGroup.location();
|
||||
imageApi = api.getVirtualMachineImageApi(resourceGroupName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@AfterClass(alwaysRun = true)
|
||||
protected void tearDownContext() {
|
||||
try {
|
||||
view.getComputeService().destroyNodesMatching(inGroup(group));
|
||||
} finally {
|
||||
try {
|
||||
URI uri = api.getResourceGroupApi().delete(resourceGroupName);
|
||||
assertResourceDeleted(uri);
|
||||
} finally {
|
||||
super.tearDownContext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void deleteImageResourceDoesNotExist() {
|
||||
assertNull(api().delete(JCLOUDS_VM_IMAGE_PREFIX + UUID.randomUUID()));
|
||||
public void testDeleteImageDoesNotExist() {
|
||||
assertNull(imageApi.delete("notAnImage"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void CreateVirtualMachineImageFromExistingVM() {
|
||||
String id = String.format("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/myVM", getSubscriptionId(), resourceGroupName);
|
||||
ImageProperties properties = ImageProperties.builder()
|
||||
.sourceVirtualMachine(ImageProperties.SourceVirtualMachine.create(id))
|
||||
.build();
|
||||
Image image = api().createOrUpdate(imageName, LOCATION, properties);
|
||||
assertTrue(waitUntilAvailable(imageName), "creation operation did not complete in the configured timeout");
|
||||
assertTrue(id.equals(image.properties().sourceVirtualMachine().id()));
|
||||
}
|
||||
public void testCreateImage() throws RunNodesException {
|
||||
NodeMetadata node = getOnlyElement(view.getComputeService().createNodesInGroup(group, 1));
|
||||
IdReference vmIdRef = IdReference.create(node.getProviderId());
|
||||
view.getComputeService().suspendNode(node.getId());
|
||||
|
||||
@Test(dependsOnMethods = "CreateVirtualMachineImageFromExistingVM")
|
||||
public void getImage() {
|
||||
Image image = api().get(imageName);
|
||||
api.getVirtualMachineApi(resourceGroupName).generalize(node.getName());
|
||||
|
||||
image = imageApi.createOrUpdate(imageName, location, ImageProperties.builder()
|
||||
.sourceVirtualMachine(vmIdRef).build());
|
||||
assertNotNull(image);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "CreateVirtualMachineImageFromExistingVM")
|
||||
public void listImages() {
|
||||
List<Image> images = api().list();
|
||||
assertTrue(images.size() > 0);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = {"listImages", "getImage"}, alwaysRun = true)
|
||||
public void deleteImage() {
|
||||
URI uri = api().delete(imageName);
|
||||
assertNotNull(uri);
|
||||
}
|
||||
|
||||
private ImageApi api() {
|
||||
return api.getVirtualMachineImageApi(resourceGroupName);
|
||||
}
|
||||
|
||||
private boolean waitUntilAvailable(final String name) {
|
||||
return resourceAvailable.apply(new Supplier<Provisionable>() {
|
||||
@Override public Provisionable get() {
|
||||
Image image = api().get(name);
|
||||
return image == null ? null : image.properties();
|
||||
@Test(dependsOnMethods = "testCreateImage")
|
||||
public void testListImages() {
|
||||
// Check that the image we've just created exists
|
||||
assertTrue(any(imageApi.list(), new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image input) {
|
||||
return image.name().equals(input.name());
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreateImage")
|
||||
public void testGetImage() {
|
||||
assertNotNull(imageApi.get(imageName));
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = { "testCreateImage", "testListImages", "testGetImage" }, alwaysRun = true)
|
||||
public void deleteImage() {
|
||||
assertResourceDeleted(imageApi.delete(imageName));
|
||||
}
|
||||
|
||||
private void assertResourceDeleted(final URI uri) {
|
||||
if (uri != null) {
|
||||
assertTrue(resourceDeleted.apply(uri),
|
||||
String.format("Resource %s was not deleted in the configured timeout", uri));
|
||||
}
|
||||
}
|
||||
|
||||
private ResourceGroup createResourceGroup() {
|
||||
Location location = view.getComputeService().templateBuilder().build().getLocation();
|
||||
return resourceGroupMap.getUnchecked(location.getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.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.util.List;
|
||||
|
||||
import org.jclouds.azurecompute.arm.domain.DataDisk;
|
||||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||
import org.jclouds.azurecompute.arm.domain.Image;
|
||||
import org.jclouds.azurecompute.arm.domain.ImageProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.OSDisk;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
@Test(groups = "unit", testName = "ImageApiMockTest", singleThreaded = true)
|
||||
public class ImageApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
private static final String subscriptionid = "SUBSCRIPTIONID";
|
||||
private static final String resourcegroup = "myresourcegroup";
|
||||
private static final String apiVersion = "api-version=2016-04-30-preview";
|
||||
private static final String imageName = "testVirtualMachineImage";
|
||||
private static final String location = "canadaeast";
|
||||
|
||||
private static final String PATH = String
|
||||
.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Compute/images/%s?%s", subscriptionid,
|
||||
resourcegroup, imageName, apiVersion);
|
||||
|
||||
public void createVirtualMachineImage() throws InterruptedException {
|
||||
server.enqueue(jsonResponse("/virtualmachineimagecreate.json"));
|
||||
|
||||
ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
Image result = imageApi.createOrUpdate(imageName, location, newVirtualMachineImage().properties());
|
||||
|
||||
assertSent(server, "PUT", PATH, "{\"location\":\"" + location + "\","
|
||||
+ "\"properties\":{\"sourceVirtualMachine\":{\"id\":\"vmId\"},"
|
||||
+ "\"storageProfile\":{\"osDisk\":{\"osType\":\"Linux\",\"name\":\"Ubuntu\"},\"dataDisks\":[]},"
|
||||
+ "\"provisioningState\":\"Succeeded\"}}");
|
||||
|
||||
assertEquals(result.name(), imageName);
|
||||
assertEquals(result.location(), location);
|
||||
}
|
||||
|
||||
public void getVirtualMachineImage() throws InterruptedException {
|
||||
server.enqueue(jsonResponse("/virtualmachineimageget.json"));
|
||||
|
||||
ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
Image result = imageApi.get(imageName);
|
||||
|
||||
assertSent(server, "GET", PATH);
|
||||
|
||||
assertEquals(result.name(), imageName);
|
||||
assertEquals(result.location(), location);
|
||||
assertNotNull(result.properties().sourceVirtualMachine());
|
||||
assertNotNull(result.properties().storageProfile());
|
||||
}
|
||||
|
||||
public void getVirtualMachineImageReturns404() throws InterruptedException {
|
||||
server.enqueue(response404());
|
||||
|
||||
final ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
Image result = imageApi.get(imageName);
|
||||
|
||||
assertSent(server, "GET", PATH);
|
||||
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
public void listVirtualMachineImages() throws InterruptedException {
|
||||
server.enqueue(jsonResponse("/virtualmachineimagelist.json"));
|
||||
|
||||
final ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
List<Image> result = imageApi.list();
|
||||
|
||||
assertSent(server, "GET", String
|
||||
.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Compute/images?%s", subscriptionid,
|
||||
resourcegroup, apiVersion));
|
||||
|
||||
assertNotNull(result);
|
||||
assertTrue(result.size() > 0);
|
||||
}
|
||||
|
||||
public void listVirtualMachineImagesReturns404() throws InterruptedException {
|
||||
server.enqueue(response404());
|
||||
|
||||
final ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
List<Image> result = imageApi.list();
|
||||
|
||||
assertSent(server, "GET", String
|
||||
.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Compute/images?%s", subscriptionid,
|
||||
resourcegroup, apiVersion));
|
||||
|
||||
assertTrue(isEmpty(result));
|
||||
}
|
||||
|
||||
public void deleteVirtualMachineImage() throws InterruptedException {
|
||||
server.enqueue(response202WithHeader());
|
||||
|
||||
final ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
URI uri = imageApi.delete(imageName);
|
||||
|
||||
assertSent(server, "DELETE", PATH);
|
||||
|
||||
assertNotNull(uri);
|
||||
assertTrue(uri.toString().contains("api-version"));
|
||||
assertTrue(uri.toString().contains("operationresults"));
|
||||
}
|
||||
|
||||
public void deleteVirtualMachineImageDoesNotExist() throws InterruptedException {
|
||||
server.enqueue(response404());
|
||||
|
||||
final ImageApi imageApi = api.getVirtualMachineImageApi(resourcegroup);
|
||||
URI uri = imageApi.delete(imageName);
|
||||
assertNull(uri);
|
||||
|
||||
assertSent(server, "DELETE", PATH);
|
||||
}
|
||||
|
||||
private Image newVirtualMachineImage() {
|
||||
return Image
|
||||
.builder()
|
||||
.name(imageName)
|
||||
.location(location)
|
||||
.properties(
|
||||
ImageProperties
|
||||
.builder()
|
||||
.sourceVirtualMachine(IdReference.create("vmId"))
|
||||
.storageProfile(
|
||||
StorageProfile.create(null, OSDisk.builder().osType("Linux").name("Ubuntu").build(),
|
||||
ImmutableList.<DataDisk> of())).provisioningState("Succeeded").build()).build();
|
||||
|
||||
}
|
||||
}
|
@ -116,7 +116,7 @@ public class LoadBalancerApiLiveTest extends BaseComputeServiceContextLiveTest {
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
AzureLiveTestUtils.defaultProperties(properties, getClass().getSimpleName().toLowerCase());
|
||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
@ -356,7 +356,7 @@ public class LoadBalancerApiLiveTest extends BaseComputeServiceContextLiveTest {
|
||||
// set
|
||||
AvailabilitySetProperties props = AvailabilitySetProperties.builder().platformUpdateDomainCount(count)
|
||||
.platformFaultDomainCount(count).build();
|
||||
AvailabilitySet as = AvailabilitySet.builder().name(group).properties(props).build();
|
||||
AvailabilitySet as = AvailabilitySet.managed().name(group).properties(props).build();
|
||||
|
||||
Set<? extends NodeMetadata> nodes = view.getComputeService()
|
||||
.createNodesInGroup(group, count, availabilitySet(as));
|
||||
|
@ -16,6 +16,12 @@
|
||||
*/
|
||||
package org.jclouds.azurecompute.arm.features;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -24,7 +30,6 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
@ -37,6 +42,7 @@ import org.jclouds.azurecompute.arm.domain.NetworkProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.OSDisk;
|
||||
import org.jclouds.azurecompute.arm.domain.OSProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageAccountType;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||
@ -45,8 +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.functions.ParseJobStatus;
|
||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@ -55,20 +61,12 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
@Test(groups = "live", testName = "VirtualMachineApiLiveTest")
|
||||
public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
|
||||
private String subscriptionid;
|
||||
private String storageServiceName;
|
||||
private String vmName;
|
||||
private String nicName;
|
||||
private StorageService storageService;
|
||||
private String virtualNetworkName;
|
||||
private String subnetId;
|
||||
|
||||
@ -81,9 +79,6 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
createTestResourceGroup();
|
||||
virtualNetworkName = String.format("vn-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
|
||||
|
||||
storageServiceName = String.format("st%s%s", System.getProperty("user.name"), RAND);
|
||||
storageService = createStorageService(resourceGroupName, storageServiceName, LOCATION);
|
||||
|
||||
// Subnets belong to a virtual network so that needs to be created first
|
||||
assertNotNull(createDefaultVirtualNetwork(resourceGroupName, virtualNetworkName, "10.2.0.0/16", LOCATION));
|
||||
|
||||
@ -103,25 +98,10 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
|
||||
@Test
|
||||
public void testCreate() {
|
||||
String blob = storageService.storageServiceProperties().primaryEndpoints().get("blob");
|
||||
|
||||
VirtualMachine vm = api().createOrUpdate(vmName, LOCATION, getProperties(blob, nicName),
|
||||
VirtualMachine vm = api().createOrUpdate(vmName, LOCATION, getProperties(nicName, null),
|
||||
Collections.<String, String> emptyMap(), null);
|
||||
assertTrue(!vm.name().isEmpty());
|
||||
|
||||
//Poll until resource is ready to be used
|
||||
boolean jobDone = retry(new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String name) {
|
||||
return !api().get(name).properties().provisioningState().equals(VirtualMachineProperties.ProvisioningState.CREATING);
|
||||
}
|
||||
}, 60 * 20 * 1000).apply(vmName);
|
||||
assertTrue(jobDone, "createOrUpdate operation did not complete in the configured timeout");
|
||||
|
||||
VirtualMachineProperties.ProvisioningState status = api().get(vmName).properties().provisioningState();
|
||||
// Cannot be creating anymore. Should be succeeded or running but not failed.
|
||||
assertThat(status).isNotEqualTo(VirtualMachineProperties.ProvisioningState.CREATING);
|
||||
assertThat(status).isNotEqualTo(VirtualMachineProperties.ProvisioningState.FAILED);
|
||||
waitUntilReady(vmName);
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
@ -139,7 +119,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
@Test(dependsOnMethods = "testGet")
|
||||
public void testStart() {
|
||||
api().start(vmName);
|
||||
assertTrue(stateReached(PowerState.RUNNING), "start operation did not complete in the configured timeout");
|
||||
assertTrue(stateReached(vmName, PowerState.RUNNING), "start operation did not complete in the configured timeout");
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testStart")
|
||||
@ -147,15 +127,12 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
VirtualMachine vm = api().get(vmName);
|
||||
VirtualMachineProperties oldProperties = vm.properties();
|
||||
StorageProfile oldStorageProfile = oldProperties.storageProfile();
|
||||
|
||||
String blob = storageService.storageServiceProperties().primaryEndpoints().get("blob");
|
||||
VHD vhd = VHD.create(blob + "vhds/" + vmName + "new-data-disk.vhd");
|
||||
|
||||
DataDisk newDataDisk = DataDisk.builder()
|
||||
.name(vmName + "new-data-disk")
|
||||
.diskSizeGB("1")
|
||||
.lun(1)
|
||||
.createOption(DataDisk.DiskCreateOptionTypes.EMPTY)
|
||||
.vhd(vhd)
|
||||
.build();
|
||||
List<DataDisk> oldDataDisks = oldStorageProfile.dataDisks();
|
||||
assertEquals(oldDataDisks.size(), 1);
|
||||
@ -173,15 +150,15 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
@Test(dependsOnMethods = "testUpdate")
|
||||
public void testStop() {
|
||||
api().stop(vmName);
|
||||
assertTrue(stateReached(PowerState.STOPPED), "stop operation did not complete in the configured timeout");
|
||||
assertTrue(stateReached(vmName, PowerState.STOPPED), "stop operation did not complete in the configured timeout");
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testStop")
|
||||
public void testRestart() {
|
||||
api().start(vmName);
|
||||
assertTrue(stateReached(PowerState.RUNNING), "start operation did not complete in the configured timeout");
|
||||
assertTrue(stateReached(vmName, PowerState.RUNNING), "start operation did not complete in the configured timeout");
|
||||
api().restart(vmName);
|
||||
assertTrue(stateReached(PowerState.RUNNING), "restart operation did not complete in the configured timeout");
|
||||
assertTrue(stateReached(vmName, PowerState.RUNNING), "restart operation did not complete in the configured timeout");
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCreate")
|
||||
@ -201,15 +178,31 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
@Test(dependsOnMethods = "testRestart")
|
||||
public void testGeneralize() throws IllegalStateException {
|
||||
api().stop(vmName);
|
||||
assertTrue(stateReached(PowerState.STOPPED), "restart operation did not complete in the configured timeout");
|
||||
assertTrue(stateReached(vmName, PowerState.STOPPED), "restart operation did not complete in the configured timeout");
|
||||
api().generalize(vmName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(dependsOnMethods = "testGeneralize")
|
||||
@Test
|
||||
public void testCapture() throws IllegalStateException {
|
||||
URI uri = api().capture(vmName, vmName, vmName);
|
||||
if (uri == null) Assert.fail();
|
||||
// Capture is only allowed for Blob based VMs, so let's create one VM for this test
|
||||
NetworkInterfaceCard nic = createNetworkInterfaceCard(resourceGroupName, "capture-nic-" + RAND, LOCATION, "ipConfig-" + RAND);
|
||||
StorageService storageService = createStorageService(resourceGroupName, "capture" + RAND, LOCATION);
|
||||
String blob = storageService.storageServiceProperties().primaryEndpoints().get("blob");
|
||||
|
||||
String captureVmName = "capture-" + RAND;
|
||||
api().createOrUpdate(captureVmName, LOCATION, getProperties(nic.name(), blob),
|
||||
Collections.<String, String> emptyMap(), null);
|
||||
waitUntilReady(captureVmName);
|
||||
|
||||
api().stop(captureVmName);
|
||||
assertTrue(stateReached(captureVmName, PowerState.STOPPED),
|
||||
"restart operation did not complete in the configured timeout");
|
||||
api().generalize(captureVmName);
|
||||
|
||||
URI uri = api().capture(captureVmName, captureVmName, captureVmName);
|
||||
assertNotNull(uri);
|
||||
|
||||
if (imageAvailablePredicate.apply(uri)) {
|
||||
List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
|
||||
if (definitions != null) {
|
||||
@ -219,18 +212,13 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
Map<String, String> properties2 = (Map<String, String>) storageObject;
|
||||
Object osDiskObject = properties2.get("osDisk");
|
||||
Map<String, String> osProperties = (Map<String, String>) osDiskObject;
|
||||
Object dataDisksObject = properties2.get("dataDisks");
|
||||
List<Object> dataProperties = (List<Object>) dataDisksObject;
|
||||
Map<String, String> datadiskObject = (Map<String, String>) dataProperties.get(0);
|
||||
|
||||
assertNotNull(osProperties.get("name"));
|
||||
assertNotNull(datadiskObject.get("name"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testCapture", alwaysRun = true)
|
||||
@Test(dependsOnMethods = "testGeneralize", alwaysRun = true)
|
||||
public void testDelete() throws Exception {
|
||||
URI uri = api().delete(vmName);
|
||||
assertResourceDeleted(uri);
|
||||
@ -240,22 +228,28 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
return api.getVirtualMachineApi(resourceGroupName);
|
||||
}
|
||||
|
||||
private VirtualMachineProperties getProperties(String blob, String nic) {
|
||||
private VirtualMachineProperties getProperties(String nic, String blob) {
|
||||
|
||||
HardwareProfile hwProf = HardwareProfile.create("Standard_D1");
|
||||
ImageReference imgRef = ImageReference.builder().publisher("MicrosoftWindowsServerEssentials")
|
||||
.offer("WindowsServerEssentials").sku("WindowsServerEssentials").version("latest").build();
|
||||
DataDisk dataDisk = DataDisk.builder().name("data").diskSizeGB("100").lun(0).createOption(DataDisk.DiskCreateOptionTypes.EMPTY).build();
|
||||
List<DataDisk> dataDisks = new ArrayList<DataDisk>();
|
||||
dataDisks.add(dataDisk);
|
||||
|
||||
OSDisk osDisk = OSDisk.builder()
|
||||
|
||||
DataDisk.Builder dataDisk = DataDisk.builder().name("data").diskSizeGB("100").lun(0).createOption(DataDisk.DiskCreateOptionTypes.EMPTY);
|
||||
|
||||
OSDisk.Builder osDisk = OSDisk.builder()
|
||||
.name("os")
|
||||
.osType("Windows")
|
||||
.caching(DataDisk.CachingTypes.READ_WRITE.toString())
|
||||
.createOption("FromImage")
|
||||
.managedDiskParameters(ManagedDiskParameters.create(null, ManagedDiskParameters.StorageAccountTypes.STANDARD_LRS.toString()))
|
||||
.build();
|
||||
StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk, dataDisks);
|
||||
.createOption("FromImage");
|
||||
|
||||
if (blob == null) {
|
||||
osDisk.managedDiskParameters(ManagedDiskParameters.create(null, StorageAccountType.STANDARD_LRS.toString()));
|
||||
} else {
|
||||
osDisk.vhd(VHD.create(blob + "vhds/" + vmName + ".vhd"));
|
||||
dataDisk.vhd(VHD.create(blob + "vhds/" + vmName + "data.vhd"));
|
||||
}
|
||||
|
||||
StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk.build(), ImmutableList.of(dataDisk.build()));
|
||||
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
|
||||
null);
|
||||
OSProfile osProfile = OSProfile.create(vmName, "azureuser", "RFe3&432dg", null, null, windowsConfig);
|
||||
@ -267,15 +261,12 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
new ArrayList<IdReference>();
|
||||
networkInterfaces.add(networkInterface);
|
||||
NetworkProfile networkProfile = NetworkProfile.create(networkInterfaces);
|
||||
DiagnosticsProfile.BootDiagnostics bootDiagnostics =
|
||||
DiagnosticsProfile.BootDiagnostics.create(true, blob);
|
||||
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
|
||||
VirtualMachineProperties properties = VirtualMachineProperties.create(null,
|
||||
null, null, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile, VirtualMachineProperties.ProvisioningState.CREATING);
|
||||
null, null, hwProf, storageProfile, osProfile, networkProfile, null, VirtualMachineProperties.ProvisioningState.CREATING);
|
||||
return properties;
|
||||
}
|
||||
|
||||
protected NetworkInterfaceCard createNetworkInterfaceCard(final String resourceGroupName, String networkInterfaceCardName, String locationName, String ipConfigurationName) {
|
||||
private NetworkInterfaceCard createNetworkInterfaceCard(final String resourceGroupName, String networkInterfaceCardName, String locationName, String ipConfigurationName) {
|
||||
//Create properties object
|
||||
final NetworkInterfaceCardProperties networkInterfaceCardProperties = NetworkInterfaceCardProperties
|
||||
.builder()
|
||||
@ -286,12 +277,46 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||
final Map<String, String> tags = ImmutableMap.of("jclouds", "livetest");
|
||||
return api.getNetworkInterfaceCardApi(resourceGroupName).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, tags);
|
||||
}
|
||||
|
||||
private StorageService createStorageService(final String resourceGroupName, final String storageServiceName,
|
||||
final String location) {
|
||||
URI uri = api.getStorageAccountApi(resourceGroupName).create(storageServiceName, location,
|
||||
ImmutableMap.of("property_name", "property_value"),
|
||||
ImmutableMap.of("accountType", StorageService.AccountType.Standard_LRS.toString()));
|
||||
if (uri != null) {
|
||||
assertTrue(uri.toString().contains("api-version"));
|
||||
|
||||
boolean jobDone = retry(new Predicate<URI>() {
|
||||
@Override
|
||||
public boolean apply(final URI uri) {
|
||||
return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
|
||||
}
|
||||
}, 60 * 1 * 1000 /* 1 minute timeout */).apply(uri);
|
||||
assertTrue(jobDone, "create operation did not complete in the configured timeout");
|
||||
}
|
||||
return api.getStorageAccountApi(resourceGroupName).get(storageServiceName);
|
||||
}
|
||||
|
||||
private boolean waitForState(String name, final PowerState state) {
|
||||
return api().getInstanceDetails(name).powerState().equals(state);
|
||||
}
|
||||
|
||||
private void waitUntilReady(String vmName) {
|
||||
boolean ready = retry(new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String name) {
|
||||
return !api().get(name).properties().provisioningState().equals(VirtualMachineProperties.ProvisioningState.CREATING);
|
||||
}
|
||||
}, 60 * 20 * 1000).apply(vmName);
|
||||
assertTrue(ready, "createOrUpdate operation did not complete in the configured timeout");
|
||||
|
||||
private boolean stateReached(final PowerState state) {
|
||||
VirtualMachineProperties.ProvisioningState status = api().get(vmName).properties().provisioningState();
|
||||
// Cannot be creating anymore. Should be succeeded or running but not failed.
|
||||
assertThat(status).isNotEqualTo(VirtualMachineProperties.ProvisioningState.CREATING);
|
||||
assertThat(status).isNotEqualTo(VirtualMachineProperties.ProvisioningState.FAILED);
|
||||
}
|
||||
|
||||
private boolean stateReached(String vmName, final PowerState state) {
|
||||
return retry(new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String name) {
|
||||
|
@ -233,7 +233,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
assertNotNull(uri);
|
||||
assertSent(server, "POST", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute"
|
||||
+ "/virtualMachines/vm/capture?api-version=2016-04-30-preview",
|
||||
"{\"vhdPrefix\":\"prefix\",\"destinationContainerName\":\"container\"}");
|
||||
"{\"vhdPrefix\":\"prefix\",\"destinationContainerName\":\"container\",\"overwriteVhds\":\"true\"}");
|
||||
}
|
||||
|
||||
public void testCapture404() throws Exception {
|
||||
@ -244,7 +244,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
assertNull(uri);
|
||||
assertSent(server, "POST", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute"
|
||||
+ "/virtualMachines/vm/capture?api-version=2016-04-30-preview",
|
||||
"{\"vhdPrefix\":\"prefix\",\"destinationContainerName\":\"container\"}");
|
||||
"{\"vhdPrefix\":\"prefix\",\"destinationContainerName\":\"container\",\"overwriteVhds\":\"true\"}");
|
||||
}
|
||||
|
||||
private VirtualMachineProperties getProperties() {
|
||||
@ -252,7 +252,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||
ImageReference imgRef = ImageReference.builder().publisher("publisher").offer("offer").sku("sku").version("ver").build();
|
||||
VHD vhd = VHD.create("https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd");
|
||||
List<DataDisk> dataDisks = new ArrayList<DataDisk>();
|
||||
OSDisk osDisk = OSDisk.create("Windows", "windowsmachine", vhd, "ReadWrite", "FromImage", null, null);
|
||||
OSDisk osDisk = OSDisk.create("Windows", "windowsmachine", vhd, "ReadWrite", "FromImage", null, null, null);
|
||||
StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk, dataDisks);
|
||||
OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true,
|
||||
null);
|
||||
|
@ -32,21 +32,20 @@ import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
|
||||
|
||||
public class AzureLiveTestUtils {
|
||||
|
||||
public static Properties defaultProperties(Properties properties) {
|
||||
properties = properties == null ? new Properties() : properties;
|
||||
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
|
||||
properties.put(PROPERTY_REGIONS, "westeurope");
|
||||
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||
properties.put(RESOURCENAME_PREFIX, "jcloudstest");
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
public static Properties defaultProperties(Properties properties, String resourceNamePrefix) {
|
||||
properties = properties == null ? new Properties() : properties;
|
||||
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
|
||||
properties.put(PROPERTY_REGIONS, "westeurope");
|
||||
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||
properties.put(RESOURCENAME_PREFIX, resourceNamePrefix);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -38,10 +38,8 @@ import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
|
||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
|
||||
import org.jclouds.azurecompute.arm.domain.Provisionable;
|
||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
||||
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
|
||||
import org.testng.annotations.AfterClass;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
@ -99,7 +97,7 @@ public class BaseAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi
|
||||
@Override protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
// for oauth
|
||||
AzureLiveTestUtils.defaultProperties(properties);
|
||||
AzureLiveTestUtils.defaultProperties(properties, getClass().getSimpleName().toLowerCase());
|
||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||
return properties;
|
||||
}
|
||||
@ -139,23 +137,6 @@ public class BaseAzureComputeApiLiveTest extends BaseApiLiveTest<AzureComputeApi
|
||||
return subnet;
|
||||
}
|
||||
|
||||
protected StorageService createStorageService(final String resourceGroupName, final String storageServiceName, final String location) {
|
||||
URI uri = api.getStorageAccountApi(resourceGroupName).create(storageServiceName, location, ImmutableMap.of("property_name",
|
||||
"property_value"), ImmutableMap.of("accountType", StorageService.AccountType.Standard_LRS.toString()));
|
||||
if (uri != null) {
|
||||
assertTrue(uri.toString().contains("api-version"));
|
||||
|
||||
boolean jobDone = retry(new Predicate<URI>() {
|
||||
@Override
|
||||
public boolean apply(final URI uri) {
|
||||
return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
|
||||
}
|
||||
}, 60 * 1 * 1000 /* 1 minute timeout */).apply(uri);
|
||||
assertTrue(jobDone, "create operation did not complete in the configured timeout");
|
||||
}
|
||||
return api.getStorageAccountApi(resourceGroupName).get(storageServiceName);
|
||||
}
|
||||
|
||||
protected void createTestResourceGroup() {
|
||||
String name = String.format("rg-%s-%s", this.getClass().getSimpleName().toLowerCase(),
|
||||
System.getProperty("user.name"));
|
||||
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "Microsoft.Compute/images",
|
||||
"location": "canadaeast",
|
||||
"id": "/subscriptions/bd81406c-6028-4037-9f03-9a3af4ff725d/resourceGroups/jcloudstest-canadaeast/providers/Microsoft.Compute/images/testVirtualMachineImage",
|
||||
"name": "testVirtualMachineImage",
|
||||
"properties": {
|
||||
"sourceVirtualMachine": {
|
||||
"id": "/subscriptions/bd81406c-6028-4037-9f03-9a3af4ff725d/resourceGroups/jcloudstest-canadaeast/providers/Microsoft.Compute/virtualMachines/vm2image"
|
||||
},
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"osType": "Linux",
|
||||
"osState": "Generalized",
|
||||
"blobUri": "https://jcloudstestcanadaeast982.blob.core.windows.net/vhds/vm2image20170315140332.vhd",
|
||||
"caching": "ReadWrite"
|
||||
},
|
||||
"dataDisks": []
|
||||
},
|
||||
"provisioningState": "Succeeded"
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
{
|
||||
"type": "Microsoft.Compute/images",
|
||||
"location": "canadaeast",
|
||||
"id": "/subscriptions/bd81406c-6028-4037-9f03-9a3af4ff725d/resourceGroups/jcloudstest-canadaeast/providers/Microsoft.Compute/images/testVirtualMachineImage",
|
||||
"name": "testVirtualMachineImage",
|
||||
"properties": {
|
||||
"sourceVirtualMachine": {
|
||||
"id": "/subscriptions/bd81406c-6028-4037-9f03-9a3af4ff725d/resourceGroups/jcloudstest-canadaeast/providers/Microsoft.Compute/virtualMachines/vm2image"
|
||||
},
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"osType": "Linux",
|
||||
"osState": "Generalized",
|
||||
"blobUri": "https://jcloudstestcanadaeast982.blob.core.windows.net/vhds/vm2image20170315140332.vhd",
|
||||
"caching": "ReadWrite"
|
||||
},
|
||||
"dataDisks": []
|
||||
},
|
||||
"provisioningState": "Succeeded"
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
{
|
||||
"value": [
|
||||
{
|
||||
"type": "Microsoft.Compute/images",
|
||||
"location": "canadaeast",
|
||||
"id": "/subscriptions/bd81406c-6028-4037-9f03-9a3af4ff725d/resourceGroups/jcloudstest-canadaeast/providers/Microsoft.Compute/images/imageFromRest",
|
||||
"name": "testVirtualMachineImage",
|
||||
"properties": {
|
||||
"sourceVirtualMachine": {
|
||||
"id": "/subscriptions/bd81406c-6028-4037-9f03-9a3af4ff725d/resourceGroups/jcloudstest-canadaeast/providers/Microsoft.Compute/virtualMachines/vm2image"
|
||||
},
|
||||
"storageProfile": {
|
||||
"osDisk": {
|
||||
"osType": "Linux",
|
||||
"osState": "Generalized",
|
||||
"blobUri": "https://jcloudstestcanadaeast982.blob.core.windows.net/vhds/vm2image20170315140332.vhd",
|
||||
"caching": "ReadWrite"
|
||||
},
|
||||
"dataDisks": []
|
||||
},
|
||||
"provisioningState": "Succeeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user