http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VirtualMachineApi.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VirtualMachineApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VirtualMachineApi.java index 4689064..14f3c70 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VirtualMachineApi.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/VirtualMachineApi.java @@ -131,5 +131,30 @@ public interface VirtualMachineApi { @Path("/{name}/powerOff") void stop(@PathParam("name") String name); + /** + * Generalize the virtual machine + */ + @Named("generalize") + @POST + @Path("/{name}/generalize") + void generalize(@PathParam("name") String name); + + /** + * Capture the virtual machine image + * destinationContainerName: the name of the folder created under the "system" container in the storage account + * Folder structure: Microsoft.Computer > Images > destinationContainerName + * Within the folder, there will be 1 page blob for the osDisk vhd and 1 block blob for the vmTemplate json file + */ + @Named("capture") + @POST + @Payload("%7B\"vhdPrefix\":\"{vhdPrefix}\",\"destinationContainerName\":\"{destinationContainerName}\",\"overwriteVhds\":\"true\"%7D") + @MapBinder(BindToJsonPayload.class) + @Path("/{name}/capture") + @ResponseParser(URIParser.class) + @Fallback(Fallbacks.NullOnNotFoundOr404.class) + URI capture(@PathParam("name") String name, + @PayloadParam("vhdPrefix") String vhdPrefix, + @PayloadParam("destinationContainerName") String destinationContainerName); + }
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java index 2b6a18e..1646aec 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/CleanupResources.java @@ -26,8 +26,15 @@ import javax.inject.Singleton; import com.google.common.base.Predicate; import org.jclouds.azurecompute.arm.AzureComputeApi; +import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule; +import org.jclouds.azurecompute.arm.domain.Deployment; +import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard; +import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup; +import org.jclouds.azurecompute.arm.domain.PublicIPAddress; +import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.compute.reference.ComputeServiceConstants; import org.jclouds.logging.Logger; +import org.jclouds.azurecompute.arm.domain.StorageService; import com.google.common.base.Function; @@ -36,6 +43,7 @@ import java.net.URI; @Singleton public class CleanupResources implements Function<String, Boolean> { + private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants; @Resource @Named(ComputeServiceConstants.COMPUTE_LOGGER) protected Logger logger = Logger.NULL; @@ -46,9 +54,10 @@ public class CleanupResources implements Function<String, Boolean> { @Inject public CleanupResources(AzureComputeApi azureComputeApi, + AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, @Named(TIMEOUT_NODE_TERMINATED) Predicate<URI> nodeTerminated, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted) { - + this.azureComputeConstants = azureComputeConstants; this.api = azureComputeApi; this.nodeTerminated = nodeTerminated; this.resourceDeleted = resourceDeleted; @@ -58,36 +67,67 @@ public class CleanupResources implements Function<String, Boolean> { public Boolean apply(String id) { logger.debug("Destroying %s ...", id); - String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "storage"; - int index = id.lastIndexOf("-"); - String group = id.substring(0, index); - - // Delete VM - URI uri = api.getVirtualMachineApi(group).delete(id); - if (uri != null){ - boolean jobDone = nodeTerminated.apply(uri); - - if (jobDone) { - // Delete storage account - api.getStorageAccountApi(group).delete(storageAccountName); - - // Delete NIC - uri = api.getNetworkInterfaceCardApi(group).delete(id + "nic"); - if (uri != null){ - jobDone = resourceDeleted.apply(uri); - if (jobDone) { - - // Delete deployment + String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "stor"; + String group = azureComputeConstants.azureResourceGroup(); + + VirtualMachine vm = api.getVirtualMachineApi(group).get(id); + if (vm != null) { + URI uri = api.getVirtualMachineApi(group).delete(id); + if (uri != null) { + boolean jobDone = nodeTerminated.apply(uri); + boolean storageAcctDeleteStatus = false; + boolean deploymentDeleteStatus = false; + + if (jobDone) { + StorageService ss = api.getStorageAccountApi(group).get(storageAccountName); + if (ss != null) { + storageAcctDeleteStatus = api.getStorageAccountApi(group).delete(storageAccountName); + } else { + storageAcctDeleteStatus = true; + } + Deployment deployment = api.getDeploymentApi(group).get(id); + if (deployment != null) { uri = api.getDeploymentApi(group).delete(id); jobDone = resourceDeleted.apply(uri); if (jobDone) { - // Delete public ip - boolean ipDeleteStatus = api.getPublicIPAddressApi(group).delete(id + "publicip"); - - // Delete Virtual network - boolean vnetDeleteStatus = api.getVirtualNetworkApi(group).delete(group + "virtualnetwork"); - return ipDeleteStatus && vnetDeleteStatus; - + deploymentDeleteStatus = true; + } + } else { + deploymentDeleteStatus = true; + } + NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(group).get(id + "nic"); + if (nic != null) { + uri = api.getNetworkInterfaceCardApi(group).delete(id + "nic"); + if (uri != null) { + jobDone = resourceDeleted.apply(uri); + if (jobDone) { + boolean ipDeleteStatus = false; + PublicIPAddress ip = api.getPublicIPAddressApi(group).get(id + "publicip"); + if (ip != null) { + ipDeleteStatus = api.getPublicIPAddressApi(group).delete(id + "publicip"); + } else { + ipDeleteStatus = true; + } + + // Get NSG + boolean nsgDeleteStatus = false; + NetworkSecurityGroup nsg = api.getNetworkSecurityGroupApi(group).get(id + "nsg"); + if (nsg != null) { + uri = api.getNetworkSecurityGroupApi(group).delete(id + "nsg"); + jobDone = resourceDeleted.apply(uri); + if (jobDone) { + nsgDeleteStatus = true; + + } + } + else { + nsgDeleteStatus = true; + } + + return deploymentDeleteStatus && storageAcctDeleteStatus && ipDeleteStatus && nsgDeleteStatus; + } else { + return false; + } } else { return false; } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/StatusCodeParser.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/StatusCodeParser.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/StatusCodeParser.java new file mode 100644 index 0000000..4c14ec2 --- /dev/null +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/functions/StatusCodeParser.java @@ -0,0 +1,38 @@ +/* + * 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.functions; +import com.google.common.base.Function; +import org.jclouds.http.HttpResponse; + +import javax.inject.Singleton; + +import static org.jclouds.http.HttpUtils.releasePayload; + +/** + * Parses an http response code from http responser + */ +@Singleton +public class StatusCodeParser implements Function<HttpResponse, String> { + public String apply(final HttpResponse from) { + releasePayload(from); + final String statusCode = Integer.toString(from.getStatusCode()); + if (statusCode != null) { + return statusCode; + } + throw new IllegalStateException("did not receive RequestId in: " + from); + } +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java index d5a2d69..6532173 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/handlers/AzureComputeErrorHandler.java @@ -48,7 +48,12 @@ public class AzureComputeErrorHandler implements HttpErrorHandler { : message; switch (response.getStatusCode()) { case 400: - exception = new IllegalArgumentException(message, exception); + if (message.contains("unauthorized_client")) { + exception = new AuthorizationException(message, exception); + } + else { + exception = new IllegalArgumentException(message, exception); + } break; case 401: case 403: http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java index ed5ec9e..f7850d4 100644 --- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java +++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/util/DeploymentTemplateBuilder.java @@ -16,37 +16,42 @@ */ package org.jclouds.azurecompute.arm.util; -import com.google.common.collect.ImmutableMap; +import com.google.common.base.Strings; +import com.google.common.collect.Lists; import com.google.inject.assistedinject.Assisted; +import com.google.common.base.Joiner; +import com.google.common.base.Preconditions; import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule; -import org.jclouds.azurecompute.arm.domain.DeploymentProperties; -import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension; +import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; import org.jclouds.azurecompute.arm.domain.DataDisk; import org.jclouds.azurecompute.arm.domain.DeploymentBody; +import org.jclouds.azurecompute.arm.domain.DeploymentProperties; import org.jclouds.azurecompute.arm.domain.DeploymentTemplate; import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile; import org.jclouds.azurecompute.arm.domain.DnsSettings; 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.KeyVaultReference; import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties; import org.jclouds.azurecompute.arm.domain.NetworkProfile; import org.jclouds.azurecompute.arm.domain.OSDisk; import org.jclouds.azurecompute.arm.domain.OSProfile; import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties; -import org.jclouds.azurecompute.arm.domain.ResourceDefinition; import org.jclouds.azurecompute.arm.domain.StorageProfile; import org.jclouds.azurecompute.arm.domain.StorageService; -import org.jclouds.azurecompute.arm.domain.StorageService.StorageServiceProperties; -import org.jclouds.azurecompute.arm.domain.Subnet; -import org.jclouds.azurecompute.arm.domain.Subnet.SubnetProperties; +import org.jclouds.azurecompute.arm.domain.TemplateParameterType; import org.jclouds.azurecompute.arm.domain.VHD; import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; -import org.jclouds.azurecompute.arm.domain.VirtualNetwork.VirtualNetworkProperties; -import org.jclouds.azurecompute.arm.domain.VirtualNetwork.AddressSpace; +import org.jclouds.azurecompute.arm.domain.StorageService.StorageServiceProperties; +import org.jclouds.azurecompute.arm.domain.IdReference; +import org.jclouds.azurecompute.arm.domain.ResourceDefinition; +import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties; +import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule; +import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties; import org.jclouds.compute.domain.Template; import org.jclouds.json.Json; @@ -56,8 +61,10 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import static com.google.common.io.BaseEncoding.base64; import com.google.inject.Inject; +import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_PREFIX; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION; public class DeploymentTemplateBuilder { @@ -66,11 +73,14 @@ public class DeploymentTemplateBuilder { } private final String name; + private final String azureGroup; private final String group; private final Template template; private final Json json; - private TemplateOptions options; + private AzureTemplateOptions options; + private Iterable<String> tags; + private Map<String, String> userMetaData; private List<ResourceDefinition> resources; private Map<String, String> variables; private static String loginUser; @@ -79,10 +89,6 @@ public class DeploymentTemplateBuilder { private AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants; private static final String DEPLOYMENT_MODE = "Incremental"; - private static final String DEFAULT_DATA_DISK_SIZE = "1023"; - - private static final String DEFAULT_vnAddresSpacePrefix = "10.0.0.0/16"; - private static final String DEFAULT_subnetAddressPrefix = "10.0.0.0/24"; @Inject DeploymentTemplateBuilder(Json json, @Assisted("group") String group, @Assisted("name") String name, @Assisted Template template, @@ -90,13 +96,16 @@ public class DeploymentTemplateBuilder { this.name = name; this.group = group; this.template = template; - this.options = template.getOptions().as(TemplateOptions.class); + this.options = template.getOptions().as(AzureTemplateOptions.class); + this.tags = template.getOptions().getTags(); + this.userMetaData = template.getOptions().getUserMetadata(); this.variables = new HashMap<String, String>(); this.resources = new ArrayList<ResourceDefinition>(); this.location = template.getLocation().getId(); this.json = json; this.azureComputeConstants = azureComputeConstants; + this.azureGroup = this.azureComputeConstants.azureResourceGroup(); String[] defaultLogin = this.azureComputeConstants.azureDefaultImageLogin().split(":"); String defaultUser = null; @@ -126,30 +135,53 @@ public class DeploymentTemplateBuilder { public DeploymentBody getDeploymentTemplate() { addStorageResource(); - addVirtualNetworkResource(); addPublicIpAddress(); + addNetworkSecurityGroup(); addNetworkInterfaceCard(); addVirtualMachine(); + + DeploymentTemplate.TemplateParameters templateParameters = null; + DeploymentTemplate.Parameters parameters = null; + + if (keyVaultInUse()){ + String[] keyVaultInfo = options.getKeyVaultIdAndSecret().split(":"); + Preconditions.checkArgument(keyVaultInfo.length == 2); + String vaultId = keyVaultInfo[0].trim(); + String secretName = keyVaultInfo[1].trim(); + + templateParameters = DeploymentTemplate.TemplateParameters.create(TemplateParameterType.create("securestring")); + parameters = DeploymentTemplate.Parameters.create(KeyVaultReference.create(KeyVaultReference.Reference.create(IdReference.create(vaultId), secretName))); + } else { + templateParameters = DeploymentTemplate.TemplateParameters.create(null); + parameters = DeploymentTemplate.Parameters.create(null); + } + + DeploymentTemplate template = DeploymentTemplate.builder() .schema("https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#") .contentVersion("1.0.0.0") .resources(resources) .variables(variables) - .parameters(DeploymentTemplate.Parameters.create()) + .parameters(templateParameters) .build(); - DeploymentBody body = DeploymentBody.create(template, DEPLOYMENT_MODE, DeploymentTemplate.Parameters.create()); + DeploymentBody body = DeploymentBody.create(template, DEPLOYMENT_MODE, parameters); return body; } - public String getDeploymentTemplateJson(DeploymentProperties properties){ + public String getDeploymentTemplateJson(DeploymentProperties properties) { return json.toJson(properties); } private void addStorageResource() { - String storageAccountName = name.replaceAll("[^A-Za-z0-9 ]", "") + "storage"; + String storageAccountName = name.replaceAll("[^A-Za-z0-9 ]", "") + "stor"; + + String storageName = template.getImage().getName(); + if (storageName.startsWith(CUSTOM_IMAGE_PREFIX)) { + storageAccountName = storageName.substring(CUSTOM_IMAGE_PREFIX.length()); // get group name + } variables.put("storageAccountName", storageAccountName); @@ -168,47 +200,13 @@ public class DeploymentTemplateBuilder { resources.add(storageAccount); } - private void addVirtualNetworkResource() { - String virtualNetworkName = group + "virtualnetwork"; - - String subnetName = group + "subnet"; - variables.put("virtualNetworkName", virtualNetworkName); - variables.put("virtualNetworkReference", "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualNetworkName'))]"); - variables.put("subnetName", subnetName); - variables.put("subnetReference", "[concat(variables('virtualNetworkReference'),'/subnets/',variables('subnetName'))]"); - - VirtualNetworkProperties properties = VirtualNetworkProperties.builder() - .addressSpace( - AddressSpace.create(Arrays.asList(DEFAULT_vnAddresSpacePrefix)) - ) - .subnets( - Arrays.asList( - Subnet.create("[variables('subnetName')]", null, null, - SubnetProperties.builder() - .addressPrefix(DEFAULT_subnetAddressPrefix).build() - )) - ) - .build(); - - - ResourceDefinition virtualNetwork = ResourceDefinition.builder() - .name("[variables('virtualNetworkName')]") - .type("Microsoft.Network/virtualNetworks") - .location(location) - .apiVersion(STORAGE_API_VERSION) - .properties(properties) - .build(); - - resources.add(virtualNetwork); - } - private void addPublicIpAddress() { String publicIPAddressName = name + "publicip"; - String dnsLabelPrefix = name; //TODO: read from Azure template properties + String dnsLabelPrefix = options.getDNSLabelPrefix(); PublicIPAddressProperties.Builder properties = PublicIPAddressProperties.builder(); - if (!dnsLabelPrefix.isEmpty()) { + if (!Strings.isNullOrEmpty(dnsLabelPrefix)) { properties.dnsSettings(DnsSettings.builder().domainNameLabel(dnsLabelPrefix).build()); variables.put("dnsLabelPrefix", dnsLabelPrefix); } @@ -233,7 +231,11 @@ public class DeploymentTemplateBuilder { List<IpConfiguration> ipConfigurations = new ArrayList<IpConfiguration>(); String ipConfigurationName = name + "ipconfig"; + String subnetId = options.getSubnetId(); + String vnetName = options.getVirtualNetworkName(); + variables.put("ipConfigurationName", ipConfigurationName); + variables.put("subnetReference", subnetId); IpConfiguration ipConfig = IpConfiguration.create(ipConfigurationName, null, null, null, IpConfigurationProperties.builder() @@ -244,9 +246,22 @@ public class DeploymentTemplateBuilder { ipConfigurations.add(ipConfig); - NetworkInterfaceCardProperties networkInterfaceCardProperties = NetworkInterfaceCardProperties.builder() - .ipConfigurations(ipConfigurations) - .build(); + // Check to see if we have defined a network security group + IdReference networkSecurityGroup = null; + int ports[] = options.getInboundPorts(); + if ((ports != null) && (ports.length > 0)) { + networkSecurityGroup = IdReference.create("[variables('networkSecurityGroupNameReference')]"); + } + + ArrayList<String> depends = new ArrayList<String>(Arrays.asList("[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]")); + + NetworkInterfaceCardProperties.Builder networkInterfaceCardPropertiesBuilder = NetworkInterfaceCardProperties.builder(); + networkInterfaceCardPropertiesBuilder.ipConfigurations(ipConfigurations); + if (networkSecurityGroup != null) { + networkInterfaceCardPropertiesBuilder.networkSecurityGroup(networkSecurityGroup); + depends.add("[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]"); + } + NetworkInterfaceCardProperties networkInterfaceCardProperties = networkInterfaceCardPropertiesBuilder.build(); String networkInterfaceCardName = name + "nic"; variables.put("networkInterfaceCardName", networkInterfaceCardName); @@ -257,16 +272,58 @@ public class DeploymentTemplateBuilder { .type("Microsoft.Network/networkInterfaces") .location(location) .apiVersion(STORAGE_API_VERSION) - .dependsOn(Arrays.asList("[concat('Microsoft.Network/publicIPAddresses/', variables('publicIPAddressName'))]", - "[concat('Microsoft.Network/virtualNetworks/', variables('virtualNetworkName'))]")) + .dependsOn(depends) .properties(networkInterfaceCardProperties) .build(); resources.add(networkInterfaceCard); } - private void addVirtualMachine() { + private void addNetworkSecurityGroup() { + int ports[] = options.getInboundPorts(); + if ((ports != null) && (ports.length > 0)) { + variables.put("networkSecurityGroupName", name + "nsg"); + variables.put("networkSecurityGroupNameReference", "[resourceId('Microsoft.Network/networkSecurityGroups',variables('networkSecurityGroupName'))]"); + + List<NetworkSecurityRule> rules = new ArrayList<NetworkSecurityRule>(); + for (int i = 0; i < ports.length; i++) { + NetworkSecurityRuleProperties ruleProperties = NetworkSecurityRuleProperties.builder() + .description("default-allow-port-" + ports[i]) + .protocol(NetworkSecurityRuleProperties.Protocol.All) + .access(NetworkSecurityRuleProperties.Access.Allow) + .sourcePortRange("*") + .destinationPortRange(Integer.toString(ports[i])) + .sourceAddressPrefix("*") + .destinationAddressPrefix("*") + .priority(1234 + i) + .direction(NetworkSecurityRuleProperties.Direction.Inbound) + .build(); + + NetworkSecurityRule networkSecurityRule = NetworkSecurityRule.create( + "default-allow-port-" + ports[i], + null, + null, + ruleProperties); + + rules.add(networkSecurityRule); + } + + NetworkSecurityGroupProperties networkSecurityGroupProperties = NetworkSecurityGroupProperties.builder() + .securityRules(rules) + .build(); + + ResourceDefinition networkSecurityGroup = ResourceDefinition.builder() + .name("[variables('networkSecurityGroupName')]") + .type("Microsoft.Network/networkSecurityGroups").location(location) + .apiVersion(STORAGE_API_VERSION) + .properties(networkSecurityGroupProperties) + .build(); + resources.add(networkSecurityGroup); + } + } + + private void addVirtualMachine() { //Build OS Profile final String computerName = name + "pc"; @@ -275,51 +332,52 @@ public class DeploymentTemplateBuilder { .adminUsername(loginUser) .computerName(computerName); - boolean usePublicKey = options.getPublicKey() != null; + profileBuilder.adminPassword(loginPassword); + //boolean usePublicKey = options.getPublicKey() != null; - if (usePublicKey) { - OSProfile.LinuxConfiguration configuration = OSProfile.LinuxConfiguration.create("true", + if (keyVaultInUse()) { + OSProfile.LinuxConfiguration configuration = OSProfile.LinuxConfiguration.create("false", OSProfile.LinuxConfiguration.SSH.create(Arrays.asList( OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create( "[concat('/home/',variables('loginUser'),'/.ssh/authorized_keys')]", - options.getPublicKey()) - )) - ); + "[parameters('publicKeyFromAzureKeyVault')]" + )) + )); profileBuilder.linuxConfiguration(configuration); - } else { - profileBuilder.adminPassword(loginPassword); } - OSProfile osProfile = profileBuilder.build(); - - //Build Image Reference - final String imagePublisher = template.getImage().getProviderId(); - final String imageOffer = template.getImage().getName(); - final String imageSku = template.getImage().getVersion(); + if (!Strings.isNullOrEmpty(options.getCustomData())){ + String encodedCustomData = base64().encode(options.getCustomData().getBytes()); + profileBuilder.customData(encodedCustomData); + } - ImageReference imageReference = ImageReference.builder() - .publisher(imagePublisher) - .offer(imageOffer) - .sku(imageSku) - .version("latest") - .build(); + OSProfile osProfile = profileBuilder.build(); //Build OsDisk - final String storageAccountContainerName = "vhds"; + final String storageAccountContainerName = name + "vhds"; variables.put("storageAccountContainerName", storageAccountContainerName); final String osDiskName = name + "osdisk"; variables.put("osDiskName", osDiskName); - OSDisk osDisk = OSDisk.builder() - .name("[variables('osDiskName')]") - .vhd( - VHD.create("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('storageAccountContainerName'),'/',variables('osDiskName'),'.vhd')]") - ) - .caching("ReadWrite") - .createOption("FromImage") - .build(); + boolean usingMarketplaceImage = true; + String cusotomImageUri = ""; + + // TODO: make new fields for group information + String publisher = template.getImage().getProviderId(); + String storageName = template.getImage().getName(); + String sku = template.getImage().getDescription(); // this is actual VHD + if (storageName.startsWith(CUSTOM_IMAGE_PREFIX)) { + storageName = storageName.substring(CUSTOM_IMAGE_PREFIX.length()); // get group name + cusotomImageUri = sku; + cusotomImageUri = "https://" + storageName + ".blob.core.windows.net/system/Microsoft.Compute/Images/" + AzureComputeImageExtension.CONTAINER_NAME + "/" + cusotomImageUri; + } + + if (!cusotomImageUri.isEmpty()) { + usingMarketplaceImage = false; + } + OSDisk osDisk = getOsDisk("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('storageAccountContainerName'),'/',variables('osDiskName'),'.vhd')]", cusotomImageUri); //Create Data Disk(s) and add to list final String dataDiskName = name + "datadisk"; @@ -328,7 +386,7 @@ public class DeploymentTemplateBuilder { List<DataDisk> dataDisks = new ArrayList<DataDisk>(); DataDisk dataDisk = DataDisk.builder() .name("[variables('dataDiskName')]") - .diskSizeGB(DEFAULT_DATA_DISK_SIZE) + .diskSizeGB(azureComputeConstants.azureDefaultDataDiskSizeProperty()) .lun(0) .vhd( VHD.create("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('storageAccountContainerName'),'/',variables('dataDiskName'),'.vhd')]") @@ -339,11 +397,20 @@ public class DeploymentTemplateBuilder { dataDisks.add(dataDisk); //Create Storage Profile - StorageProfile storageProfile = StorageProfile.builder() - .imageReference(imageReference) + StorageProfile.Builder storageProfileBuilder = StorageProfile.builder() .osDisk(osDisk) - .dataDisks(dataDisks) - .build(); + .dataDisks(dataDisks); + + if (usingMarketplaceImage) { + //Build Image Reference if marketplace image is used + ImageReference imageReference = getImageReference(template.getImage().getProviderId(), + template.getImage().getName(), + template.getImage().getVersion()); + + storageProfileBuilder.imageReference(imageReference); + } + StorageProfile storageProfile = storageProfileBuilder.build(); + //Create Network Profile for this VM (links to network interface cards) NetworkProfile networkProfile = NetworkProfile.create( @@ -370,19 +437,54 @@ public class DeploymentTemplateBuilder { .diagnosticsProfile(diagnosticsProfile) .build(); + + String tagString = Joiner.on(",").join(Lists.newArrayList(tags)); + if (tagString.isEmpty()) + tagString = "jclouds"; + userMetaData.put("tags", tagString); + variables.put("virtualMachineName", name); ResourceDefinition virtualMachine = ResourceDefinition.builder() .name("[variables('virtualMachineName')]") .type("Microsoft.Compute/virtualMachines") .location(location) - .apiVersion(STORAGE_API_VERSION) + .apiVersion("2015-06-15") .dependsOn(Arrays.asList("[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]", "[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceCardName'))]")) - .tags(ImmutableMap.of("displayName", "VirtualMachine")) + .tags(userMetaData) .properties(properties) .build(); resources.add(virtualMachine); } + + private ImageReference getImageReference(String publisher, String offer, String sku) { + return ImageReference.builder() + .publisher(publisher) + .offer(offer) + .sku(sku) + .version("latest") + .build(); + + } + + private OSDisk getOsDisk(String vhdUri, String imageUri) { + OSDisk.Builder builder = OSDisk.builder(); + builder.name("[variables('osDiskName')]"); + builder.caching("ReadWrite"); + builder.createOption("FromImage"); + builder.vhd(VHD.create(vhdUri)); + + if (!imageUri.isEmpty()) { + builder.osType("Linux"); + builder.image(VHD.create(imageUri)); + } + return builder.build(); + } + + private boolean keyVaultInUse(){ + return !Strings.isNullOrEmpty(options.getKeyVaultIdAndSecret()); + } + } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java deleted file mode 100644 index 940f785..0000000 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceContextLiveTest.java +++ /dev/null @@ -1,284 +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 com.google.common.base.Preconditions; -import com.google.common.base.Predicate; -import com.google.inject.Module; -import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata; -import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils; -import org.jclouds.compute.RunNodesException; -import org.jclouds.compute.RunScriptOnNodesException; -import org.jclouds.compute.domain.ComputeMetadata; -import org.jclouds.compute.domain.ExecResponse; -import org.jclouds.compute.domain.NodeMetadata; -import org.jclouds.compute.domain.OsFamily; -import org.jclouds.compute.domain.Template; -import org.jclouds.compute.domain.TemplateBuilder; -import org.jclouds.compute.internal.BaseComputeServiceContextLiveTest; -import org.jclouds.domain.Credentials; -import org.jclouds.domain.LoginCredentials; -import org.jclouds.providers.ProviderMetadata; -import org.jclouds.sshj.config.SshjSshClientModule; -import org.testng.annotations.Test; - -import java.util.Map; -import java.util.Properties; -import java.util.Random; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import static com.google.common.base.Preconditions.checkNotNull; -import static org.assertj.core.api.Assertions.assertThat; -import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME; -import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; -import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE; - -import static org.jclouds.compute.predicates.NodePredicates.inGroup; -import static org.jclouds.compute.options.TemplateOptions.Builder.overrideLoginCredentials; -import static org.jclouds.scriptbuilder.domain.Statements.exec; -import static org.testng.Assert.assertTrue; - -@Test(groups = "live", testName = "AzureComputeServiceContextLiveTest") -public class AzureComputeServiceContextLiveTest extends BaseComputeServiceContextLiveTest { - - public String azureGroup; - protected static final int RAND = new Random().nextInt(999); - - @Override - protected Module getSshModule() { - return new SshjSshClientModule(); - } - - @Override protected Properties setupProperties() { - azureGroup = "jc" + RAND; - - Properties properties = super.setupProperties(); - long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES); - properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + ""); - properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + ""); - - AzureLiveTestUtils.defaultProperties(properties); - checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); - - properties.put(RESOURCE_GROUP_NAME, azureGroup); - return properties; - } - - public AzureComputeServiceContextLiveTest() { - provider = "azurecompute-arm"; - } - - @Test - public void testDefault() throws RunNodesException { - - final String groupName = this.azureGroup; - final TemplateBuilder templateBuilder = view.getComputeService().templateBuilder(); - templateBuilder.osFamily(OsFamily.UBUNTU); - templateBuilder.osVersionMatches("14.04"); - templateBuilder.hardwareId("Standard_A0"); - templateBuilder.locationId("westus"); - - final Template template = templateBuilder.build(); - - try { - Set<? extends NodeMetadata> nodes = view.getComputeService().createNodesInGroup(groupName, 1, template); - assertThat(nodes).hasSize(1); - } finally { -// Do not destroy view.getComputeService().destroyNodesMatching(inGroup(groupName)); - } - } - - private LoginCredentials getLogin() { - Credentials credentials = new Credentials("jclouds", "Password1!"); - LoginCredentials login = LoginCredentials.fromCredentials(credentials); - return login; - } - - @Test(dependsOnMethods = "testDefault") - public void testExec() throws RunScriptOnNodesException { - final String groupName = this.azureGroup; - String command = "echo hello"; - - Map<? extends NodeMetadata, ExecResponse> responses = view.getComputeService().runScriptOnNodesMatching(// - inGroup(groupName), // predicate used to select nodes - exec(command), // what you actually intend to run - overrideLoginCredentials(getLogin()) // use my local user & - // ssh key - .runAsRoot(false) // don't attempt to run as root (sudo) - .wrapInInitScript(false)); // run command directly - - assertTrue(responses.size() > 0); - } - - public static Predicate<ComputeMetadata> nameStartsWith(final String prefix) { - Preconditions.checkNotNull(prefix, "prefix must be defined"); - - return new Predicate<ComputeMetadata>() { - @Override - public boolean apply(ComputeMetadata computeMetadata) { - return computeMetadata.getName().startsWith(prefix); - } - - @Override - public String toString() { - return "nameStartsWith(" + prefix + ")"; - } - }; - } - - @Test(dependsOnMethods = "testExec") - public void testStop() throws RunScriptOnNodesException { - final String groupName = this.azureGroup; - Set<? extends NodeMetadata> nodes = view.getComputeService().suspendNodesMatching(inGroup(groupName)); - assertTrue(nodes.size() > 0); - - boolean allStopped = false; - while (!allStopped) { - nodes = view.getComputeService().listNodesDetailsMatching(nameStartsWith(groupName)); - for (NodeMetadata node : nodes) { - if (node.getStatus() != NodeMetadata.Status.SUSPENDED) - { - // Not stopped yet - allStopped = false; - try { - Thread.sleep(15 * 1000); - } catch (InterruptedException e) { - } - continue; - } - else - { - allStopped = true; - } - } - } - assertTrue(allStopped); - } - - @Test(dependsOnMethods = "testStop") - public void testStart() throws RunScriptOnNodesException { - final String groupName = this.azureGroup; - Set<? extends NodeMetadata> nodes = view.getComputeService().resumeNodesMatching(inGroup(groupName)); - assertTrue(nodes.size() > 0); - - boolean allStarted = false; - while (!allStarted) { - nodes = view.getComputeService().listNodesDetailsMatching(nameStartsWith(groupName)); - for (NodeMetadata node : nodes) { - if (node.getStatus() != NodeMetadata.Status.RUNNING) - { - // Not started yet - allStarted = false; - try { - Thread.sleep(15 * 1000); - } catch (InterruptedException e) { - } - continue; - } - else - { - allStarted = true; - } - } - } - assertTrue(allStarted); - } - - @Test(dependsOnMethods = "testStart") - public void testRestart() throws RunScriptOnNodesException { - final String groupName = this.azureGroup; - Set<? extends NodeMetadata> nodes = view.getComputeService().rebootNodesMatching(inGroup(groupName)); - assertTrue(nodes.size() > 0); - - boolean allRestarted = false; - while (!allRestarted) { - nodes = view.getComputeService().listNodesDetailsMatching(nameStartsWith(groupName)); - for (NodeMetadata node : nodes) { - if (node.getStatus() != NodeMetadata.Status.RUNNING) - { - // Not started yet - allRestarted = false; - try { - Thread.sleep(30 * 1000); - } catch (InterruptedException e) { - } - continue; - } - else - { - allRestarted = true; - } - } - } - assertTrue(allRestarted); - - view.getComputeService().destroyNodesMatching(inGroup(groupName)); - } - - @Test(dependsOnMethods = "testRestart") - public void testLinuxNode() throws RunNodesException { - final String groupName = this.azureGroup; - final TemplateBuilder templateBuilder = view.getComputeService().templateBuilder(); - templateBuilder.osFamily(OsFamily.UBUNTU); - templateBuilder.osVersionMatches("14.04"); - templateBuilder.hardwareId("Standard_A0"); - templateBuilder.locationId("westus"); - final Template template = templateBuilder.build(); - - try { - Set<? extends NodeMetadata> nodes = view.getComputeService().createNodesInGroup(groupName, 1, template); - assertThat(nodes).hasSize(1); - } finally { - view.getComputeService().destroyNodesMatching(inGroup(groupName)); - } - } - - @Test(dependsOnMethods = "testLinuxNode") - public void testWindowsNode() throws RunNodesException { - final String groupName = this.azureGroup; - final TemplateBuilder templateBuilder = view.getComputeService().templateBuilder(); - templateBuilder.imageId("global/MicrosoftWindowsServer/WindowsServer/Windows-Server-Technical-Preview"); - templateBuilder.hardwareId("Standard_A0"); - templateBuilder.locationId("westus"); - final Template template = templateBuilder.build(); - - try { - Set<? extends NodeMetadata> nodes = view.getComputeService().createNodesInGroup(groupName, 1, template); - assertThat(nodes).hasSize(1); - } finally { - view.getComputeService().destroyNodesMatching(inGroup(groupName)); - } - } - - @Override - protected ProviderMetadata createProviderMetadata() { - AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build(); - return pm; - } - - protected String setIfTestSystemPropertyPresent(Properties overrides, String key) { - if (System.getProperties().containsKey("test." + key)) { - String val = System.getProperty("test." + key); - overrides.setProperty(key, val); - return val; - } else { - return null; - } - } - -} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java index ae43511..b1223e2 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceLiveTest.java @@ -16,33 +16,57 @@ */ package org.jclouds.azurecompute.arm.compute; +import org.jclouds.compute.RunScriptOnNodesException; +import org.jclouds.compute.domain.ExecResponse; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Template; import org.jclouds.compute.internal.BaseComputeServiceLiveTest; +import org.jclouds.compute.predicates.NodePredicates; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.scriptbuilder.domain.Statement; +import org.jclouds.scriptbuilder.domain.Statements; +import org.jclouds.scriptbuilder.statements.java.InstallJDK; +import org.jclouds.scriptbuilder.statements.login.AdminAccess; import org.jclouds.sshj.config.SshjSshClientModule; import org.testng.annotations.Test; - import org.jclouds.providers.ProviderMetadata; - import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata; import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN; import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE; import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils; - import com.google.inject.Module; +import java.util.Map; import java.util.Properties; +import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; + import static com.google.common.base.Preconditions.checkNotNull; +import org.jclouds.logging.slf4j.config.SLF4JLoggingModule; +import org.jclouds.logging.config.LoggingModule; + /** * Live tests for the {@link org.jclouds.compute.ComputeService} integration. */ @Test(groups = "live", singleThreaded = true, testName = "AzureComputeServiceLiveTest") public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest { - public String azureGroup; + protected int nonBlockDurationSeconds = 30; public AzureComputeServiceLiveTest() { provider = "azurecompute-arm"; + nonBlockDurationSeconds = 300; + group = "az-u"; + } + + @Override + protected LoggingModule getLoggingModule() { + return new SLF4JLoggingModule(); } @Override @@ -56,18 +80,42 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest { return pm; } - @Override protected Properties setupProperties() { - azureGroup = "jc" + System.getProperty("user.name").substring(0, 3); + @Override + protected Properties setupProperties() { Properties properties = super.setupProperties(); - long scriptTimeout = TimeUnit.MILLISECONDS.convert(20, TimeUnit.MINUTES); + long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES); properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + ""); properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + ""); - properties.put(RESOURCE_GROUP_NAME, azureGroup); + properties.setProperty(TIMEOUT_PORT_OPEN, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_TERMINATED, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_SUSPENDED, scriptTimeout + ""); + properties.put(RESOURCE_GROUP_NAME, "a4"); AzureLiveTestUtils.defaultProperties(properties); checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); return properties; + } + @Override + protected Template refreshTemplate() { + return this.template = addRunScriptToTemplate(this.buildTemplate(this.client.templateBuilder())); + } + + @Override + protected Template addRunScriptToTemplate(Template template) { + template.getOptions().runScript(Statements.newStatementList(new Statement[]{AdminAccess.standard(), Statements.exec("sleep 50"), InstallJDK.fromOpenJDK()})); + return template; + } + + @Override + @Test( enabled = false) + protected void weCanCancelTasks(NodeMetadata node) throws InterruptedException, ExecutionException { + return; + } + + @Override + protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(String group, OperatingSystem os, LoginCredentials creds) throws RunScriptOnNodesException { + return this.client.runScriptOnNodesMatching(NodePredicates.runningInGroup(group), Statements.newStatementList(Statements.exec("sleep 50"), InstallJDK.fromOpenJDK()), org.jclouds.compute.options.TemplateOptions.Builder.overrideLoginCredentials(creds).nameTask("runScriptWithCreds")); } } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtensionLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtensionLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtensionLiveTest.java new file mode 100644 index 0000000..fecd0fd --- /dev/null +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtensionLiveTest.java @@ -0,0 +1,89 @@ +/* + * 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 com.google.inject.Module; +import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata; +import org.jclouds.azurecompute.arm.config.AzureComputeProperties; +import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils; +import org.jclouds.compute.config.ComputeServiceProperties; +import org.jclouds.compute.extensions.internal.BaseImageExtensionLiveTest; +import org.jclouds.providers.ProviderMetadata; +import org.jclouds.sshj.config.SshjSshClientModule; +import org.testng.annotations.Test; + +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE; + +/** + * Live tests for the {@link org.jclouds.compute.extensions.ImageExtension} integration. + */ +@Test(groups = "live", singleThreaded = true, testName = "AzureComputeImageExtensionLiveTest") +public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTest { + + public AzureComputeImageExtensionLiveTest() { + provider = "azurecompute-arm"; + } + + public static String NAME_PREFIX = "%s"; + + @Override + protected Module getSshModule() { + return new SshjSshClientModule(); + } + + @Override + protected Properties setupProperties() { + Properties properties = super.setupProperties(); + long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES); + properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + ""); + properties.setProperty(TIMEOUT_PORT_OPEN, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_TERMINATED, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_SUSPENDED, scriptTimeout + ""); + properties.put(RESOURCE_GROUP_NAME, "a5"); + + properties.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, 1000); + properties.put(ComputeServiceProperties.POLL_MAX_PERIOD, 10000); + properties.setProperty(AzureComputeProperties.OPERATION_TIMEOUT, "46000000"); + properties.setProperty(AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD, "5"); + properties.setProperty(AzureComputeProperties.OPERATION_POLL_MAX_PERIOD, "15"); + properties.setProperty(AzureComputeProperties.TCP_RULE_FORMAT, "tcp_%s-%s"); + properties.setProperty(AzureComputeProperties.TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}"); + + AzureLiveTestUtils.defaultProperties(properties); + checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); + + return properties; + + } + + @Override + protected ProviderMetadata createProviderMetadata() { + AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build(); + return pm; + } + +} http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentApiLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentApiLiveTest.java index 0e2baef..7493a63 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentApiLiveTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentApiLiveTest.java @@ -18,6 +18,7 @@ package org.jclouds.azurecompute.arm.features; import com.google.common.base.Predicate; import com.google.common.net.UrlEscapers; +import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; import org.jclouds.azurecompute.arm.domain.Deployment; import org.jclouds.azurecompute.arm.domain.Deployment.ProvisioningState; import org.jclouds.azurecompute.arm.domain.DeploymentBody; @@ -141,7 +142,7 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest { public void testCreate() { String rsakey = new String("ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAmfk/QSF0pvnrpdz+Ah2KulGruKU+8FFBdlw938MpOysRdmp7uwpH6Z7+5VNGNdxFIAyc/W3UaZXF9hTsU8+78TlwkZpsr2mzU+ycu37XLAQ8Uv7hjsAN0DkKKPrZ9lgUUfZVKV/8E/JIAs03gIbL6zO3y7eYJQ5fNeZb+nji7tQT+YLpGq/FDegvraPKVMQbCSCZhsHyWhdPLyFlu9/30npZ0ahYOPI/KyZxFDtM/pHp88+ZAk9Icq5owaLRWcJQqrBGWqjbZnHtjdDqvHZ+C0wPhdJZPyfkHOrSYTwSQBXfX4JLRRCz3J1jf62MbQWT1o6Y4JEs1ZP1Skxu6zR96Q== mocktest"); - TemplateOptions options = new TemplateOptions(); + TemplateOptions options = new AzureTemplateOptions(); options.authorizePublicKey(rsakey); DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithOptions(options); DeploymentBody deploymentTemplateBody = templateBuilder.getDeploymentTemplate(); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentTemplateBuilderTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentTemplateBuilderTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentTemplateBuilderTest.java index bc505e7..ad5b1f3 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentTemplateBuilderTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/DeploymentTemplateBuilderTest.java @@ -18,18 +18,17 @@ package org.jclouds.azurecompute.arm.features; import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest; import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; import org.jclouds.azurecompute.arm.domain.DeploymentBody; 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.NetworkInterfaceCardProperties; -import org.jclouds.azurecompute.arm.domain.OSProfile; import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties; import org.jclouds.azurecompute.arm.domain.ResourceDefinition; import org.jclouds.azurecompute.arm.domain.StorageService; import org.jclouds.azurecompute.arm.domain.StorageService.StorageServiceProperties; import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; -import org.jclouds.azurecompute.arm.domain.VirtualNetwork.VirtualNetworkProperties; import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder; import org.jclouds.compute.domain.Hardware; import org.jclouds.compute.domain.HardwareBuilder; @@ -56,6 +55,8 @@ import static org.testng.Assert.fail; public class DeploymentTemplateBuilderTest extends BaseAzureComputeApiMockTest { final String group = "jcgroup"; + final String vnetName = group + "virtualnetwork"; + final String subnetId = ""; @Test public void testResourceGroup() { @@ -72,22 +73,6 @@ public class DeploymentTemplateBuilderTest extends BaseAzureComputeApiMockTest { } @Test - void testVirtualNetwork() { - DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithEmptyOptions(); - DeploymentBody deploymentBody = builder.getDeploymentTemplate(); - List<ResourceDefinition> resources = deploymentBody.template().resources(); - Map<String, String> variables = deploymentBody.template().variables(); - - ResourceDefinition resource = getResourceByType(resources, "Microsoft.Network/virtualNetworks"); - - VirtualNetworkProperties properties = (VirtualNetworkProperties) resource.properties(); - assertTrue(properties.addressSpace().addressPrefixes().size() > 0); - assertTrue(properties.subnets().size() > 0); - - assertTrue(variables.containsKey(parseVariableName(resource.name()))); - } - - @Test void testPublicIpAddress() { DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithEmptyOptions(); DeploymentBody deploymentBody = builder.getDeploymentTemplate(); @@ -147,42 +132,49 @@ public class DeploymentTemplateBuilderTest extends BaseAzureComputeApiMockTest { } @Test - void testVirtualMachineWithSSH() { + void testCustomOptions(){ + final String dnsLabelPrefix = "mydnslabel"; + final String customData = "echo customData"; + final String customData64 = "ZWNobyBjdXN0b21EYXRh"; + final String keyvaultString = "/url/to/vault/:publickeysecret"; + + AzureTemplateOptions options = new AzureTemplateOptions() + .customData(customData) + .DNSLabelPrefix(dnsLabelPrefix) + .keyVaultIdAndSecret(keyvaultString); - String rsakey = new String("ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAmfk/QSF0pvnrpdz+Ah2KulGruKU+8FFBdlw938MpOysRdmp7uwpH6Z7+5VNGNdxFIAyc/W3UaZXF9hTsU8+78TlwkZpsr2mzU+ycu37XLAQ8Uv7hjsAN0DkKKPrZ9lgUUfZVKV/8E/JIAs03gIbL6zO3y7eYJQ5fNeZb+nji7tQT+YLpGq/FDegvraPKVMQbCSCZhsHyWhdPLyFlu9/30npZ0ahYOPI/KyZxFDtM/pHp88+ZAk9Icq5owaLRWcJQqrBGWqjbZnHtjdDqvHZ+C0wPhdJZPyfkHOrSYTwSQBXfX4JLRRCz3J1jf62MbQWT1o6Y4JEs1ZP1Skxu6zR96Q== mocktest"); + options.virtualNetworkName(vnetName); + options.subnetId(subnetId); - TemplateOptions options = new TemplateOptions(); - options.authorizePublicKey(rsakey); + assertEquals(options.as(AzureTemplateOptions.class).getCustomData(), customData); + assertEquals(options.getDNSLabelPrefix(), dnsLabelPrefix); + assertEquals(options.as(AzureTemplateOptions.class).getKeyVaultIdAndSecret(), keyvaultString); DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithOptions(options); - Template template = builder.getTemplate(); DeploymentBody deploymentBody = builder.getDeploymentTemplate(); - List<ResourceDefinition> resources = deploymentBody.template().resources(); - Map<String, String> variables = deploymentBody.template().variables(); - ResourceDefinition resource = getResourceByType(resources, "Microsoft.Compute/virtualMachines"); - assertNotNull(resource); + List<ResourceDefinition> resources = deploymentBody.template().resources(); + ResourceDefinition publicIpResource = getResourceByType(resources, "Microsoft.Network/publicIPAddresses"); + assertNotNull(publicIpResource); - VirtualMachineProperties properties = (VirtualMachineProperties) resource.properties(); - assertEquals(properties.hardwareProfile().vmSize(), template.getHardware().getId()); + PublicIPAddressProperties ipProperties = (PublicIPAddressProperties) publicIpResource.properties(); + assertEquals(ipProperties.dnsSettings().domainNameLabel(), dnsLabelPrefix); - ImageReference image = properties.storageProfile().imageReference(); - assertEquals(image.publisher(), template.getImage().getProviderId()); - assertEquals(image.offer(), template.getImage().getName()); - assertEquals(image.sku(), template.getImage().getVersion()); - assertEquals(image.version(), "latest"); + ResourceDefinition vmResource = getResourceByType(resources, "Microsoft.Compute/virtualMachines"); + assertNotNull(vmResource); - // Check that ssh key is in place - OSProfile.LinuxConfiguration osConfig = properties.osProfile().linuxConfiguration(); - assertEquals(osConfig.disablePasswordAuthentication(), "true"); - assertTrue(osConfig.ssh().publicKeys().size() > 0); - assertEquals(osConfig.ssh().publicKeys().get(0).keyData(), rsakey); + VirtualMachineProperties virtualMachineProperties = (VirtualMachineProperties) vmResource.properties(); + assertEquals(virtualMachineProperties.osProfile().customData(), customData64); - assertTrue(variables.containsKey(parseVariableName(resource.name()))); + //populated when keyvault is used to get public key. + assertNotNull(virtualMachineProperties.osProfile().linuxConfiguration().ssh().publicKeys()); } private Template getMockTemplate(TemplateOptions options) { + ((AzureTemplateOptions)options).virtualNetworkName(vnetName); + ((AzureTemplateOptions)options).subnetId(subnetId); + Location provider = (new LocationBuilder()).scope(LocationScope.PROVIDER).id("azurecompute-arm").description("azurecompute-arm").build(); Location region = (new LocationBuilder()).scope(LocationScope.REGION).id("northeurope").description("North Europe").parent(provider).build(); OperatingSystem os = OperatingSystem.builder().name("osName").version("osVersion").description("osDescription").arch("X86_32").build(); @@ -193,13 +185,19 @@ public class DeploymentTemplateBuilderTest extends BaseAzureComputeApiMockTest { } private DeploymentTemplateBuilder getMockDeploymentTemplateBuilderWithEmptyOptions() { - TemplateOptions options = new TemplateOptions(); + AzureTemplateOptions options = new AzureTemplateOptions(); + options.virtualNetworkName(vnetName); + options.subnetId(subnetId); + Template template = getMockTemplate(options); DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(group, "mydeployment", template); return templateBuilder; } private DeploymentTemplateBuilder getMockDeploymentTemplateBuilderWithOptions(TemplateOptions options) { + ((AzureTemplateOptions)options).virtualNetworkName(vnetName); + ((AzureTemplateOptions)options).subnetId(subnetId); + Template template = getMockTemplate(options); DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(group, "mydeployment", template); return templateBuilder; http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/JobApiMockTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/JobApiMockTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/JobApiMockTest.java index 3e55df1..7364145 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/JobApiMockTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/JobApiMockTest.java @@ -18,12 +18,15 @@ package org.jclouds.azurecompute.arm.features; import java.io.IOException; import java.net.URI; +import java.util.List; +import org.jclouds.azurecompute.arm.domain.ResourceDefinition; import org.jclouds.azurecompute.arm.functions.ParseJobStatus.JobStatus; import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest; import org.testng.annotations.Test; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; @Test(groups = "unit", testName = "JobApiMockTest", singleThreaded = true) public class JobApiMockTest extends BaseAzureComputeApiMockTest { @@ -70,4 +73,24 @@ public class JobApiMockTest extends BaseAzureComputeApiMockTest { assertSent(server, "GET", requestUrl); } + public void testCaptureJobStatus() throws IOException, InterruptedException { + server.enqueue(jsonResponse("/resourceDefinition.json").setResponseCode(200)); + + List<ResourceDefinition> resourceDefinitionsList = api.getJobApi().captureStatus(URI.create(requestUrl)); + + assertTrue(resourceDefinitionsList.size() > 0); + + assertSent(server, "GET", requestUrl); + } + + public void testCaptureJobStatusFailed() throws InterruptedException { + server.enqueue(response404()); + + List<ResourceDefinition> resourceDefinitionsList = api.getJobApi().captureStatus(URI.create(requestUrl)); + + assertEquals(resourceDefinitionsList.size(), 0); + + assertSent(server, "GET", requestUrl); + } + } http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApiMockTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApiMockTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApiMockTest.java index 12ad073..bda8cad 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApiMockTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/NetworkInterfaceCardApiMockTest.java @@ -107,7 +107,8 @@ public class NetworkInterfaceCardApiMockTest extends BaseAzureComputeApiMockTest NetworkInterfaceCardProperties.create(null, null, null, Arrays.asList(IpConfiguration.create("myipconfig", null, null, null, IpConfigurationProperties.create(null, null, "Dynamic", IdReference.create(SubnetID), null)) - ) + ), + null ); final Map<String, String> tags = ImmutableMap.of("mycustomtag", "foobar"); http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/TemplateToDeploymentTemplateLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/TemplateToDeploymentTemplateLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/TemplateToDeploymentTemplateLiveTest.java index be2eb3e..12d6255 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/TemplateToDeploymentTemplateLiveTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/TemplateToDeploymentTemplateLiveTest.java @@ -17,10 +17,12 @@ package org.jclouds.azurecompute.arm.features; import com.google.common.net.UrlEscapers; -import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions; import org.jclouds.azurecompute.arm.domain.Deployment; import org.jclouds.azurecompute.arm.domain.DeploymentBody; import org.jclouds.azurecompute.arm.domain.DeploymentProperties; +import org.jclouds.azurecompute.arm.domain.Subnet; +import org.jclouds.azurecompute.arm.domain.VirtualNetwork; import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest; import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder; import org.jclouds.compute.domain.Hardware; @@ -31,6 +33,7 @@ import org.jclouds.compute.domain.OperatingSystem; import org.jclouds.compute.domain.OsFamily; import org.jclouds.compute.domain.Template; import org.jclouds.compute.domain.internal.TemplateImpl; +import org.jclouds.compute.options.TemplateOptions; import org.jclouds.domain.Location; import org.jclouds.domain.LocationBuilder; import org.jclouds.domain.LocationScope; @@ -47,12 +50,50 @@ public class TemplateToDeploymentTemplateLiveTest extends BaseAzureComputeApiLiv private int pollingInterval = 3; // how frequently to poll for create status private String resourceGroup; private String deploymentName; + private String vnetName; + private String subnetId; @BeforeClass @Override public void setup() { super.setup(); resourceGroup = getResourceGroupName(); + + //Subnets belong to a virtual network so that needs to be created first + VirtualNetwork vn = getOrCreateVirtualNetwork(VIRTUAL_NETWORK_NAME); + assertNotNull(vn); + vnetName = vn.name(); + + //Subnet needs to be up & running before NIC can be created + Subnet subnet = getOrCreateSubnet(DEFAULT_SUBNET_NAME, VIRTUAL_NETWORK_NAME); + assertNotNull(subnet); + assertNotNull(subnet.id()); + subnetId = subnet.id(); + } + + @Test(groups = "live") + public void testValidateDeploymentTemplateLinuxNodeWithOptions() { + Long now = System.currentTimeMillis(); + deploymentName = "jc" + now; + + AzureTemplateOptions options = new AzureTemplateOptions(); + options.virtualNetworkName(vnetName); + options.subnetId(subnetId); + + options.inboundPorts(22, 8080); + + DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithOptions(options); + + DeploymentBody deploymentTemplateBody = templateBuilder.getDeploymentTemplate(); + + DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody); + + String deploymentTemplate = templateBuilder.getDeploymentTemplateJson(properties); + deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplate); + + //Validates that template is syntactically correct + Deployment deployment = api().validate(deploymentName, deploymentTemplate); + assertNotNull(deployment); } @Test(groups = "live") @@ -75,13 +116,44 @@ public class TemplateToDeploymentTemplateLiveTest extends BaseAzureComputeApiLiv } @Test(groups = "live") + public void testValidateDeploymentTemplateWithCustomOptions() { + Long now = System.currentTimeMillis(); + deploymentName = "jc" + now; + + String rsakey = new String("ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAmfk/QSF0pvnrpdz+Ah2KulGruKU+8FFBdlw938MpOysRdmp7uwpH6Z7+5VNGNdxFIAyc/W3UaZXF9hTsU8+78TlwkZpsr2mzU+ycu37XLAQ8Uv7hjsAN0DkKKPrZ9lgUUfZVKV/8E/JIAs03gIbL6zO3y7eYJQ5fNeZb+nji7tQT+YLpGq/FDegvraPKVMQbCSCZhsHyWhdPLyFlu9/30npZ0ahYOPI/KyZxFDtM/pHp88+ZAk9Icq5owaLRWcJQqrBGWqjbZnHtjdDqvHZ+C0wPhdJZPyfkHOrSYTwSQBXfX4JLRRCz3J1jf62MbQWT1o6Y4JEs1ZP1Skxu6zR96Q== mocktest"); + TemplateOptions options = new AzureTemplateOptions() + .DNSLabelPrefix("mydnslabel") + .virtualNetworkAddressPrefix("10.0.0.0/20") + .subnetAddressPrefix("10.0.0.0/25") + .authorizePublicKey(rsakey); + + ((AzureTemplateOptions)options).virtualNetworkName(vnetName); + ((AzureTemplateOptions)options).subnetId(subnetId); + + DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithOptions(options); + + DeploymentBody deploymentTemplateBody = templateBuilder.getDeploymentTemplate(); + + DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody); + + String deploymentTemplate = templateBuilder.getDeploymentTemplateJson(properties); + deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplate); + + Deployment deployment = api().validate(deploymentName, deploymentTemplate); + assertNotNull(deployment); + } + + @Test(groups = "live") public void testValidateDeploymentTemplateLinuxNodeWithSSH() { Long now = System.currentTimeMillis(); deploymentName = "jc" + now; String rsakey = new String("ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAmfk/QSF0pvnrpdz+Ah2KulGruKU+8FFBdlw938MpOysRdmp7uwpH6Z7+5VNGNdxFIAyc/W3UaZXF9hTsU8+78TlwkZpsr2mzU+ycu37XLAQ8Uv7hjsAN0DkKKPrZ9lgUUfZVKV/8E/JIAs03gIbL6zO3y7eYJQ5fNeZb+nji7tQT+YLpGq/FDegvraPKVMQbCSCZhsHyWhdPLyFlu9/30npZ0ahYOPI/KyZxFDtM/pHp88+ZAk9Icq5owaLRWcJQqrBGWqjbZnHtjdDqvHZ+C0wPhdJZPyfkHOrSYTwSQBXfX4JLRRCz3J1jf62MbQWT1o6Y4JEs1ZP1Skxu6zR96Q== mocktest"); - TemplateOptions options = new TemplateOptions(); + AzureTemplateOptions options = new AzureTemplateOptions(); + options.virtualNetworkName(vnetName); + options.subnetId(subnetId); + options.authorizePublicKey(rsakey); DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithOptions(options); @@ -103,8 +175,12 @@ public class TemplateToDeploymentTemplateLiveTest extends BaseAzureComputeApiLiv String rsakey = new String("ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAmfk/QSF0pvnrpdz+Ah2KulGruKU+8FFBdlw938MpOysRdmp7uwpH6Z7+5VNGNdxFIAyc/W3UaZXF9hTsU8+78TlwkZpsr2mzU+ycu37XLAQ8Uv7hjsAN0DkKKPrZ9lgUUfZVKV/8E/JIAs03gIbL6zO3y7eYJQ5fNeZb+nji7tQT+YLpGq/FDegvraPKVMQbCSCZhsHyWhdPLyFlu9/30npZ0ahYOPI/KyZxFDtM/pHp88+ZAk9Icq5owaLRWcJQqrBGWqjbZnHtjdDqvHZ+C0wPhdJZPyfkHOrSYTwSQBXfX4JLRRCz3J1jf62MbQWT1o6Y4JEs1ZP1Skxu6zR96Q== mocktest"); - TemplateOptions options = new TemplateOptions(); + AzureTemplateOptions options = new AzureTemplateOptions(); + options.virtualNetworkName(vnetName); + options.subnetId(subnetId); + options.authorizePublicKey(rsakey); + options.inboundPorts(22, 8080); DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithOptions(options); DeploymentBody deploymentTemplateBody = templateBuilder.getDeploymentTemplate(); @@ -144,7 +220,7 @@ public class TemplateToDeploymentTemplateLiveTest extends BaseAzureComputeApiLiv private Template getTemplate(TemplateOptions options) { Location provider = (new LocationBuilder()).scope(LocationScope.PROVIDER).id("azurecompute-arm").description("azurecompute-arm").build(); - Location region = (new LocationBuilder()).scope(LocationScope.REGION).id("northeurope").description("North Europe").parent(provider).build(); + Location region = (new LocationBuilder()).scope(LocationScope.REGION).id(LOCATION).description(LOCATIONDESCRIPTION).parent(provider).build(); OperatingSystem os = OperatingSystem.builder() .family(OsFamily.UBUNTU) @@ -168,7 +244,10 @@ public class TemplateToDeploymentTemplateLiveTest extends BaseAzureComputeApiLiv } private DeploymentTemplateBuilder getDeploymentTemplateBuilderWithEmptyOptions() { - TemplateOptions options = new TemplateOptions(); + AzureTemplateOptions options = new AzureTemplateOptions(); + options.virtualNetworkName(vnetName); + options.subnetId(subnetId); + Template template = getTemplate(options); DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(resourceGroup, deploymentName, template); return templateBuilder; http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java ---------------------------------------------------------------------- diff --git a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java index f117f1c..5271e2a 100644 --- a/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java +++ b/azurecompute-arm/src/test/java/org/jclouds/azurecompute/arm/features/VirtualMachineApiLiveTest.java @@ -17,6 +17,8 @@ package org.jclouds.azurecompute.arm.features; import com.google.common.base.Predicate; +import com.google.gson.internal.LinkedTreeMap; +import com.google.common.collect.Iterables; import org.jclouds.azurecompute.arm.domain.DataDisk; import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile; import org.jclouds.azurecompute.arm.domain.HardwareProfile; @@ -33,16 +35,28 @@ import org.jclouds.azurecompute.arm.domain.VirtualMachine; import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance; import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties; import org.jclouds.azurecompute.arm.functions.ParseJobStatus; +import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils; import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest; import org.jclouds.util.Predicates2; +import org.jclouds.azurecompute.arm.domain.ResourceDefinition; +import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_PORT_OPEN; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED; +import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED; import static org.testng.Assert.assertNotNull; import java.net.URI; import java.util.ArrayList; import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; import static org.testng.Assert.assertTrue; @@ -60,6 +74,23 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest { nicName = nic.name(); } + @Override + protected Properties setupProperties() { + Properties properties = super.setupProperties(); + long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES); + properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + ""); + properties.setProperty(TIMEOUT_PORT_OPEN, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_TERMINATED, scriptTimeout + ""); + properties.setProperty(TIMEOUT_NODE_SUSPENDED, scriptTimeout + ""); + properties.put(RESOURCE_GROUP_NAME, getResourceGroupName()); + + AzureLiveTestUtils.defaultProperties(properties); + checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint"); + + return properties; + } + private String getName() { if (vmName == null) { vmName = String.format("%3.24s", @@ -70,7 +101,6 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest { @Test public void testCreate() { - StorageAccountApi storageApi = api.getStorageAccountApi(getResourceGroupName()); StorageService storageAccount = storageApi.get(getStorageServiceName()); String blob = storageAccount.storageServiceProperties().primaryEndpoints().get("blob"); @@ -109,22 +139,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest { public void testStop() { api().stop(getName()); //Poll until resource is ready to be used - boolean jobDone = Predicates2.retry(new Predicate<String>() { - @Override - public boolean apply(String name) { - String status = ""; - List<VirtualMachineInstance.VirtualMachineStatus> statuses = api().getInstanceDetails(name).statuses(); - for (int c = 0; c < statuses.size(); c++) { - if (statuses.get(c).code().substring(0, 10).equals("PowerState")) { - status = statuses.get(c).displayStatus(); - break; - } - } - return status.equals("VM stopped"); - } - }, 60 * 4 * 1000).apply(getName()); - assertTrue(jobDone, "stop operation did not complete in the configured timeout"); - + nodeSuspendedPredicate.apply(getName()); } @Test(dependsOnMethods = "testGet") @@ -194,11 +209,53 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest { @Test(dependsOnMethods = "testCreate") public void testList() { List<VirtualMachine> list = api().list(); - VirtualMachine vm = api().get(getName()); - assertTrue(list.contains(vm)); + final VirtualMachine vm = api().get(getName()); + + boolean vmPresent = Iterables.any(list, new Predicate<VirtualMachine>() { + public boolean apply(VirtualMachine input) { + return input.name().equals(vm.name()); + } + }); + + assertTrue(vmPresent); + } + + @Test(dependsOnMethods = "testRestart") + public void testGeneralize() throws IllegalStateException { + api().stop(getName()); + //Poll until resource is ready to be used + + if (nodeSuspendedPredicate.apply(getName())) { + api().generalize(getName()); + } + } + + @Test(dependsOnMethods = "testGeneralize") + public void testCapture() throws IllegalStateException { + URI uri = api().capture(getName(), getName(), getName()); + if (uri != null) { + if (imageAvailablePredicate.apply(uri)) { + List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri); + if (definitions != null) { + for (ResourceDefinition definition : definitions) { + LinkedTreeMap<String, String> properties = (LinkedTreeMap<String, String>) definition.properties(); + Object storageObject = properties.get("storageProfile"); + LinkedTreeMap<String, String> properties2 = (LinkedTreeMap<String, String>) storageObject; + Object osDiskObject = properties2.get("osDisk"); + LinkedTreeMap<String, String> osProperties = (LinkedTreeMap<String, String>) osDiskObject; + Object dataDisksObject = properties2.get("dataDisks"); + ArrayList<Object> dataProperties = (ArrayList<Object>) dataDisksObject; + LinkedTreeMap<String, String> datadiskObject = (LinkedTreeMap<String, String>) dataProperties.get(0); + + Assert.assertNotNull(osProperties.get("name")); + Assert.assertNotNull(datadiskObject.get("name")); + } + } + } + } } - @Test(dependsOnMethods = {"testRestart", "testList", "testGet"}, alwaysRun = true) + @Test(dependsOnMethods = "testCapture", alwaysRun = true) public void testDelete() throws Exception { URI uri = api().delete(getName()); @@ -227,8 +284,10 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest { VHD vhd = VHD.create(blob + "vhds/" + getName() + ".vhd"); VHD vhd2 = VHD.create(blob + "vhds/" + getName() + "data.vhd"); DataDisk dataDisk = DataDisk.create(getName() + "data", "100", 0, vhd2, "Empty"); - OSDisk osDisk = OSDisk.create(null, getName(), vhd, "ReadWrite", "FromImage"); - StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk, null); + List<DataDisk> dataDisks = new ArrayList<DataDisk>(); + dataDisks.add(dataDisk); + OSDisk osDisk = OSDisk.create(null, getName(), vhd, "ReadWrite", "FromImage", null); + StorageProfile storageProfile = StorageProfile.create(imgRef, osDisk, dataDisks); OSProfile.WindowsConfiguration windowsConfig = OSProfile.WindowsConfiguration.create(false, null, null, true, null); OSProfile osProfile = OSProfile.create(getName(), "azureuser", "RFe3&432dg", null, null, windowsConfig);
