Update ImageExtension to work with Managed Disks
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/ea62a4c3 Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/ea62a4c3 Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/ea62a4c3 Branch: refs/heads/2.0.x Commit: ea62a4c39892871fd75663fc9741f16e707655bc Parents: 64bcdc0 Author: Dani Estevez <[email protected]> Authored: Fri Mar 17 17:23:49 2017 -0400 Committer: Ignasi Barrera <[email protected]> Committed: Mon Apr 24 08:19:46 2017 +0200 ---------------------------------------------------------------------- azurecompute-arm/pom.xml | 29 +-- .../azurecompute/arm/AzureComputeApi.java | 3 +- .../arm/AzureComputeProviderMetadata.java | 39 ++-- .../arm/compute/AzureComputeServiceAdapter.java | 134 +++++--------- .../AzureComputeServiceContextModule.java | 48 ++++- .../extensions/AzureComputeImageExtension.java | 83 ++++----- .../compute/functions/CustomImageToVMImage.java | 31 ++++ .../ResourceDefinitionToCustomImage.java | 91 ---------- .../functions/TemplateToAvailabilitySet.java | 3 +- .../arm/compute/functions/VMImageToImage.java | 32 ++-- .../functions/VirtualMachineToNodeMetadata.java | 62 ++----- .../arm/compute/strategy/CleanupResources.java | 40 +---- .../arm/domain/AvailabilitySet.java | 75 +++++++- .../jclouds/azurecompute/arm/domain/Image.java | 23 ++- .../arm/domain/ImageProperties.java | 17 +- .../azurecompute/arm/domain/ImageReference.java | 16 +- .../arm/domain/ManagedDiskParameters.java | 35 +--- .../jclouds/azurecompute/arm/domain/OSDisk.java | 28 +-- .../arm/domain/StorageAccountType.java | 47 +++++ .../azurecompute/arm/domain/VMImage.java | 21 ++- .../arm/features/AvailabilitySetApi.java | 9 +- .../arm/features/DeploymentApi.java | 8 +- .../azurecompute/arm/features/DiskApi.java | 4 - .../azurecompute/arm/features/ImageApi.java | 4 - .../azurecompute/arm/features/JobApi.java | 3 +- .../arm/features/LoadBalancerApi.java | 2 - .../arm/features/NetworkSecurityGroupApi.java | 2 - .../arm/features/NetworkSecurityRuleApi.java | 3 +- .../arm/features/ResourceGroupApi.java | 3 - .../arm/features/ResourceProviderApi.java | 1 - .../arm/features/StorageAccountApi.java | 5 - .../arm/features/VirtualMachineApi.java | 4 +- .../StorageProfileToStorageAccountName.java | 38 ---- .../azurecompute/arm/util/BlobHelper.java | 83 --------- .../jclouds/azurecompute/arm/util/VMImages.java | 2 +- .../compute/AzureComputeServiceLiveTest.java | 16 +- .../compute/AzureTemplateBuilderLiveTest.java | 6 +- .../AzureComputeImageExtensionLiveTest.java | 63 +++++-- ...reComputeSecurityGroupExtensionLiveTest.java | 15 +- .../features/AvailabilitySetApiLiveTest.java | 9 +- .../features/AvailabilitySetApiMockTest.java | 8 +- .../arm/features/DeploymentApiLiveTest.java | 63 +------ .../arm/features/DiskApiLiveTest.java | 8 +- .../arm/features/ImageApiLiveTest.java | 176 +++++++++++++------ .../arm/features/ImageApiMockTest.java | 155 ++++++++++++++++ .../arm/features/LoadBalancerApiLiveTest.java | 4 +- .../arm/features/VirtualMachineApiLiveTest.java | 153 +++++++++------- .../arm/features/VirtualMachineApiMockTest.java | 6 +- .../arm/internal/AzureLiveTestUtils.java | 33 ++-- .../internal/BaseAzureComputeApiLiveTest.java | 21 +-- .../resources/virtualmachineimagecreate.json | 21 +++ .../test/resources/virtualmachineimageget.json | 21 +++ .../test/resources/virtualmachineimagelist.json | 25 +++ 53 files changed, 954 insertions(+), 877 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/pom.xml ---------------------------------------------------------------------- diff --git a/azurecompute-arm/pom.xml b/azurecompute-arm/pom.xml index b8c7eaf..2addd07 100644 --- a/azurecompute-arm/pom.xml +++ b/azurecompute-arm/pom.xml @@ -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> @@ -103,27 +107,11 @@ <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> <scope>test</scope> @@ -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> http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java index 51ed402..7081486 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java @@ -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. http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java index 3bf1ab3..9d3f05d 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java @@ -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"); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java index e79c50d..8f9b67c 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java @@ -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(); } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java index 690022b..cf3c90c 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java @@ -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(); + } + }); + } + }; + } + } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java index cae2c7e..4bfa449 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java @@ -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), - "Image for node %s was not created within the configured time limit", cloneTemplate.getName()); + org.jclouds.azurecompute.arm.domain.Image imageFromVM = api.getVirtualMachineImageApi(resourceGroupName) + .createOrUpdate(cloneTemplate.getName(), regionAndId.region(), + ImageProperties.builder().sourceVirtualMachine(vmIdRef).build()); - 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()); + checkState(imageAvailablePredicate.create(resourceGroupName).apply(imageFromVM.name()), + "Image for node %s was not created within the configured time limit", cloneTemplate.getName()); - 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); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java new file mode 100644 index 0000000..9cb2188 --- /dev/null +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/CustomImageToVMImage.java @@ -0,0 +1,31 @@ +/* + * 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 org.jclouds.azurecompute.arm.domain.Image; +import org.jclouds.azurecompute.arm.domain.VMImage; + +import com.google.common.base.Function; + +public class CustomImageToVMImage implements Function<Image, VMImage> { + + @Override + public VMImage apply(Image input) { + return VMImage.customImage().customImageId(input.id()).location(input.location()).name(input.name()) + .offer(input.properties().storageProfile().osDisk().osType()).build(); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java deleted file mode 100644 index c27f584..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/ResourceDefinitionToCustomImage.java +++ /dev/null @@ -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()); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java index 1416872..2732b6e 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/TemplateToAvailabilitySet.java @@ -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()); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java index 25bcc3b..4f02100 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java @@ -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()); } }; http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java index cb40a14..9bad6e5 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VirtualMachineToNodeMetadata.java @@ -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(); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CleanupResources.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CleanupResources.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CleanupResources.java index 481f695..fb635aa 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CleanupResources.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CleanupResources.java @@ -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); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/AvailabilitySet.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/AvailabilitySet.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/AvailabilitySet.java index 624c664..4c4720e 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/AvailabilitySet.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/AvailabilitySet.java @@ -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 @@ -116,30 +157,44 @@ public abstract class AvailabilitySet { 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(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Image.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Image.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Image.java index 5d9226b..b442617 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Image.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/Image.java @@ -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(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageProperties.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageProperties.java index ef877be..44cb16e 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageProperties.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageProperties.java @@ -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(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageReference.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageReference.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageReference.java index 443e054..d9b43cd 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageReference.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ImageReference.java @@ -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); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ManagedDiskParameters.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ManagedDiskParameters.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ManagedDiskParameters.java index 84cbab1..a8a0ae3 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ManagedDiskParameters.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/ManagedDiskParameters.java @@ -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)); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java index c87fe75..20392a0 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java @@ -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(); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageAccountType.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageAccountType.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageAccountType.java new file mode 100644 index 0000000..33e1109 --- /dev/null +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageAccountType.java @@ -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; + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java index 04863ad..a01ed23 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java @@ -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); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ea62a4c3/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/AvailabilitySetApi.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/AvailabilitySetApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/AvailabilitySetApi.java index 30456d4..cf5116c 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/AvailabilitySetApi.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/AvailabilitySetApi.java @@ -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")
