http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/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 deleted file mode 100644 index cd5e0e9..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java +++ /dev/null @@ -1,545 +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; - -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.filter; -import static com.google.common.collect.Iterables.getOnlyElement; -import static com.google.common.collect.Iterables.transform; -import static com.google.common.collect.Lists.newArrayList; -import static org.jclouds.azurecompute.arm.compute.domain.LocationAndName.fromSlashEncoded; -import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName; -import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.getMarketplacePlanFromImageMetadata; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS; -import static org.jclouds.azurecompute.arm.domain.IdReference.extractName; -import static org.jclouds.azurecompute.arm.domain.IdReference.extractResourceGroup; -import static org.jclouds.azurecompute.arm.util.VMImages.isCustom; -import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Resource; -import javax.inject.Inject; -import javax.inject.Named; -import javax.inject.Singleton; - -import org.jclouds.azurecompute.arm.AzureComputeApi; -import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.PublicIpAvailablePredicateFactory; -import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; -import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage; -import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; -import org.jclouds.azurecompute.arm.compute.options.IpOptions; -import org.jclouds.azurecompute.arm.compute.strategy.CleanupResources; -import org.jclouds.azurecompute.arm.domain.AvailabilitySet; -import org.jclouds.azurecompute.arm.domain.CreationData; -import org.jclouds.azurecompute.arm.domain.DataDisk; -import org.jclouds.azurecompute.arm.domain.HardwareProfile; -import org.jclouds.azurecompute.arm.domain.IdReference; -import org.jclouds.azurecompute.arm.domain.ImageReference; -import org.jclouds.azurecompute.arm.domain.IpConfiguration; -import org.jclouds.azurecompute.arm.domain.IpConfigurationProperties; -import org.jclouds.azurecompute.arm.domain.Location; -import org.jclouds.azurecompute.arm.domain.ManagedDiskParameters; -import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard; -import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties; -import org.jclouds.azurecompute.arm.domain.NetworkProfile; -import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface; -import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface.NetworkInterfaceProperties; -import org.jclouds.azurecompute.arm.domain.OSDisk; -import org.jclouds.azurecompute.arm.domain.OSProfile; -import org.jclouds.azurecompute.arm.domain.Offer; -import org.jclouds.azurecompute.arm.domain.Plan; -import org.jclouds.azurecompute.arm.domain.Provisionable; -import org.jclouds.azurecompute.arm.domain.PublicIPAddress; -import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; -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.VMHardware; -import org.jclouds.azurecompute.arm.domain.VMImage; -import org.jclouds.azurecompute.arm.domain.VMSize; -import org.jclouds.azurecompute.arm.domain.Version; -import org.jclouds.azurecompute.arm.domain.VirtualMachine; -import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; -import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi; -import org.jclouds.azurecompute.arm.features.OSImageApi; -import org.jclouds.compute.ComputeServiceAdapter; -import org.jclouds.compute.domain.Image; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.functions.GroupNamingConvention; -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.location.Region; -import org.jclouds.logging.Logger; - -import com.google.common.base.Function; -import com.google.common.base.MoreObjects; -import com.google.common.base.Predicate; -import com.google.common.base.Splitter; -import com.google.common.base.Strings; -import com.google.common.base.Supplier; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -/** - * Defines the connection between the {@link AzureComputeApi} implementation and - * the jclouds {@link org.jclouds.compute.ComputeService}. - */ -@Singleton -public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location> { - - public static final String GROUP_KEY = "jclouds_group"; - public static final String AUTOGENERATED_IP_KEY = "jclouds-autogenerated"; - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final CleanupResources cleanupResources; - private final AzureComputeApi api; - private final List<String> imagePublishers; - private final Supplier<Set<String>> regionIds; - private final PublicIpAvailablePredicateFactory publicIpAvailable; - private final CustomImageToVMImage customImagetoVmImage; - private final GroupNamingConvention namingConvention; - private Predicate<Supplier<Provisionable>> resourceAvailable; - - @Inject - AzureComputeServiceAdapter(final AzureComputeApi api, @Named(IMAGE_PUBLISHERS) String imagePublishers, - CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds, - PublicIpAvailablePredicateFactory publicIpAvailable, CustomImageToVMImage customImagetoVmImage, - GroupNamingConvention.Factory namingConvention, Predicate<Supplier<Provisionable>> resourceAvailable) { - this.api = api; - this.imagePublishers = Splitter.on(',').trimResults().omitEmptyStrings().splitToList(imagePublishers); - this.cleanupResources = cleanupResources; - this.regionIds = regionIds; - this.publicIpAvailable = publicIpAvailable; - this.customImagetoVmImage = customImagetoVmImage; - this.namingConvention = namingConvention.create(); - this.resourceAvailable = resourceAvailable; - } - - @Override - public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(final String group, final String name, final Template template) { - String locationName = template.getLocation().getId(); - Image image = template.getImage(); - String hardwareId = fromSlashEncoded(template.getHardware().getId()).name(); - AzureTemplateOptions templateOptions = template.getOptions().as(AzureTemplateOptions.class); - String resourceGroupName = templateOptions.getResourceGroup(); - - IdReference availabilitySet = getAvailabilitySetIdReference(templateOptions.getAvailabilitySet()); - NetworkProfile networkProfile = createNetworkProfile(createNetworkInterfaceCards(name, locationName, - templateOptions)); - StorageProfile storageProfile = createStorageProfile(image, templateOptions.getDataDisks()); - HardwareProfile hardwareProfile = HardwareProfile.builder().vmSize(hardwareId).build(); - OSProfile osProfile = createOsProfile(name, template); - - VirtualMachineProperties virtualMachineProperties = VirtualMachineProperties.builder() - .availabilitySet(availabilitySet) - .hardwareProfile(hardwareProfile) - .storageProfile(storageProfile) - .osProfile(osProfile) - .networkProfile(networkProfile) - .build(); - - // Store group apart from the name to be able to identify nodes with - // custom names in the configured group - templateOptions.getUserMetadata().put(GROUP_KEY, group); - Map<String, String> metadataAndTags = metadataAndTagsAsCommaDelimitedValue(templateOptions); - Plan plan = getMarketplacePlanFromImageMetadata(image); - - VirtualMachine virtualMachine = api.getVirtualMachineApi(resourceGroupName).createOrUpdate(name, locationName, - virtualMachineProperties, metadataAndTags, plan); - - // Safe to pass null credentials here, as jclouds will default populate - // the node with the default credentials from the image, or the ones in - // the options, if provided. - ResourceGroupAndName resourceGroupAndName = fromResourceGroupAndName(resourceGroupName, name); - return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, resourceGroupAndName.slashEncode(), null); - } - - @Override - public Iterable<VMHardware> listHardwareProfiles() { - final List<VMHardware> hwProfiles = Lists.newArrayList(); - for (Location location : listLocations()) { - Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list(); - for (VMSize vmSize : vmSizes) { - VMHardware hwProfile = VMHardware - .create(vmSize.name(), vmSize.numberOfCores(), vmSize.osDiskSizeInMB(), - vmSize.resourceDiskSizeInMB(), vmSize.memoryInMB(), vmSize.maxDataDiskCount(), location.name()); - hwProfiles.add(hwProfile); - } - } - return hwProfiles; - } - - private List<VMImage> getImagesFromPublisher(String publisherName, String location) { - List<VMImage> osImagesRef = Lists.newArrayList(); - OSImageApi osImageApi = api.getOSImageApi(location); - Iterable<Offer> offerList = osImageApi.listOffers(publisherName); - - for (Offer offer : offerList) { - Iterable<SKU> skuList = osImageApi.listSKUs(publisherName, offer.name()); - - for (SKU sku : skuList) { - Iterable<Version> versionList = osImageApi.listVersions(publisherName, offer.name(), sku.name()); - for (Version version : versionList) { - Version versionDetails = osImageApi.getVersion(publisherName, offer.name(), sku.name(), version.name()); - VMImage vmImage = VMImage.azureImage().publisher(publisherName).offer(offer.name()).sku(sku.name()) - .version(versionDetails.name()).location(location).versionProperties(versionDetails.properties()) - .build(); - osImagesRef.add(vmImage); - } - } - } - return osImagesRef; - } - - private List<VMImage> listImagesByLocation(String location) { - final List<VMImage> osImages = Lists.newArrayList(); - for (String publisher : imagePublishers) { - osImages.addAll(getImagesFromPublisher(publisher, location)); - } - return osImages; - } - - private List<VMImage> listCustomImagesByResourceGroup(String resourceGroup) { - List<org.jclouds.azurecompute.arm.domain.Image> customImgs = api.getVirtualMachineImageApi(resourceGroup).list(); - return ImmutableList.copyOf(transform( - filter(customImgs, new Predicate<org.jclouds.azurecompute.arm.domain.Image>() { - @Override - public boolean apply(org.jclouds.azurecompute.arm.domain.Image input) { - return regionIds.get().contains(input.location()); - } - }), customImagetoVmImage)); - } - - @Override - public Iterable<VMImage> listImages() { - final ImmutableList.Builder<VMImage> osImages = ImmutableList.builder(); - - final List<String> availableLocationNames = newArrayList(transform(listLocations(), - new Function<Location, String>() { - @Override - public String apply(Location location) { - return location.name(); - } - })); - - for (String locationName : availableLocationNames) { - osImages.addAll(listImagesByLocation(locationName)); - } - - // We need to look for custom images in all resource groups - for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) { - osImages.addAll(listCustomImagesByResourceGroup(resourceGroup.name())); - } - - return osImages.build(); - } - - @Override - public VMImage getImage(final String id) { - VMImage image = VMImage.decodeFieldsFromUniqueId(id); - - if (image.custom()) { - org.jclouds.azurecompute.arm.domain.Image vmImage = api.getVirtualMachineImageApi(image.resourceGroup()).get( - image.name()); - return vmImage == null ? null : customImagetoVmImage.apply(vmImage); - } - - String location = image.location(); - String publisher = image.publisher(); - String offer = image.offer(); - String sku = image.sku(); - - OSImageApi osImageApi = api.getOSImageApi(location); - List<Version> versions = osImageApi.listVersions(publisher, offer, sku); - if (!versions.isEmpty()) { - Version version = osImageApi.getVersion(publisher, offer, sku, versions.get(0).name()); - return VMImage.azureImage().publisher(publisher).offer(offer).sku(sku).version(version.name()) - .location(location).versionProperties(version.properties()).build(); - } - - return null; - } - - @Override - public Iterable<Location> listLocations() { - final Iterable<String> vmLocations = FluentIterable.from(api.getResourceProviderApi().get("Microsoft.Compute")) - .filter(new Predicate<ResourceProviderMetaData>() { - @Override - public boolean apply(ResourceProviderMetaData input) { - return input.resourceType().equals("virtualMachines"); - } - }).transformAndConcat(new Function<ResourceProviderMetaData, Iterable<String>>() { - @Override - public Iterable<String> apply(ResourceProviderMetaData resourceProviderMetaData) { - return resourceProviderMetaData.locations(); - } - }); - - List<Location> locations = FluentIterable.from(api.getLocationApi().list()).filter(new Predicate<Location>() { - @Override - public boolean apply(Location location) { - return Iterables.contains(vmLocations, location.displayName()); - } - }).filter(new Predicate<Location>() { - @Override - public boolean apply(Location location) { - return regionIds.get().isEmpty() ? true : regionIds.get().contains(location.name()); - } - }).toList(); - - return locations; - } - - @Override - public VirtualMachine getNode(final String id) { - ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); - return api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).get(resourceGroupAndName.name()); - } - - @Override - public void destroyNode(final String id) { - checkState(cleanupResources.cleanupNode(id), "server(%s) and its resources still there after deleting!?", id); - } - - @Override - public void rebootNode(final String id) { - ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); - api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).restart(resourceGroupAndName.name()); - } - - @Override - public void resumeNode(final String id) { - ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); - api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).start(resourceGroupAndName.name()); - } - - @Override - public void suspendNode(final String id) { - ResourceGroupAndName resourceGroupAndName = ResourceGroupAndName.fromSlashEncoded(id); - api.getVirtualMachineApi(resourceGroupAndName.resourceGroup()).stop(resourceGroupAndName.name()); - } - - @Override - public Iterable<VirtualMachine> listNodes() { - ImmutableList.Builder<VirtualMachine> nodes = builder(); - for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) { - List<VirtualMachine> vms = api.getVirtualMachineApi(resourceGroup.name()).list(); - nodes.addAll(filter(vms, new Predicate<VirtualMachine>() { - @Override - public boolean apply(VirtualMachine input) { - return regionIds.get().contains(input.location()); - } - })); - } - return nodes.build(); - } - - @Override - public Iterable<VirtualMachine> listNodesByIds(final Iterable<String> ids) { - return transform(ids, new Function<String, VirtualMachine>() { - @Override - public VirtualMachine apply(String input) { - return getNode(input); - } - }); - } - - private OSProfile createOsProfile(String computerName, Template template) { - String defaultLoginUser = template.getImage().getDefaultCredentials().getUser(); - String adminUsername = MoreObjects.firstNonNull(template.getOptions().getLoginUser(), defaultLoginUser); - // Password already generated in CreateResourcesThenCreateNodes (if not set by user) - String adminPassword = template.getOptions().getLoginPassword(); - OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).adminPassword(adminPassword) - .computerName(computerName); - - if (!Strings.isNullOrEmpty(template.getOptions().getPublicKey()) - && OsFamily.WINDOWS != template.getImage().getOperatingSystem().getFamily()) { - OSProfile.LinuxConfiguration linuxConfiguration = OSProfile.LinuxConfiguration.create("true", - OSProfile.LinuxConfiguration.SSH.create(of( - OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create( - String.format("/home/%s/.ssh/authorized_keys", adminUsername), - template.getOptions().getPublicKey())))); - builder.linuxConfiguration(linuxConfiguration); - } - - AzureTemplateOptions azureTemplateOptions = template.getOptions().as(AzureTemplateOptions.class); - - if (azureTemplateOptions.getWindowsConfiguration() != null) { - builder.windowsConfiguration(azureTemplateOptions.getWindowsConfiguration()); - } - - if (azureTemplateOptions.getSecrets() != null) { - builder.secrets(azureTemplateOptions.getSecrets()); - } - - if (!Strings.isNullOrEmpty(azureTemplateOptions.getCustomData())) { - builder.customData(azureTemplateOptions.getCustomData()); - } - - return builder.build(); - } - - private List<NetworkInterfaceCard> createNetworkInterfaceCards(final String nodeName, final String location, - AzureTemplateOptions options) { - // Prefer a sorted list of NICs with the ones with public IPs first, to - // make sure the primary NIC is the public one - final String securityGroup = getOnlyElement(options.getGroups(), null); - return Lists.transform(publicIpsFirst(options.getIpOptions()), new Function<IpOptions, NetworkInterfaceCard>() { - @Override - public NetworkInterfaceCard apply(IpOptions input) { - return createNetworkInterfaceCard(input, nodeName, location, securityGroup); - } - }); - } - - private NetworkInterfaceCard createNetworkInterfaceCard(IpOptions ipConfig, String nodeName, String location, - String securityGroup) { - String resourceGroup = extractResourceGroup(ipConfig.subnet()); - String subnetName = extractName(ipConfig.subnet()); - - IpConfigurationProperties.Builder ipProperties = IpConfigurationProperties.builder() - .subnet(IdReference.create(ipConfig.subnet())) - .privateIPAllocationMethod(ipConfig.address().isPresent() ? "Static" : "Dynamic") - .privateIPAddress(ipConfig.address().orNull()); - - configurePublicIP(ipConfig, ipProperties, resourceGroup, location, nodeName); - - String ipName = namingConvention.uniqueNameForGroup(subnetName); - final String nicName = namingConvention.uniqueNameForGroup(subnetName); - - IpConfiguration config = IpConfiguration.builder().name(ipName).properties(ipProperties.build()).build(); - - NetworkInterfaceCardProperties.Builder nicProperties = NetworkInterfaceCardProperties.builder().ipConfigurations( - ImmutableList.of(config)); - - if (securityGroup != null) { - nicProperties.networkSecurityGroup(IdReference.create(securityGroup)); - } - - logger.debug(">> creating nic %s(%s) with security groups (%s)", nicName, config, - securityGroup != null ? securityGroup : ""); - - final NetworkInterfaceCardApi nicApi = api.getNetworkInterfaceCardApi(resourceGroup); - NetworkInterfaceCard nic = nicApi.createOrUpdate(nicName, location, nicProperties.build(), - ImmutableMap.of("jclouds", nodeName)); - - resourceAvailable.apply(new Supplier<Provisionable>() { - @Override - public Provisionable get() { - NetworkInterfaceCard updated = nicApi.get(nicName); - return updated == null ? null : updated.properties(); - } - }); - - return nic; - } - - private void configurePublicIP(IpOptions ipConfig, IpConfigurationProperties.Builder ipProperties, - String resourceGroup, String location, String nodeName) { - if (ipConfig.publicIpId() != null) { - logger.debug(">> configuring public ip: %s", extractName(ipConfig.publicIpId())); - PublicIPAddress publicIp = api.getPublicIPAddressApi(extractResourceGroup(ipConfig.publicIpId())).get( - extractName(ipConfig.publicIpId())); - ipProperties.publicIPAddress(IdReference.create(publicIp.id())); - } else if (ipConfig.allocateNewPublicIp()) { - PublicIPAddress publicIp = createPublicIp(resourceGroup, location, nodeName); - ipProperties.publicIPAddress(IdReference.create(publicIp.id())); - } - } - - /** - * Create the network profile and configure the first NIC as primary. - */ - private NetworkProfile createNetworkProfile(List<NetworkInterfaceCard> nics) { - List<NetworkInterface> nicAttachments = new ArrayList<NetworkInterface>(nics.size()); - for (int i = 0; i < nics.size(); i++) { - nicAttachments.add(NetworkInterface.create(nics.get(i).id(), NetworkInterfaceProperties.create(i == 0))); - } - return NetworkProfile.create(nicAttachments); - } - - private static List<IpOptions> publicIpsFirst(List<IpOptions> ipOptions) { - List<IpOptions> sorted = new ArrayList<IpOptions>(ipOptions); - Collections.sort(sorted, new Comparator<IpOptions>() { - @Override - public int compare(IpOptions o1, IpOptions o2) { - return o1.allocateNewPublicIp() == o2.allocateNewPublicIp() ? 0 : o1.allocateNewPublicIp() ? -1 : 1; - } - }); - return sorted; - } - - private PublicIPAddress createPublicIp(String resourceGroup, String location, String nodeName) { - String name = namingConvention.uniqueNameForGroup(nodeName); - - PublicIPAddressProperties properties = PublicIPAddressProperties.builder() - .publicIPAllocationMethod("Static") - .idleTimeoutInMinutes(4) - .build(); - - logger.debug(">> allocating new public ip address: %s", name); - - PublicIPAddress ip = api.getPublicIPAddressApi(resourceGroup).createOrUpdate(name, location, - ImmutableMap.of("jclouds", nodeName, AUTOGENERATED_IP_KEY, "true"), properties); - - checkState(publicIpAvailable.create(resourceGroup).apply(name), - "Public IP was not provisioned in the configured timeout"); - - return ip; - } - - private StorageProfile createStorageProfile(Image image, List<DataDisk> dataDisks) { - return StorageProfile.create(createImageReference(image), createOSDisk(image), dataDisks); - } - - private ImageReference createImageReference(Image image) { - 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) { - OsFamily osFamily = image.getOperatingSystem().getFamily(); - String osType = osFamily == OsFamily.WINDOWS ? "Windows" : "Linux"; - return OSDisk.builder() - .osType(osType) - .caching(DataDisk.CachingTypes.READ_WRITE.toString()) - .createOption(CreationData.CreateOptions.FROM_IMAGE.toString()) - .managedDiskParameters(ManagedDiskParameters.create(null, StorageAccountType.STANDARD_LRS.toString())) - .build(); - } - - private IdReference getAvailabilitySetIdReference(AvailabilitySet availabilitySet) { - return availabilitySet != null ? IdReference.create(availabilitySet.id()) : null; - } -}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/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 deleted file mode 100644 index 0a81ecb..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java +++ /dev/null @@ -1,134 +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.config; - -import javax.inject.Singleton; - -import org.jclouds.azurecompute.arm.compute.AzureComputeService; -import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter; -import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndNameAndIngressRules; -import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension; -import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeSecurityGroupExtension; -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.VMHardwareToHardware; -import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage; -import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToNodeMetadata; -import org.jclouds.azurecompute.arm.compute.loaders.CreateSecurityGroupIfNeeded; -import org.jclouds.azurecompute.arm.compute.loaders.DefaultResourceGroup; -import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; -import org.jclouds.azurecompute.arm.compute.strategy.CreateResourcesThenCreateNodes; -import org.jclouds.azurecompute.arm.domain.Location; -import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup; -import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule; -import org.jclouds.azurecompute.arm.domain.ResourceGroup; -import org.jclouds.azurecompute.arm.domain.VMHardware; -import org.jclouds.azurecompute.arm.domain.VMImage; -import org.jclouds.azurecompute.arm.domain.VirtualMachine; -import org.jclouds.compute.ComputeService; -import org.jclouds.compute.ComputeServiceAdapter; -import org.jclouds.compute.config.ComputeServiceAdapterContextModule; -import org.jclouds.compute.domain.Hardware; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.SecurityGroup; -import org.jclouds.compute.extensions.ImageExtension; -import org.jclouds.compute.extensions.SecurityGroupExtension; -import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatement; -import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatementWithoutPublicKey; -import org.jclouds.compute.options.TemplateOptions; -import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet; -import org.jclouds.net.domain.IpPermission; -import org.jclouds.util.PasswordGenerator; - -import com.google.common.base.Function; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; -import com.google.inject.Provides; -import com.google.inject.TypeLiteral; - -public class AzureComputeServiceContextModule extends - ComputeServiceAdapterContextModule<VirtualMachine, VMHardware, VMImage, Location> { - - @Override - protected void configure() { - super.configure(); - - bind(new TypeLiteral<ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location>>() { - }).to(AzureComputeServiceAdapter.class); - - bind(new TypeLiteral<Function<VMImage, org.jclouds.compute.domain.Image>>() { - }).to(VMImageToImage.class); - bind(new TypeLiteral<Function<VMHardware, Hardware>>() { - }).to(VMHardwareToHardware.class); - bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() { - }).to(VirtualMachineToNodeMetadata.class); - bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() { - }).to(LocationToLocation.class); - bind(new TypeLiteral<Function<NetworkSecurityGroup, SecurityGroup>>() { - }).to(NetworkSecurityGroupToSecurityGroup.class); - bind(new TypeLiteral<Function<NetworkSecurityRule, IpPermission>>() { - }).to(NetworkSecurityRuleToIpPermission.class); - bind(ComputeService.class).to(AzureComputeService.class); - - install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, VMHardware, VMImage, Location>() { - }); - - bind(TemplateOptions.class).to(AzureTemplateOptions.class); - bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class); - bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourcesThenCreateNodes.class); - - bind(new TypeLiteral<CacheLoader<ResourceGroupAndNameAndIngressRules, String>>() { - }).to(CreateSecurityGroupIfNeeded.class); - bind(new TypeLiteral<CacheLoader<String, ResourceGroup>>() { - }).to(DefaultResourceGroup.class); - - bind(new TypeLiteral<ImageExtension>() { - }).to(AzureComputeImageExtension.class); - bind(new TypeLiteral<SecurityGroupExtension>() { - }).to(AzureComputeSecurityGroupExtension.class); - } - - @Provides - @Singleton - protected PasswordGenerator.Config providePasswordGenerator() { - // Guest passwords must be between 6-72 characters long. - // Must contain an upper case character. - // Must contain a lower case character. - // Must contain a numeric digit. - // Must contain a special character. Control characters are not allowed. - return new PasswordGenerator() - .lower().min(2).max(10) - .upper().min(2).max(10) - .numbers().min(2).max(10) - .symbols().min(2).max(10); - } - - @Provides - @Singleton - protected final LoadingCache<ResourceGroupAndNameAndIngressRules, String> securityGroupMap( - CacheLoader<ResourceGroupAndNameAndIngressRules, String> in) { - return CacheBuilder.newBuilder().build(in); - } - - @Provides - @Singleton - protected final LoadingCache<String, ResourceGroup> defaultResourceGroup(CacheLoader<String, ResourceGroup> in) { - return CacheBuilder.newBuilder().build(in); - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java deleted file mode 100644 index c8dfd6e..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java +++ /dev/null @@ -1,602 +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.config; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Predicate; -import com.google.common.base.Supplier; -import com.google.common.collect.Iterables; -import com.google.inject.AbstractModule; -import com.google.inject.Provides; -import com.google.inject.name.Named; - -import org.jclouds.compute.reference.ComputeServiceConstants; -import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod; - -import org.jclouds.azurecompute.arm.domain.Image; -import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup; -import org.jclouds.azurecompute.arm.domain.Provisionable; -import org.jclouds.azurecompute.arm.domain.PublicIPAddress; -import org.jclouds.azurecompute.arm.domain.ResourceDefinition; -import org.jclouds.azurecompute.arm.domain.Vault; -import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance; -import org.jclouds.azurecompute.arm.functions.ParseJobStatus; -import org.jclouds.azurecompute.arm.AzureComputeApi; -import org.jclouds.azurecompute.arm.domain.Key.DeletedKeyBundle; -import org.jclouds.azurecompute.arm.domain.Key.KeyBundle; -import org.jclouds.azurecompute.arm.domain.Secret.DeletedSecretBundle; -import org.jclouds.azurecompute.arm.domain.Secret.SecretBundle; -import org.jclouds.azurecompute.arm.domain.Certificate.DeletedCertificateBundle; -import org.jclouds.azurecompute.arm.domain.Certificate.CertificateBundle; -import org.jclouds.azurecompute.arm.domain.Certificate.CertificateOperation; - -import java.net.URI; -import java.util.List; - -import static org.jclouds.util.Predicates2.retry; -import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; -import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; -import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; -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.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_DELETE_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_KEY_DELETED_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_KEY_RECOVERABLE_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_SECRET_DELETE_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_SECRET_RECOVERABLE_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_DELETE_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_RECOVERABLE_STATUS; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_OPERATION_STATUS; - -import static com.google.common.base.Preconditions.checkNotNull; - -public class AzurePredicatesModule extends AbstractModule { - protected void configure() { - } - - @Provides - @Named(TIMEOUT_NODE_RUNNING) - protected VirtualMachineInStatePredicateFactory provideVirtualMachineRunningPredicate(final AzureComputeApi api, - final ComputeServiceConstants.Timeouts timeouts, final PollPeriod pollPeriod) { - return new VirtualMachineInStatePredicateFactory(api, VirtualMachineInstance.PowerState.RUNNING, timeouts.nodeRunning, - pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(TIMEOUT_NODE_TERMINATED) - protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, final ComputeServiceConstants.Timeouts timeouts, - final PollPeriod pollPeriod) { - return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod, - pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(TIMEOUT_IMAGE_AVAILABLE) - protected Predicate<URI> provideImageCapturedPredicate(final AzureComputeApi api, final ComputeServiceConstants.Timeouts timeouts, - final PollPeriod pollPeriod) { - return retry(new ImageCapturedPredicate(api), timeouts.imageAvailable, pollPeriod.pollInitialPeriod, - pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(TIMEOUT_RESOURCE_DELETED) - protected Predicate<URI> provideResourceDeletedPredicate(final AzureComputeApi api, final ComputeServiceConstants.Timeouts timeouts, - final PollPeriod pollPeriod) { - return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod, - pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(TIMEOUT_NODE_SUSPENDED) - protected VirtualMachineInStatePredicateFactory provideNodeSuspendedPredicate(final AzureComputeApi api, - final ComputeServiceConstants.Timeouts timeouts, final PollPeriod pollPeriod) { - return new VirtualMachineInStatePredicateFactory(api, VirtualMachineInstance.PowerState.STOPPED, timeouts.nodeTerminated, - pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - @Provides - protected PublicIpAvailablePredicateFactory providePublicIpAvailablePredicate(final AzureComputeApi api, - Predicate<Supplier<Provisionable>> resourceAvailable) { - return new PublicIpAvailablePredicateFactory(api, resourceAvailable); - } - - @Provides - protected SecurityGroupAvailablePredicateFactory provideSecurityGroupAvailablePredicate(final AzureComputeApi api, - Predicate<Supplier<Provisionable>> resourceAvailable) { - return new SecurityGroupAvailablePredicateFactory(api, resourceAvailable); - } - - @Provides - protected ImageAvailablePredicateFactory provideImageAvailablePredicate(final AzureComputeApi api, - Predicate<Supplier<Provisionable>> resourceAvailable, final ComputeServiceConstants.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, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, PollPeriod pollPeriod) { - return retry(new ResourceInStatusPredicate("Succeeded"), operationTimeout, pollPeriod.pollInitialPeriod, - pollPeriod.pollMaxPeriod); - } - - @VisibleForTesting - static class ActionDonePredicate implements Predicate<URI> { - - private final AzureComputeApi api; - - public ActionDonePredicate(final AzureComputeApi api) { - this.api = checkNotNull(api, "api must not be null"); - } - - @Override - public boolean apply(final URI uri) { - checkNotNull(uri, "uri cannot be null"); - return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri) - || ParseJobStatus.JobStatus.NO_CONTENT == api.getJobApi().jobStatus(uri); - } - } - - @VisibleForTesting - static class ImageCapturedPredicate implements Predicate<URI> { - - private final AzureComputeApi api; - - public ImageCapturedPredicate(final AzureComputeApi api) { - this.api = checkNotNull(api, "api must not be null"); - } - - @Override - public boolean apply(final URI uri) { - checkNotNull(uri, "uri cannot be null"); - if (api.getJobApi().jobStatus(uri) != ParseJobStatus.JobStatus.DONE) { - return false; - } - List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri); - return definitions != null; - } - } - - public static class VirtualMachineInStatePredicateFactory { - - private final AzureComputeApi api; - private final VirtualMachineInstance.PowerState powerState; - private final long timeout; - private final long period; - private final long maxPeriod; - - VirtualMachineInStatePredicateFactory(final AzureComputeApi api, final VirtualMachineInstance.PowerState powerState, final long timeout, - final long period, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.powerState = checkNotNull(powerState, "powerState cannot be null"); - this.timeout = timeout; - this.period = period; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String azureGroup) { - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - VirtualMachineInstance vmInstance = api.getVirtualMachineApi(azureGroup).getInstanceDetails(name); - if (vmInstance == null) { - return false; - } - return powerState == vmInstance.powerState(); - } - }, timeout, period, maxPeriod); - } - } - - public static class ResourceInStatusPredicate implements Predicate<Supplier<Provisionable>> { - private final String expectedStatus; - - ResourceInStatusPredicate(String expectedStatus) { - this.expectedStatus = checkNotNull(expectedStatus, "expectedStatus cannot be null"); - } - - @Override - public boolean apply(Supplier<Provisionable> provisionableSupplier) { - checkNotNull(provisionableSupplier, "provisionableSupplier supplier cannot be null"); - Provisionable provisionable = provisionableSupplier.get(); - return provisionable != null && provisionable.provisioningState().equalsIgnoreCase(expectedStatus); - } - } - - public static class PublicIpAvailablePredicateFactory { - private final AzureComputeApi api; - private final Predicate<Supplier<Provisionable>> resourceAvailable; - - PublicIpAvailablePredicateFactory(final AzureComputeApi api, Predicate<Supplier<Provisionable>> resourceAvailable) { - this.api = checkNotNull(api, "api cannot be null"); - this.resourceAvailable = resourceAvailable; - } - - public Predicate<String> create(final String azureGroup) { - checkNotNull(azureGroup, "azureGroup 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() { - PublicIPAddress publicIp = api.getPublicIPAddressApi(azureGroup).get(name); - return publicIp == null ? null : publicIp.properties(); - } - }); - } - }; - } - } - - public static class SecurityGroupAvailablePredicateFactory { - private final AzureComputeApi api; - private final Predicate<Supplier<Provisionable>> resourceAvailable; - - SecurityGroupAvailablePredicateFactory(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() { - NetworkSecurityGroup sg = api.getNetworkSecurityGroupApi(resourceGroup).get(name); - return sg == null ? null : sg.properties(); - } - }); - } - }; - } - } - - 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(); - } - }); - } - }; - } - } - - @Provides - @Named(VAULT_DELETE_STATUS) - protected VaultPredicates.DeletedVaultStatusPredicateFactory provideDeletedVaultStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultPredicates.DeletedVaultStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - public static class VaultPredicates { - public static class DeletedVaultStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - DeletedVaultStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final boolean shouldBePresent) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - boolean present = false; - List<Vault.DeletedVault> vaults = api.getVaultApi(resourceGroup).listDeletedVaults(); - return shouldBePresent == Iterables.any(vaults, new Predicate<Vault.DeletedVault>() { - @Override public boolean apply(Vault.DeletedVault input) { - return input.name().equals(name); - } - }); - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - } - - @Provides - @Named(VAULT_KEY_DELETED_STATUS) - protected VaultKeyPredicates.DeletedKeyStatusPredicateFactory provideDeletedKeyStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultKeyPredicates.DeletedKeyStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(VAULT_KEY_RECOVERABLE_STATUS) - protected VaultKeyPredicates.RecoverableKeyStatusPredicateFactory provideRecoverableKeyStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultKeyPredicates.RecoverableKeyStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - public static class VaultKeyPredicates { - public static class DeletedKeyStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - DeletedKeyStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean shouldBePresent) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - boolean present = false; - DeletedKeyBundle key = api.getVaultApi(resourceGroup).getDeletedKey(vaultUri, name); - return shouldBePresent == (key != null); - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - - public static class RecoverableKeyStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - RecoverableKeyStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isRecovered) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - boolean result = false; - KeyBundle key = api.getVaultApi(resourceGroup).getKey(vaultUri, name); - return key != null ? (isRecovered ? true : key.attributes().recoveryLevel().contains("Recoverable")) : false; - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - } - - @Provides - @Named(VAULT_SECRET_DELETE_STATUS) - protected VaultSecretPredicates.DeletedSecretStatusPredicateFactory provideDeletedSecretStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultSecretPredicates.DeletedSecretStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(VAULT_SECRET_RECOVERABLE_STATUS) - protected VaultSecretPredicates.RecoverableSecretStatusPredicateFactory provideRecoverableSecretStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultSecretPredicates.RecoverableSecretStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - public static class VaultSecretPredicates { - public static class DeletedSecretStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - DeletedSecretStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean shouldBePresent) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - boolean present = false; - checkNotNull(name, "name cannot be null"); - DeletedSecretBundle secret = api.getVaultApi(resourceGroup).getDeletedSecret(vaultUri, name); - return shouldBePresent == (secret != null); - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - - public static class RecoverableSecretStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - RecoverableSecretStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isRecovered) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - SecretBundle secret = api.getVaultApi(resourceGroup).getSecret(vaultUri, name, null); - return secret != null ? (isRecovered ? true : secret.attributes().recoveryLevel().contains("Recoverable")) : false; - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - } - - @Provides - @Named(VAULT_CERTIFICATE_DELETE_STATUS) - protected VaultCertificatePredicates.DeletedCertificateStatusPredicateFactory provideDeletedCertificateStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultCertificatePredicates.DeletedCertificateStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(VAULT_CERTIFICATE_RECOVERABLE_STATUS) - protected VaultCertificatePredicates.RecoverableCertificateStatusPredicateFactory provideRecoverableCertificateStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultCertificatePredicates.RecoverableCertificateStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - @Provides - @Named(VAULT_CERTIFICATE_OPERATION_STATUS) - protected VaultCertificatePredicates.CertificateOperationStatusPredicateFactory provideCertificateOperationStatusPredicateFactory(final AzureComputeApi api, - @Named(OPERATION_TIMEOUT) Integer operationTimeout, - final PollPeriod pollPeriod) { - return new VaultCertificatePredicates.CertificateOperationStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod); - } - - public static class VaultCertificatePredicates { - public static class DeletedCertificateStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - DeletedCertificateStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean shouldBePresent) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - boolean present = false; - checkNotNull(name, "name cannot be null"); - DeletedCertificateBundle cert = api.getVaultApi(resourceGroup).getDeletedCertificate(vaultUri, name); - return shouldBePresent == (cert != null); - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - - public static class RecoverableCertificateStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - RecoverableCertificateStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isImport) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - CertificateBundle cert = api.getVaultApi(resourceGroup).getCertificate(vaultUri, name, null); - return cert != null ? (isImport ? true : cert.attributes().recoveryLevel().contains("Recoverable")) : false; - - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - - public static class CertificateOperationStatusPredicateFactory { - private final AzureComputeApi api; - private final long operationTimeout; - private final long initialPeriod; - private final long maxPeriod; - - CertificateOperationStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) { - this.api = checkNotNull(api, "api cannot be null"); - this.operationTimeout = operationTimeout; - this.initialPeriod = initialPeriod; - this.maxPeriod = maxPeriod; - } - - public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isCreate) { - checkNotNull(resourceGroup, "resourceGroup cannot be null"); - checkNotNull(vaultUri, "vaultUri cannot be null"); - return retry(new Predicate<String>() { - @Override - public boolean apply(final String name) { - checkNotNull(name, "name cannot be null"); - boolean result = false; - CertificateOperation certOp = api.getVaultApi(resourceGroup).getCertificateOperation(vaultUri, name); - return isCreate ? ((certOp != null) ? !certOp.status().equals("inProgress") : false) : (certOp == null); - } - }, operationTimeout, initialPeriod, maxPeriod); - } - } - } -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java deleted file mode 100644 index 0142448..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/LocationAndName.java +++ /dev/null @@ -1,50 +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.domain; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.auto.value.AutoValue; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - -@AutoValue -public abstract class LocationAndName { - - public abstract String location(); - public abstract String name(); - - protected LocationAndName() { - - } - - public static LocationAndName fromSlashEncoded(String id) { - Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id")); - checkArgument(Iterables.size(parts) == 2, "id must be in format location/name"); - return new AutoValue_LocationAndName(Iterables.get(parts, 0), Iterables.get(parts, 1)); - } - - public static LocationAndName fromLocationAndName(String location, String name) { - return new AutoValue_LocationAndName(location, name); - } - - public String slashEncode() { - return location() + "/" + name(); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java deleted file mode 100644 index c06056e..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndName.java +++ /dev/null @@ -1,50 +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.domain; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.auto.value.AutoValue; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - -@AutoValue -public abstract class ResourceGroupAndName { - - public abstract String resourceGroup(); - public abstract String name(); - - protected ResourceGroupAndName() { - - } - - public static ResourceGroupAndName fromSlashEncoded(String id) { - Iterable<String> parts = Splitter.on('/').split(checkNotNull(id, "id")); - checkArgument(Iterables.size(parts) == 2, "id must be in format resourcegroup/name"); - return new AutoValue_ResourceGroupAndName(Iterables.get(parts, 0), Iterables.get(parts, 1)); - } - - public static ResourceGroupAndName fromResourceGroupAndName(String resourceGroup, String name) { - return new AutoValue_ResourceGroupAndName(resourceGroup, name); - } - - public String slashEncode() { - return resourceGroup() + "/" + name(); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java deleted file mode 100644 index 7c11642..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java +++ /dev/null @@ -1,74 +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.domain; - -import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName; - -import java.util.Arrays; - -import com.google.auto.value.AutoValue; -import com.google.common.base.Objects; - -@AutoValue -public abstract class ResourceGroupAndNameAndIngressRules { - - abstract ResourceGroupAndName resourceGroupAndName(); // Intentionally hidden - - public abstract String location(); - - @SuppressWarnings("mutable") - public abstract int[] inboundPorts(); - - ResourceGroupAndNameAndIngressRules() { - - } - - public static ResourceGroupAndNameAndIngressRules create(String resourceGroup, String location, String name, - int[] inboundPorts) { - return new AutoValue_ResourceGroupAndNameAndIngressRules(fromResourceGroupAndName(resourceGroup, name), location, - Arrays.copyOf(inboundPorts, inboundPorts.length)); - } - - public String name() { - return resourceGroupAndName().name(); - } - - public String resourceGroup() { - return resourceGroupAndName().resourceGroup(); - } - - // Intentionally delegate equals and hashcode to the fields in the parent - // class so that we can search only by region/id in a map - - @Override - public int hashCode() { - return Objects.hashCode(resourceGroup(), name()); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ResourceGroupAndName)) { - return false; - } - ResourceGroupAndName that = (ResourceGroupAndName) obj; - return Objects.equal(resourceGroup(), that.resourceGroup()) && Objects.equal(name(), that.name()); - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/ac03bac4/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 deleted file mode 100644 index 6cba2c4..0000000 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java +++ /dev/null @@ -1,134 +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.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.domain.ResourceGroupAndName.fromSlashEncoded; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED; -import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; - -import java.net.URI; -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.AzurePredicatesModule.ImageAvailablePredicateFactory; -import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.VirtualMachineInStatePredicateFactory; -import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName; -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.VMImage; -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; -import org.jclouds.compute.domain.ImageTemplateBuilder; -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.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.ListeningExecutorService; -import com.google.inject.Inject; -import com.google.inject.name.Named; - -public class AzureComputeImageExtension implements ImageExtension { - public static final String CUSTOM_IMAGE_OFFER = "custom"; - - @Resource - @Named(ComputeServiceConstants.COMPUTE_LOGGER) - protected Logger logger = Logger.NULL; - - private final AzureComputeApi api; - private final ListeningExecutorService userExecutor; - private final ImageAvailablePredicateFactory imageAvailablePredicate; - private final VirtualMachineInStatePredicateFactory nodeSuspendedPredicate; - private final Function<VMImage, Image> vmImageToImage; - private final Predicate<URI> resourceDeleted; - private final CustomImageToVMImage customImagetoVmImage; - - @Inject - AzureComputeImageExtension(AzureComputeApi api, ImageAvailablePredicateFactory imageAvailablePredicate, - @Named(TIMEOUT_NODE_SUSPENDED) VirtualMachineInStatePredicateFactory nodeSuspendedPredicate, - @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor, - Function<VMImage, Image> vmImageToImage, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted, - CustomImageToVMImage customImagetoVmImage) { - this.api = api; - this.imageAvailablePredicate = imageAvailablePredicate; - this.nodeSuspendedPredicate = nodeSuspendedPredicate; - this.userExecutor = userExecutor; - this.vmImageToImage = vmImageToImage; - this.resourceDeleted = resourceDeleted; - this.customImagetoVmImage = customImagetoVmImage; - } - - @Override - public ImageTemplate buildImageTemplateFromNode(String name, String id) { - return new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name.toLowerCase()).build(); - } - - @Override - public ListenableFuture<Image> createImage(ImageTemplate template) { - final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template; - final ResourceGroupAndName resourceGroupAndName = fromSlashEncoded(cloneTemplate.getSourceNodeId()); - final String resourceGroupName = resourceGroupAndName.resourceGroup(); - final String vmName = resourceGroupAndName.name(); - - final VirtualMachine vm = api.getVirtualMachineApi(resourceGroupName).get(vmName); - final IdReference vmIdRef = IdReference.create(vm.id()); - - logger.debug(">> stopping node %s...", cloneTemplate.getSourceNodeId()); - api.getVirtualMachineApi(resourceGroupName).stop(vmName); - checkState(nodeSuspendedPredicate.create(resourceGroupName).apply(vmName), - "Node %s was not suspended within the configured time limit", cloneTemplate.getSourceNodeId()); - - return userExecutor.submit(new Callable<Image>() { - @Override - public Image call() throws Exception { - logger.debug(">> generalizing virtal machine %s...", vmName); - - api.getVirtualMachineApi(resourceGroupName).generalize(vmName); - - org.jclouds.azurecompute.arm.domain.Image imageFromVM = api.getVirtualMachineImageApi(resourceGroupName) - .createOrUpdate(cloneTemplate.getName(), vm.location(), - 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()); - - return compose(vmImageToImage, customImagetoVmImage).apply(imageFromVM); - } - }); - } - - @Override - public boolean deleteImage(String id) { - VMImage image = VMImage.decodeFieldsFromUniqueId(id); - checkArgument(image.custom(), "Only custom images can be deleted"); - - logger.debug(">> deleting image %s", id); - URI uri = api.getVirtualMachineImageApi(image.resourceGroup()).delete(image.name()); - return resourceDeleted.apply(uri); - } -}
