You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2016/06/30 22:49:33 UTC
[3/3] jclouds-labs git commit: JCLOUDS-664 Azurecompute-arm image
capture userdata keyvault
JCLOUDS-664 Azurecompute-arm image capture userdata keyvault
Project: http://git-wip-us.apache.org/repos/asf/jclouds-labs/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds-labs/commit/2b36a75f
Tree: http://git-wip-us.apache.org/repos/asf/jclouds-labs/tree/2b36a75f
Diff: http://git-wip-us.apache.org/repos/asf/jclouds-labs/diff/2b36a75f
Branch: refs/heads/master
Commit: 2b36a75f9fb44e84ff82ae51438347b43db225a5
Parents: 5722ec2
Author: Rita Zhang <ri...@gmail.com>
Authored: Mon May 16 18:55:01 2016 -0700
Committer: Ignasi Barrera <na...@apache.org>
Committed: Fri Jul 1 00:30:29 2016 +0200
----------------------------------------------------------------------
azurecompute-arm/pom.xml | 1 +
.../arm/AzureComputeProviderMetadata.java | 8 +-
.../arm/compute/AzureComputeServiceAdapter.java | 103 ++++---
.../AzureComputeServiceContextModule.java | 144 ++++++++-
.../extensions/AzureComputeImageExtension.java | 142 +++++++++
.../functions/DeploymentToNodeMetadata.java | 56 ++--
.../compute/functions/VMHardwareToHardware.java | 23 +-
.../arm/compute/functions/VMImageToImage.java | 29 +-
.../compute/options/AzureTemplateOptions.java | 223 ++++++++++++++
...DefaultLoginCredentialsForImageStrategy.java | 43 +++
.../CreateResourceGroupThenCreateNodes.java | 62 +++-
.../arm/config/AzureComputeProperties.java | 6 +
.../arm/domain/DeploymentTemplate.java | 27 +-
.../arm/domain/KeyVaultReference.java | 46 +++
.../domain/NetworkInterfaceCardProperties.java | 12 +-
.../jclouds/azurecompute/arm/domain/OSDisk.java | 29 +-
.../azurecompute/arm/domain/StorageProfile.java | 1 +
.../arm/domain/TemplateParameterType.java | 34 +++
.../azurecompute/arm/domain/VMDeployment.java | 5 +
.../azurecompute/arm/domain/VMHardware.java | 25 +-
.../azurecompute/arm/domain/VMImage.java | 21 +-
.../azurecompute/arm/features/JobApi.java | 15 +
.../arm/features/VirtualMachineApi.java | 25 ++
.../arm/functions/CleanupResources.java | 96 ++++--
.../arm/functions/StatusCodeParser.java | 38 +++
.../arm/handlers/AzureComputeErrorHandler.java | 7 +-
.../arm/util/DeploymentTemplateBuilder.java | 300 +++++++++++++------
.../AzureComputeServiceContextLiveTest.java | 284 ------------------
.../compute/AzureComputeServiceLiveTest.java | 64 +++-
.../AzureComputeImageExtensionLiveTest.java | 89 ++++++
.../arm/features/DeploymentApiLiveTest.java | 3 +-
.../features/DeploymentTemplateBuilderTest.java | 80 +++--
.../arm/features/JobApiMockTest.java | 23 ++
.../NetworkInterfaceCardApiMockTest.java | 3 +-
.../TemplateToDeploymentTemplateLiveTest.java | 89 +++++-
.../arm/features/VirtualMachineApiLiveTest.java | 103 +++++--
.../arm/features/VirtualMachineApiMockTest.java | 32 +-
.../AbstractAzureComputeApiLiveTest.java | 15 +
.../internal/BaseAzureComputeApiLiveTest.java | 10 +-
azurecompute-arm/src/test/resources/logback.xml | 82 +++++
.../src/test/resources/resourceDefinition.json | 22 ++
41 files changed, 1787 insertions(+), 633 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/pom.xml
----------------------------------------------------------------------
diff --git a/azurecompute-arm/pom.xml b/azurecompute-arm/pom.xml
index 33251fd..5a41e44 100644
--- a/azurecompute-arm/pom.xml
+++ b/azurecompute-arm/pom.xml
@@ -156,6 +156,7 @@
<goal>test</goal>
</goals>
<configuration>
+ <threadCount>1</threadCount>
<systemPropertyVariables>
<test.azurecompute-arm.endpoint>${test.azurecompute-arm.endpoint}</test.azurecompute-arm.endpoint>
<test.azurecompute-arm.api-version>${test.azurecompute-arm.api-version}</test.azurecompute-arm.api-version>
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
index 4bbc508..460df67 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
@@ -24,6 +24,9 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATI
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
@@ -70,7 +73,10 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
properties.put(RESOURCE, "https://management.azure.com/");
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
properties.put(RESOURCE_GROUP_NAME, "jcloudsgroup");
- properties.put(IMAGE_PUBLISHERS, "Microsoft.WindowsAzure.Compute, MicrosoftWindowsServer, Canonical");
+ properties.put(DEFAULT_VNET_ADDRESS_SPACE_PREFIX, "10.0.0.0/16");
+ properties.put(DEFAULT_SUBNET_ADDRESS_PREFIX, "10.0.0.0/24");
+ properties.put(DEFAULT_DATADISKSIZE, "100");
+ properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
properties.put(DEFAULT_IMAGE_LOGIN, "jclouds:Password1!");
properties.put(TIMEOUT_NODE_TERMINATED, 60 * 10 * 1000);
return properties;
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
index 9a1d221..3d87d6d 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -18,9 +18,11 @@ package org.jclouds.azurecompute.arm.compute;
import static java.lang.String.format;
import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_PREFIX;
import static org.jclouds.util.Predicates2.retry;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -40,15 +42,14 @@ import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
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.ResourceProviderMetaData;
import org.jclouds.azurecompute.arm.domain.VMImage;
import org.jclouds.azurecompute.arm.domain.VMHardware;
import org.jclouds.azurecompute.arm.domain.Location;
import org.jclouds.azurecompute.arm.domain.Offer;
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
-import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
import org.jclouds.azurecompute.arm.domain.SKU;
import org.jclouds.azurecompute.arm.domain.VMDeployment;
-import org.jclouds.azurecompute.arm.domain.VMSize;
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
import org.jclouds.azurecompute.arm.features.DeploymentApi;
import org.jclouds.azurecompute.arm.features.OSImageApi;
@@ -60,6 +61,8 @@ import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.logging.Logger;
import org.jclouds.azurecompute.arm.functions.CleanupResources;
+import org.jclouds.azurecompute.arm.domain.VMSize;
+import org.jclouds.azurecompute.arm.domain.Version;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
@@ -118,15 +121,13 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
logger.debug("Deployment created with name: %s group: %s", name, group);
-
final Set<VMDeployment> deployments = Sets.newHashSet();
- final DeploymentApi deploymentApi = api.getDeploymentApi(group);
+ final DeploymentApi deploymentApi = api.getDeploymentApi(azureGroup);
if (!retry(new Predicate<String>() {
@Override
public boolean apply(final String name) {
-
Deployment deployment = deploymentApi.create(name, deploymentTemplate);
if (deployment != null) {
@@ -149,8 +150,18 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
final VMDeployment deployment = deployments.iterator().next();
- return new NodeAndInitialCredentials<VMDeployment>(deployment, name,
- LoginCredentials.builder().user(loginUser).identity(loginUser).password(loginPassword).authenticateSudo(true).build());
+ NodeAndInitialCredentials<VMDeployment> credential = null;
+
+ if (template.getOptions().getPublicKey() != null){
+ String privateKey = template.getOptions().getPrivateKey();
+ credential = new NodeAndInitialCredentials<VMDeployment>(deployment, name,
+ LoginCredentials.builder().user(loginUser).privateKey(privateKey).authenticateSudo(true).build());
+ } else {
+ credential = new NodeAndInitialCredentials<VMDeployment>(deployment, name,
+ LoginCredentials.builder().user(loginUser).password(loginPassword).authenticateSudo(true).build());
+ }
+
+ return credential;
}
@Override
@@ -166,17 +177,17 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
for (VMSize vmSize : vmSizes){
- VMHardware hwProfile = new VMHardware();
- hwProfile.name = vmSize.name();
- hwProfile.numberOfCores = vmSize.numberOfCores();
- hwProfile.osDiskSizeInMB = vmSize.osDiskSizeInMB();
- hwProfile.resourceDiskSizeInMB = vmSize.resourceDiskSizeInMB();
- hwProfile.memoryInMB = vmSize.memoryInMB();
- hwProfile.maxDataDiskCount = vmSize.maxDataDiskCount();
- hwProfile.location = location.name();
+ VMHardware hwProfile = VMHardware.create(
+ vmSize.name(),
+ vmSize.numberOfCores(),
+ vmSize.osDiskSizeInMB(),
+ vmSize.resourceDiskSizeInMB(),
+ vmSize.memoryInMB(),
+ vmSize.maxDataDiskCount(),
+ location.name(),
+ false);
hwProfiles.add(hwProfile);
}
-
}
checkAndSetHwAvailability(hwProfiles, Sets.newHashSet(locationIds));
@@ -186,32 +197,33 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
private void checkAndSetHwAvailability(List<VMHardware> hwProfiles, Collection<String> locations) {
Multimap<String, String> hwMap = ArrayListMultimap.create();
for (VMHardware hw : hwProfiles) {
- hwMap.put(hw.name, hw.location);
+ hwMap.put(hw.name(), hw.location());
}
- for (VMHardware hw : hwProfiles) {
- hw.globallyAvailable = hwMap.get(hw.name).containsAll(locations);
- }
+ /// TODO
+ // for (VMHardware hw : hwProfiles) {
+ // hw.globallyAvailable() = hwMap.get(hw.name()).containsAll(locations);
+ // }
}
private void getImagesFromPublisher(String publisherName, List<VMImage> osImagesRef, String location) {
- OSImageApi osImageApi = api.getOSImageApi(location);
+ 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) {
- VMImage vmImage = new VMImage();
- vmImage.publisher = publisherName;
- vmImage.offer = offer.name();
- vmImage.sku = sku.name();
- vmImage.location = location;
- osImagesRef.add(vmImage);
+ Iterable<Version> versionList = osImageApi.listVersions(publisherName, offer.name(), sku.name());
+ for (Version version : versionList) {
+ VMImage vmImage = VMImage.create(publisherName, offer.name(), sku.name(), version.name(), location, false);
+ osImagesRef.add(vmImage);
+ }
}
}
+
}
private List<VMImage> listImagesByLocation(String location) {
@@ -241,17 +253,23 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
Multimap<String, String> map = ArrayListMultimap.create();
for (VMImage image : images) {
- map.put( image.offer + "/" + image.sku, image.location);
- }
-
- for (VMImage image : images) {
- image.globallyAvailable = map.get(image.offer + "/" + image.sku).containsAll(locations);
+ map.put( image.offer() + "/" + image.sku(), image.location());
}
+ ///TODO
+ // for (VMImage image : images) {
+ // image.globallyAvailable() = map.get(image.offer() + "/" + image.sku()).containsAll(locations);
+ // }
}
@Override
public VMImage getImage(final String id) {
String[] fields = VMImageToImage.decodeFieldsFromUniqueId(id);
+ if (fields[2].startsWith(CUSTOM_IMAGE_PREFIX)) {
+ String storage = fields[2].substring(CUSTOM_IMAGE_PREFIX.length());
+ String vhd = fields[3];
+ VMImage ref = VMImage.create(CUSTOM_IMAGE_PREFIX + azureGroup, CUSTOM_IMAGE_PREFIX + storage, vhd, null, fields[0], false);
+ return ref;
+ }
Iterable<VMImage> images = listImages();
@@ -266,6 +284,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
@Override
public Iterable<Location> listLocations() {
+
List<Location> locations = api.getLocationApi().list();
List<ResourceProviderMetaData> resources = api.getResourceProviderApi().get("Microsoft.Compute");
@@ -286,7 +305,7 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
}
});
- return result;
+ return result;
}
private String getResourceGroupFromId(String id) {
@@ -309,9 +328,15 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
vmDeployment.deployment = deployment;
List<PublicIPAddress> list = getIPAddresses(deployment);
vmDeployment.ipAddressList = list;
-
VirtualMachine vm = api.getVirtualMachineApi(azureGroup).get(id);
vmDeployment.virtualMachine = vm;
+ vmDeployment.vm = api.getVirtualMachineApi(azureGroup).getInstanceDetails(id);
+ if (vm != null && vm.tags() != null) {
+ vmDeployment.userMetaData = vm.tags();
+ String tagString = vmDeployment.userMetaData.get("tags");
+ List<String> tags = Arrays.asList(tagString.split(","));
+ vmDeployment.tags = tags;
+ }
return vmDeployment;
}
@@ -372,9 +397,15 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
List<PublicIPAddress> list = getIPAddresses(d);
vmDeployment.ipAddressList = list;
- VirtualMachine virtualMachine = vmApi.get(d.name());
- vmDeployment.virtualMachine = virtualMachine;
+ VirtualMachine vm = vmApi.get(d.name());
+ vmDeployment.virtualMachine = vm;
+ if (vm != null && vm.tags() != null) {
+ vmDeployment.userMetaData = vm.tags();
+ String tagString = vmDeployment.userMetaData.get("tags");
+ List<String> tags = Arrays.asList(tagString.split(","));
+ vmDeployment.tags = tags;
+ }
vmDeployments.add(vmDeployment);
}
return vmDeployments;
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
index 9844be4..7df8111 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
@@ -16,34 +16,56 @@
*/
package org.jclouds.azurecompute.arm.compute.config;
+import javax.annotation.Resource;
import javax.inject.Named;
import javax.inject.Singleton;
+
import com.google.inject.Provides;
import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter;
+import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension;
import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
import org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata;
import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware;
import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation;
+import org.jclouds.azurecompute.arm.compute.strategy.AzurePopulateDefaultLoginCredentialsForImageStrategy;
+import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
+import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
import org.jclouds.azurecompute.arm.domain.VMDeployment;
import org.jclouds.azurecompute.arm.domain.VMHardware;
import org.jclouds.azurecompute.arm.domain.VMImage;
import org.jclouds.azurecompute.arm.domain.Location;
import org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes;
import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
-import org.jclouds.azurecompute.arm.compute.AzureComputeService;
-
+import org.jclouds.compute.options.TemplateOptions;
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.reference.ComputeServiceConstants;
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
-import org.jclouds.compute.ComputeService;
+
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
+
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
import static org.jclouds.util.Predicates2.retry;
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
import com.google.common.base.Function;
import com.google.inject.Inject;
@@ -52,21 +74,22 @@ import com.google.common.base.Predicate;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.annotations.VisibleForTesting;
import java.net.URI;
+import java.util.List;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_INITIAL_PERIOD;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
+import org.jclouds.azurecompute.arm.compute.AzureComputeService;
+import org.jclouds.compute.ComputeService;
+import org.jclouds.logging.Logger;
public class AzureComputeServiceContextModule
extends ComputeServiceAdapterContextModule<VMDeployment, VMHardware, VMImage, Location> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
@Override
protected void configure() {
super.configure();
@@ -84,7 +107,12 @@ public class AzureComputeServiceContextModule
install(new LocationsFromComputeServiceAdapterModule<VMDeployment, VMHardware, VMImage, Location>() {
});
+ bind(TemplateOptions.class).to(AzureTemplateOptions.class);
+ bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(AzurePopulateDefaultLoginCredentialsForImageStrategy.class);
+ //bind(TemplateOptionsToStatement.class).to(TemplateOptionsToStatementWithoutPublicKey.class);
bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class);
+ bind(new TypeLiteral<ImageExtension>() {
+ }).to(AzureComputeImageExtension.class);
}
@Singleton
@@ -122,6 +150,18 @@ public class AzureComputeServiceContextModule
@Inject
private String azureDefaultImageLoginProperty;
+ @Named(DEFAULT_VNET_ADDRESS_SPACE_PREFIX)
+ @Inject
+ private String azureDefaultVnetAddressPrefixProperty;
+
+ @Named(DEFAULT_SUBNET_ADDRESS_PREFIX)
+ @Inject
+ private String azureDefaultSubnetAddressPrefixProperty;
+
+ @Named(DEFAULT_DATADISKSIZE)
+ @Inject
+ private String azureDefaultDataDiskSizeProperty;
+
public Long operationTimeout() {
return Long.parseLong(operationTimeoutProperty);
}
@@ -138,6 +178,18 @@ public class AzureComputeServiceContextModule
return azureDefaultImageLoginProperty;
}
+ public String azureDefaultVnetAddressPrefixProperty() {
+ return azureDefaultVnetAddressPrefixProperty;
+ }
+
+ public String azureDefaultSubnetAddressPrefixProperty() {
+ return azureDefaultSubnetAddressPrefixProperty;
+ }
+
+ public String azureDefaultDataDiskSizeProperty() {
+ return azureDefaultDataDiskSizeProperty;
+ }
+
public Integer operationPollInitialPeriod() {
return Integer.parseInt(operationPollInitialPeriodProperty);
}
@@ -158,19 +210,39 @@ public class AzureComputeServiceContextModule
@Provides
@Named(TIMEOUT_NODE_TERMINATED)
protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, Timeouts timeouts,
- PollPeriod pollPeriod) {
+ PollPeriod pollPeriod) {
return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
pollPeriod.pollMaxPeriod);
}
@Provides
+ @Named(TIMEOUT_IMAGE_AVAILABLE)
+ protected Predicate<URI> provideImageAvailablePredicate(final AzureComputeApi api, Timeouts timeouts,
+ PollPeriod pollPeriod) {
+ return retry(new ImageDonePredicate(api), timeouts.imageAvailable, pollPeriod.pollInitialPeriod,
+ pollPeriod.pollMaxPeriod);
+ }
+
+ @Provides
@Named(TIMEOUT_RESOURCE_DELETED)
protected Predicate<URI> provideResourceDeletedPredicate(final AzureComputeApi api, Timeouts timeouts,
- PollPeriod pollPeriod) {
+ PollPeriod pollPeriod) {
return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
pollPeriod.pollMaxPeriod);
}
+ @Provides
+ @Named(TIMEOUT_NODE_SUSPENDED)
+ protected Predicate<String> provideNodeSuspendedPredicate(final AzureComputeApi api,
+ final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
+ Timeouts timeouts,
+ PollPeriod pollPeriod) {
+
+ String azureGroup = azureComputeConstants.azureResourceGroup();
+ return retry(new NodeSuspendedPredicate(api, azureGroup), timeouts.nodeSuspended, pollPeriod.pollInitialPeriod,
+ pollPeriod.pollMaxPeriod);
+ }
+
@VisibleForTesting
static class ActionDonePredicate implements Predicate<URI> {
@@ -183,9 +255,51 @@ public class AzureComputeServiceContextModule
@Override
public boolean apply(URI uri) {
checkNotNull(uri, "uri cannot be null");
- return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
+ return (ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri)) || (ParseJobStatus.JobStatus.NO_CONTENT == api.getJobApi().jobStatus(uri));
}
}
+ @VisibleForTesting
+ static class ImageDonePredicate implements Predicate<URI> {
+
+ private final AzureComputeApi api;
+
+ public ImageDonePredicate(AzureComputeApi api) {
+ this.api = checkNotNull(api, "api must not be null");
+ }
+
+ @Override
+ public boolean apply(URI uri) {
+ checkNotNull(uri, "uri cannot be null");
+ List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
+ return definitions != null;
+ }
+ }
+
+ @VisibleForTesting
+ static class NodeSuspendedPredicate implements Predicate<String> {
+
+ private final AzureComputeApi api;
+ private final String azureGroup;
+
+ public NodeSuspendedPredicate(AzureComputeApi api, String azureGroup) {
+ this.api = checkNotNull(api, "api must not be null");
+ this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
+ }
+
+ @Override
+ public boolean apply(String name) {
+ checkNotNull(name, "name cannot be null");
+ String status = "";
+ List<VirtualMachineInstance.VirtualMachineStatus> statuses = api.getVirtualMachineApi(this.azureGroup).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");
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/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
new file mode 100644
index 0000000..626f511
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
@@ -0,0 +1,142 @@
+/*
+ * 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.common.base.Predicate;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.gson.internal.LinkedTreeMap;
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import org.jclouds.Constants;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
+import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
+import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
+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.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
+
+import static java.lang.String.format;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+
+import com.google.common.util.concurrent.UncheckedTimeoutException;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+
+public class AzureComputeImageExtension implements ImageExtension {
+ private final AzureComputeApi api;
+ private final Predicate<URI> imageAvailablePredicate;
+ private final Predicate<String> nodeSuspendedPredicate;
+ private final AzureComputeConstants azureComputeConstants;
+ private final ListeningExecutorService userExecutor;
+ private final String group;
+ private final VMImageToImage imageReferenceToImage;
+ public static final String CONTAINER_NAME = "vhdsnew";
+ public static final String CUSTOM_IMAGE_PREFIX = "#";
+
+ @Inject
+ AzureComputeImageExtension(AzureComputeApi api,
+ @Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> imageAvailablePredicate,
+ @Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> nodeSuspendedPredicate,
+ final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
+ @Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
+ VMImageToImage imageReferenceToImage) {
+ this.userExecutor = userExecutor;
+ this.group = azureComputeConstants.azureResourceGroup();
+ this.imageReferenceToImage = imageReferenceToImage;
+ this.api = api;
+ this.imageAvailablePredicate = imageAvailablePredicate;
+ this.nodeSuspendedPredicate = nodeSuspendedPredicate;
+ this.azureComputeConstants = azureComputeConstants;
+ }
+
+ @Override
+ public ImageTemplate buildImageTemplateFromNode(String name, String id) {
+ String imageName = name.toLowerCase();
+ return new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(imageName).build();
+ }
+
+ @Override
+ public ListenableFuture<Image> createImage(ImageTemplate template) {
+ final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
+ final String id = cloneTemplate.getSourceNodeId();
+ final String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "stor";
+
+ // VM needs to be stopped before it can be generalized
+ String status = "";
+ api.getVirtualMachineApi(group).stop(id);
+ //Poll until resource is ready to be used
+ if (nodeSuspendedPredicate.apply(id)) {
+ return userExecutor.submit(new Callable<Image>() {
+ @Override
+ public Image call() throws Exception {
+ api.getVirtualMachineApi(group).generalize(id);
+
+ final String[] disks = new String[2];
+ URI uri = api.getVirtualMachineApi(group).capture(id, cloneTemplate.getName(), CONTAINER_NAME);
+ 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);
+
+ disks[0] = osProperties.get("name");
+ disks[1] = datadiskObject.get("name");
+
+ VirtualMachine vm = api.getVirtualMachineApi(group).get(id);
+ String location = vm.location();
+ final VMImage ref = VMImage.create(CUSTOM_IMAGE_PREFIX + group, CUSTOM_IMAGE_PREFIX + storageAccountName, disks[0], disks[1], location, false);
+ return imageReferenceToImage.apply(ref);
+ }
+ }
+ }
+ }
+ throw new UncheckedTimeoutException("Image was not created within the time limit: "
+ + cloneTemplate.getName());
+ }
+ });
+ } else {
+ final String illegalStateExceptionMessage = format("Node %s was not suspended within %sms.",
+ id, azureComputeConstants.operationTimeout());
+ throw new IllegalStateException(illegalStateExceptionMessage);
+ }
+ }
+
+ @Override
+ public boolean deleteImage(String id) {
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
index bccc63c..40e09b7 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/DeploymentToNodeMetadata.java
@@ -48,6 +48,7 @@ import org.jclouds.compute.domain.Hardware;
public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMetadata> {
+ public static final String JCLOUDS_DEFAULT_USERNAME = "root";
public static final String AZURE_LOGIN_USERNAME = DeploymentTemplateBuilder.getLoginUserUsername();
public static final String AZURE_LOGIN_PASSWORD = DeploymentTemplateBuilder.getLoginPassword();
@@ -116,6 +117,10 @@ public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMeta
builder.name(deployment.name());
String group = this.nodeNamingConvention.extractGroup(deployment.name());
builder.group(group);
+ if (from.tags != null)
+ builder.tags(from.tags);
+ if (from.userMetaData != null)
+ builder.userMetadata(from.userMetaData);
NodeMetadata.Status status = STATUS_TO_NODESTATUS.get(provisioningStateFromString(deployment.properties().provisioningState()));
if (status == NodeMetadata.Status.RUNNING && from.vm != null && from.vm.statuses() != null) {
@@ -134,9 +139,25 @@ public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMeta
builder.status(status);
+ if (from.vm != null) {
+ builder.hostname(deployment.name() + "pc");
+ }
+
Credentials credentials = credentialStore.get("node#" + from.deployment.name());
- if (credentials == null) {
- credentials = new Credentials(AZURE_LOGIN_USERNAME, AZURE_LOGIN_PASSWORD);
+ if (credentials != null && credentials.identity.equals(JCLOUDS_DEFAULT_USERNAME)) {
+ credentials = new Credentials(AZURE_LOGIN_USERNAME, credentials.credential);
+ }
+ else if (credentials == null) {
+ String username = AZURE_LOGIN_USERNAME;
+ String password = AZURE_LOGIN_PASSWORD;
+ if (username == null) {
+ username = "jclouds";
+ }
+ if (password == null) {
+ password = "Password1!";
+ }
+
+ credentials = new Credentials(username, password);
}
builder.credentials(LoginCredentials.fromCredentials(credentials));
@@ -149,7 +170,6 @@ public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMeta
publicIpAddresses.add(ip.properties().ipAddress());
break;
}
-
}
if (publicIpAddresses.size() > 0)
builder.publicAddresses(publicIpAddresses);
@@ -171,13 +191,12 @@ public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMeta
ImageReference imageReference = from.virtualMachine.properties().storageProfile().imageReference();
- VMImage vmImage = new VMImage();
- vmImage.publisher = imageReference.publisher();
- vmImage.offer = imageReference.offer();
- vmImage.sku = imageReference.sku();
- vmImage.location = locationName;
- Image image = vmImageToImage.apply(vmImage);
- builder.imageId(image.getId());
+ if (imageReference != null) {
+ VMImage vmImage = VMImage.create(imageReference.publisher(), imageReference.offer(), imageReference.sku(),
+ imageReference.version(), locationName, false);
+ Image image = vmImageToImage.apply(vmImage);
+ builder.imageId(image.getId());
+ }
VMSize myVMSize = null;
String vmSizeName = from.virtualMachine.properties().hardwareProfile().vmSize();
@@ -189,14 +208,15 @@ public class DeploymentToNodeMetadata implements Function<VMDeployment, NodeMeta
}
}
- VMHardware hwProfile = new VMHardware();
- hwProfile.name = myVMSize.name();
- hwProfile.numberOfCores = myVMSize.numberOfCores();
- hwProfile.osDiskSizeInMB = myVMSize.osDiskSizeInMB();
- hwProfile.resourceDiskSizeInMB = myVMSize.resourceDiskSizeInMB();
- hwProfile.memoryInMB = myVMSize.memoryInMB();
- hwProfile.maxDataDiskCount = myVMSize.maxDataDiskCount();
- hwProfile.location = locationName;
+ VMHardware hwProfile = VMHardware.create(
+ myVMSize.name(),
+ myVMSize.numberOfCores(),
+ myVMSize.osDiskSizeInMB(),
+ myVMSize.resourceDiskSizeInMB(),
+ myVMSize.memoryInMB(),
+ myVMSize.maxDataDiskCount(),
+ locationName,
+ false);
Hardware hardware = vmHardwareToHardware.apply(hwProfile);
builder.hardware(hardware);
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
index 51a6e5e..5303e25 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMHardwareToHardware.java
@@ -47,30 +47,31 @@ public class VMHardwareToHardware implements Function<VMHardware, Hardware> {
@Override
public Hardware apply(VMHardware from) {
final HardwareBuilder builder = new HardwareBuilder()
- .name(from.name)
- .id(from.name)
- .processors(ImmutableList.of(new Processor(from.numberOfCores, 2)))
- .ram(from.memoryInMB)
- .location(from.globallyAvailable ? null : FluentIterable.from(locations.get())
- .firstMatch(LocationPredicates.idEquals(from.location))
+ .name(from.name())
+ .providerId(from.name())
+ .id(from.name())
+ .processors(ImmutableList.of(new Processor(from.numberOfCores(), 2)))
+ .ram(from.memoryInMB())
+ .location(from.globallyAvailable() ? null : FluentIterable.from(locations.get())
+ .firstMatch(LocationPredicates.idEquals(from.location()))
.get());
// No id or providerId from Azure
- if (from.resourceDiskSizeInMB != null) {
+ if (from.resourceDiskSizeInMB() != null) {
builder.volume(new VolumeBuilder()
- .size(Float.valueOf(from.resourceDiskSizeInMB))
+ .size(Float.valueOf(from.resourceDiskSizeInMB()))
.type(Volume.Type.LOCAL)
.build());
}
- if (from.osDiskSizeInMB != null) {
+ if (from.osDiskSizeInMB() != null) {
builder.volume(new VolumeBuilder()
- .size(Float.valueOf(from.osDiskSizeInMB))
+ .size(Float.valueOf(from.osDiskSizeInMB()))
.type(Volume.Type.LOCAL)
.build());
}
ImmutableMap.Builder<String, String> metadata = ImmutableMap.builder();
- metadata.put("maxDataDiskCount", String.valueOf(from.maxDataDiskCount));
+ metadata.put("maxDataDiskCount", String.valueOf(from.maxDataDiskCount()));
builder.userMetadata(metadata.build());
return builder.build();
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
index 65a3d4b..75bcc0e 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/functions/VMImageToImage.java
@@ -17,6 +17,8 @@
package org.jclouds.azurecompute.arm.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_PASSWORD;
+import static org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_USERNAME;
import com.google.common.base.Supplier;
import com.google.common.collect.FluentIterable;
@@ -29,7 +31,9 @@ import org.jclouds.compute.domain.OsFamily;
import com.google.common.base.Function;
import com.google.inject.Inject;
+import org.jclouds.domain.Credentials;
import org.jclouds.domain.Location;
+import org.jclouds.domain.LoginCredentials;
import org.jclouds.location.predicates.LocationPredicates;
import java.util.Set;
@@ -59,7 +63,7 @@ public class VMImageToImage implements Function<VMImage, Image> {
private final Supplier<Set<? extends org.jclouds.domain.Location>> locations;
public static String encodeFieldsToUniqueId(VMImage imageReference){
- return (imageReference.globallyAvailable ? "global" : imageReference.location) + "/" + imageReference.publisher + "/" + imageReference.offer + "/" + imageReference.sku;
+ return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.publisher() + "/" + imageReference.offer() + "/" + imageReference.sku();
}
public static String[] decodeFieldsFromUniqueId(final String id) {
@@ -74,18 +78,19 @@ public class VMImageToImage implements Function<VMImage, Image> {
@Override
public Image apply(final VMImage image) {
+ Credentials credentials = new Credentials(AZURE_LOGIN_USERNAME, AZURE_LOGIN_PASSWORD);
final ImageBuilder builder = new ImageBuilder()
- .name(image.offer)
- .description(image.sku)
+ .name(image.offer())
+ .description(image.sku())
.status(Image.Status.AVAILABLE)
- .version(image.sku)
+ .version(image.sku())
.id(encodeFieldsToUniqueId(image))
- .providerId(image.publisher)
- .location(image.globallyAvailable ? null : FluentIterable.from(locations.get())
- .firstMatch(LocationPredicates.idEquals(image.location))
+ .defaultCredentials(LoginCredentials.fromCredentials(credentials))
+ .providerId(image.publisher())
+ .location(image.globallyAvailable() ? null : FluentIterable.from(locations.get())
+ .firstMatch(LocationPredicates.idEquals(image.location()))
.get());
-
final OperatingSystem.Builder osBuilder = osFamily().apply(image);
return builder.operatingSystem(osBuilder.build()).build();
}
@@ -94,8 +99,8 @@ public class VMImageToImage implements Function<VMImage, Image> {
return new Function<VMImage, OperatingSystem.Builder>() {
@Override
public OperatingSystem.Builder apply(final VMImage image) {
- checkNotNull(image.offer, "offer");
- final String label = image.offer;
+ checkNotNull(image.offer(), "offer");
+ final String label = image.offer();
OsFamily family = OsFamily.UNRECOGNIZED;
if (label.contains(CENTOS)) {
@@ -116,8 +121,8 @@ public class VMImageToImage implements Function<VMImage, Image> {
return OperatingSystem.builder().
family(family).
is64Bit(true).
- description(image.sku).
- version(image.sku);
+ description(image.sku()).
+ version(image.sku());
}
};
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
new file mode 100644
index 0000000..c5267b1
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/options/AzureTemplateOptions.java
@@ -0,0 +1,223 @@
+/*
+ * 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.options;
+
+import static com.google.common.base.Objects.equal;
+import org.jclouds.compute.options.TemplateOptions;
+import com.google.common.base.Objects;
+
+/**
+ * Azure ARM custom options
+ */
+public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
+
+
+ private String customData;
+ private String virtualNetworkAddressPrefix;
+ private String subnetAddressPrefix;
+ private String DNSLabelPrefix;
+ private String keyVaultIdAndSecret;
+
+
+ /**
+ * Custom options for the Azure ARM API
+ */
+ public AzureTemplateOptions customData(String customData) {
+ this.customData = customData;
+ return this;
+ }
+ private String virtualNetworkName;
+ private String subnetId;
+
+ /**
+ * Sets the CIDR block for virtual network
+ */
+ public AzureTemplateOptions virtualNetworkAddressPrefix(String virtualNetworkAddressPrefix) {
+ this.virtualNetworkAddressPrefix = virtualNetworkAddressPrefix;
+ return this;
+ }
+
+ /**
+ * Sets the CIDR block for subnet within virtual network
+ */
+ public AzureTemplateOptions subnetAddressPrefix(String subnetAddressPrefix) {
+ this.subnetAddressPrefix = subnetAddressPrefix;
+ return this;
+ }
+
+ /**
+ * Sets the DNS label prefix for public IP address. label.location.cloudapp.azure.com
+ */
+ public AzureTemplateOptions DNSLabelPrefix(String DNSLabelPrefix) {
+ this.DNSLabelPrefix = DNSLabelPrefix;
+ return this;
+ }
+
+ /**
+ * Sets the KeyVault id and secret separated with ":"
+ */
+ public AzureTemplateOptions keyVaultIdAndSecret(String keyVaultIdAndSecret) {
+ this.keyVaultIdAndSecret = keyVaultIdAndSecret;
+ return this;
+ }
+
+ public String getCustomData() { return customData; }
+ public String getVirtualNetworkAddressPrefix() { return virtualNetworkAddressPrefix; }
+ public String getSubnetAddressPrefix() { return subnetAddressPrefix; }
+ public String getDNSLabelPrefix() { return DNSLabelPrefix; }
+ public String getKeyVaultIdAndSecret() { return keyVaultIdAndSecret; }
+ public String getVirtualNetworkName() { return virtualNetworkName; }
+ public String getSubnetId() { return subnetId; }
+
+
+ /**
+ * Sets the virtual network name
+ */
+ public AzureTemplateOptions virtualNetworkName(String virtualNetworkName) {
+ this.virtualNetworkName = virtualNetworkName;
+ return this;
+ }
+
+ /**
+ * Sets the subnet name
+ */
+ public AzureTemplateOptions subnetId(String subnetId) {
+ this.subnetId = subnetId;
+ return this;
+ }
+
+ @Override
+ public AzureTemplateOptions clone() {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ copyTo(options);
+ return options;
+ }
+
+ @Override
+ public void copyTo(TemplateOptions to) {
+ super.copyTo(to);
+ if (to instanceof AzureTemplateOptions) {
+ AzureTemplateOptions eTo = AzureTemplateOptions.class.cast(to);
+ eTo.customData(customData);
+ eTo.virtualNetworkAddressPrefix(virtualNetworkAddressPrefix);
+ eTo.subnetAddressPrefix(subnetAddressPrefix);
+ eTo.DNSLabelPrefix(DNSLabelPrefix);
+ eTo.keyVaultIdAndSecret(keyVaultIdAndSecret);
+ eTo.virtualNetworkName(virtualNetworkName);
+ eTo.subnetId(subnetId);
+ }
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(super.hashCode(), virtualNetworkAddressPrefix, subnetAddressPrefix, DNSLabelPrefix, customData, keyVaultIdAndSecret, virtualNetworkName, subnetId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!super.equals(obj)) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ AzureTemplateOptions other = (AzureTemplateOptions) obj;
+ return super.equals(other)
+ && equal(this.customData, other.customData)
+ && equal(this.virtualNetworkAddressPrefix, other.virtualNetworkAddressPrefix)
+ && equal(this.subnetAddressPrefix, other.subnetAddressPrefix)
+ && equal(this.DNSLabelPrefix, other.DNSLabelPrefix)
+ && equal(this.keyVaultIdAndSecret, other.keyVaultIdAndSecret)
+ && equal(this.virtualNetworkName, other.virtualNetworkName)
+ && equal(this.subnetId, other.subnetId);
+ }
+
+ @Override
+ public Objects.ToStringHelper string() {
+ Objects.ToStringHelper toString = super.string().omitNullValues();
+ toString.add("customData", customData);
+ toString.add("virtualNetworkAddressPrefix", virtualNetworkAddressPrefix);
+ toString.add("subnetAddressPrefix", subnetAddressPrefix);
+ toString.add("DNSLabelPrefix", DNSLabelPrefix);
+ toString.add("keyVaultIdAndSecret", keyVaultIdAndSecret);
+ toString.add("virtualNetworkName", virtualNetworkName);
+ toString.add("subnetId", subnetId);
+ return toString;
+ }
+
+ public static class Builder {
+
+ /**
+ * @see AzureTemplateOptions#customData
+ */
+ public static AzureTemplateOptions customData(String customData) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.customData(customData);
+ }
+
+ /**
+ * @see AzureTemplateOptions#virtualNetworkAddressPrefix
+ */
+ public static AzureTemplateOptions virtualNetworkAddressPrefix(String virtualNetworkAddressPrefix) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.virtualNetworkAddressPrefix(virtualNetworkAddressPrefix);
+ }
+
+ /**
+ * @see AzureTemplateOptions#subnetAddressPrefix
+ */
+ public static AzureTemplateOptions subnetAddressPrefix(String subnetAddressPrefix) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.subnetAddressPrefix(subnetAddressPrefix);
+ }
+
+ /**
+ * @see AzureTemplateOptions#DNSLabelPrefix
+ */
+ public static AzureTemplateOptions DNSLabelPrefix(String DNSLabelPrefix) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.DNSLabelPrefix(DNSLabelPrefix);
+ }
+
+ /**
+ * @see AzureTemplateOptions#keyVaultIdAndSecret
+ */
+ public static AzureTemplateOptions keyVaultIdAndSecret(String keyVaultIdAndSecret) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.keyVaultIdAndSecret(keyVaultIdAndSecret);
+ }
+
+ /**
+ * @see AzureTemplateOptions#virtualNetworkName
+ */
+ public static AzureTemplateOptions virtualNetworkName(String virtualNetworkName) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.virtualNetworkName(virtualNetworkName);
+ }
+
+ /**
+ * @see AzureTemplateOptions#subnetId
+ */
+ public static AzureTemplateOptions subnetId(String subnetId) {
+ AzureTemplateOptions options = new AzureTemplateOptions();
+ return options.subnetId(subnetId);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
new file mode 100644
index 0000000..55d1a3c
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/AzurePopulateDefaultLoginCredentialsForImageStrategy.java
@@ -0,0 +1,43 @@
+/*
+ * 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.strategy;
+
+import org.jclouds.compute.domain.internal.ImageImpl;
+import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
+import org.jclouds.domain.Credentials;
+import org.jclouds.domain.LoginCredentials;
+
+import static org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_PASSWORD;
+import static org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata.AZURE_LOGIN_USERNAME;
+
+public class AzurePopulateDefaultLoginCredentialsForImageStrategy implements PopulateDefaultLoginCredentialsForImageStrategy {
+ @Override
+ public LoginCredentials apply(Object o) {
+ ImageImpl node = (ImageImpl)o;
+ String username = AZURE_LOGIN_USERNAME;
+ String password = AZURE_LOGIN_PASSWORD;
+ if (username == null) {
+ username = "jclouds";
+ }
+ if (password == null) {
+ password = "Password1!";
+ }
+ Credentials creds = new Credentials(username, password);
+ LoginCredentials credentials = LoginCredentials.fromCredentials(creds);
+ return credentials;
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
index 6900f17..468b87c 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/strategy/CreateResourceGroupThenCreateNodes.java
@@ -18,6 +18,7 @@ package org.jclouds.azurecompute.arm.compute.strategy;
import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Arrays;
import java.util.Map;
import java.util.Set;
@@ -28,8 +29,13 @@ import javax.inject.Singleton;
import com.google.common.collect.ImmutableMap;
import org.jclouds.Constants;
+import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
+import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
+import org.jclouds.azurecompute.arm.domain.Subnet;
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
+import org.jclouds.azurecompute.arm.features.SubnetApi;
+import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
import org.jclouds.compute.config.CustomizationResponse;
import org.jclouds.compute.domain.NodeMetadata;
import org.jclouds.compute.domain.Template;
@@ -40,7 +46,7 @@ import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIn
import org.jclouds.compute.strategy.ListNodesStrategy;
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.azurecompute.arm.AzureComputeApi;
-
+import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
import org.jclouds.logging.Logger;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.ListenableFuture;
@@ -54,6 +60,7 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
protected Logger logger = Logger.NULL;
private final AzureComputeApi api;
+ private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
@Inject
protected CreateResourceGroupThenCreateNodes(
@@ -62,11 +69,12 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
GroupNamingConvention.Factory namingConvention,
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
- AzureComputeApi api) {
+ AzureComputeApi api, AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
this.api = checkNotNull(api, "api cannot be null");
checkNotNull(userExecutor, "userExecutor cannot be null");
+ this.azureComputeConstants = azureComputeConstants;
}
@Override
@@ -74,23 +82,59 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
+ String azureGroupName = this.azureComputeConstants.azureResourceGroup();
+
+ AzureTemplateOptions options = template.getOptions().as(AzureTemplateOptions.class);
+ // create resource group for jclouds group if it does not already exist
ResourceGroupApi resourceGroupApi = api.getResourceGroupApi();
- ResourceGroup resourceGroup = resourceGroupApi.get(group);
+ ResourceGroup resourceGroup = resourceGroupApi.get(azureGroupName);
final String location = template.getLocation().getId();
- final String resourceGroupName;
if (resourceGroup == null){
-
final Map<String, String> tags = ImmutableMap.of("description", "jClouds managed VMs");
- resourceGroupName = resourceGroupApi.create(group, location, tags).name();
- } else {
- resourceGroupName = resourceGroup.name();
+ resourceGroupApi.create(azureGroupName, location, tags).name();
}
- Map<?, ListenableFuture<Void>> responses = super.execute(resourceGroupName, count, template, goodNodes, badNodes,
+ String vnetName = azureGroupName + "virtualnetwork";
+ String subnetName = azureGroupName + "subnet";
+
+ if (options.getVirtualNetworkName() != null) {
+ vnetName = options.getVirtualNetworkName();
+ }
+
+ this.getOrCreateVirtualNetworkWithSubnet(vnetName, subnetName, location, options, azureGroupName);
+
+
+ Map<?, ListenableFuture<Void>> responses = super.execute(group, count, template, goodNodes, badNodes,
customizationResponses);
return responses;
}
+ protected synchronized void getOrCreateVirtualNetworkWithSubnet(
+ final String virtualNetworkName, final String subnetName, final String location,
+ AzureTemplateOptions options, final String azureGroupName) {
+
+ //Subnets belong to a virtual network so that needs to be created first
+ VirtualNetworkApi vnApi = api.getVirtualNetworkApi(azureGroupName);
+ VirtualNetwork vn = vnApi.get(virtualNetworkName);
+
+ if (vn == null) {
+ VirtualNetwork.VirtualNetworkProperties virtualNetworkProperties = VirtualNetwork.VirtualNetworkProperties.builder()
+ .addressSpace(VirtualNetwork.AddressSpace.create(Arrays.asList(this.azureComputeConstants.azureDefaultVnetAddressPrefixProperty())))
+ .subnets(
+ Arrays.asList(
+ Subnet.create(subnetName, null, null,
+ Subnet.SubnetProperties.builder().addressPrefix(this.azureComputeConstants.azureDefaultSubnetAddressPrefixProperty()).build())))
+ .build();
+ vn = vnApi.createOrUpdate(virtualNetworkName, location, virtualNetworkProperties);
+ }
+
+ SubnetApi subnetApi = api.getSubnetApi(azureGroupName, virtualNetworkName);
+ Subnet subnet = subnetApi.get(subnetName);
+
+ options.virtualNetworkName(virtualNetworkName);
+ options.subnetId(subnet.id());
+
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
index 48d6287..e5ef5cd 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
@@ -41,4 +41,10 @@ public class AzureComputeProperties {
public static final String TIMEOUT_RESOURCE_DELETED = "jclouds.azurecompute.arm.timeout.resourcedeleted";
+ public static final String DEFAULT_VNET_ADDRESS_SPACE_PREFIX = "jclouds.azurecompute.arm.vnet.addressprefix";
+
+ public static final String DEFAULT_SUBNET_ADDRESS_PREFIX = "jclouds.azurecompute.arm.subnet.addressprefix";
+
+ public static final String DEFAULT_DATADISKSIZE = "jclouds.azurecompute.arm.datadisksize";
+
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
index 848000d..5221e05 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/DeploymentTemplate.java
@@ -31,8 +31,25 @@ public abstract class DeploymentTemplate {
//Empty placeholders as we want to generate the empty JSON object
@AutoValue
public abstract static class Parameters {
- public static Parameters create() {
- return new AutoValue_DeploymentTemplate_Parameters();
+
+ @Nullable
+ public abstract KeyVaultReference publicKeyFromAzureKeyVault();
+
+ public static Parameters create(KeyVaultReference reference)
+ {
+ return new AutoValue_DeploymentTemplate_Parameters(reference);
+ }
+ }
+
+ @AutoValue
+ public abstract static class TemplateParameters {
+
+ @Nullable
+ public abstract TemplateParameterType publicKeyFromAzureKeyVault();
+
+ public static TemplateParameters create(TemplateParameterType publicKeyFromAzureKeyVault)
+ {
+ return new AutoValue_DeploymentTemplate_TemplateParameters(publicKeyFromAzureKeyVault);
}
}
@@ -40,7 +57,7 @@ public abstract class DeploymentTemplate {
public abstract String contentVersion();
- public abstract Parameters parameters();
+ public abstract TemplateParameters parameters();
public abstract Map<String, String> variables();
@@ -52,7 +69,7 @@ public abstract class DeploymentTemplate {
@SerializedNames({"$schema", "contentVersion", "parameters", "variables", "resources" , "outputs"})
public static DeploymentTemplate create(final String schema,
final String contentVersion,
- final Parameters parameters,
+ final TemplateParameters parameters,
final Map<String, String> variables,
final List<ResourceDefinition> resources,
final List<?> outputs) {
@@ -83,7 +100,7 @@ public abstract class DeploymentTemplate {
public abstract Builder contentVersion(String type);
- public abstract Builder parameters(Parameters parameters);
+ public abstract Builder parameters(TemplateParameters parameters);
public abstract Builder variables(Map<String, String> variables);
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/KeyVaultReference.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/KeyVaultReference.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/KeyVaultReference.java
new file mode 100644
index 0000000..2eb2f87
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/KeyVaultReference.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
+
+// Simple helper class to serialize / deserialize keyvault reference.
+
+@AutoValue
+public abstract class KeyVaultReference {
+
+ @AutoValue
+ public abstract static class Reference {
+
+ public abstract IdReference keyVault();
+
+ public abstract String secretName();
+
+ @SerializedNames({"keyVault", "secretName"})
+ public static Reference create(final IdReference keyVault, final String secretName) {
+ return new AutoValue_KeyVaultReference_Reference(keyVault, secretName);
+ }
+ }
+
+ public abstract Reference reference();
+
+ @SerializedNames({"reference"})
+ public static KeyVaultReference create(final Reference reference) {
+ return new AutoValue_KeyVaultReference(reference);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkInterfaceCardProperties.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkInterfaceCardProperties.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkInterfaceCardProperties.java
index e6f2de7..8b19493 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkInterfaceCardProperties.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/NetworkInterfaceCardProperties.java
@@ -38,13 +38,17 @@ public abstract class NetworkInterfaceCardProperties {
@Nullable
public abstract List<IpConfiguration> ipConfigurations();
- @SerializedNames({"provisioningState", "resourceGuid", "enableIPForwarding", "ipConfigurations"})
- public static NetworkInterfaceCardProperties create(final String provisioningState, final String resourceGuid, final Boolean enableIPForwarding, final List<IpConfiguration> ipConfigurations) {
+ @Nullable
+ public abstract IdReference networkSecurityGroup();
+
+ @SerializedNames({"provisioningState", "resourceGuid", "enableIPForwarding", "ipConfigurations", "networkSecurityGroup"})
+ public static NetworkInterfaceCardProperties create(final String provisioningState, final String resourceGuid, final Boolean enableIPForwarding, final List<IpConfiguration> ipConfigurations, final IdReference networkSecurityGroup) {
NetworkInterfaceCardProperties.Builder builder = NetworkInterfaceCardProperties.builder()
.provisioningState(provisioningState)
.resourceGuid(resourceGuid)
.enableIPForwarding(enableIPForwarding)
- .ipConfigurations(ipConfigurations == null ? null : ImmutableList.copyOf(ipConfigurations));
+ .ipConfigurations(ipConfigurations == null ? null : ImmutableList.copyOf(ipConfigurations))
+ .networkSecurityGroup(networkSecurityGroup);
return builder.build();
}
@@ -66,6 +70,8 @@ public abstract class NetworkInterfaceCardProperties {
abstract List<IpConfiguration> ipConfigurations();
+ public abstract Builder networkSecurityGroup(IdReference networkSecurityGroup);
+
abstract NetworkInterfaceCardProperties autoBuild();
public NetworkInterfaceCardProperties build() {
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java
index a9f7349..0be43bf 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/OSDisk.java
@@ -52,16 +52,23 @@ public abstract class OSDisk {
@Nullable
public abstract String createOption();
- @SerializedNames({"osType", "name", "vhd", "caching", "createOption"})
+ /**
+ * The url of the custom image
+ */
+ @Nullable
+ public abstract VHD image();
+
+ @SerializedNames({"osType", "name", "vhd", "caching", "createOption", "image"})
public static OSDisk create(final String osType, final String name, final VHD vhd,
- final String caching, final String createOption) {
+ final String caching, final String createOption, final VHD image) {
return builder()
- .osType(osType)
- .name(name)
- .vhd(vhd)
- .caching(caching)
- .createOption(createOption)
- .build();
+ .osType(osType)
+ .name(name)
+ .vhd(vhd)
+ .caching(caching)
+ .createOption(createOption)
+ .image(image)
+ .build();
}
public static Builder builder() {
@@ -71,15 +78,11 @@ public abstract class OSDisk {
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder osType(String osType);
-
public abstract Builder name(String name);
-
public abstract Builder caching(String caching);
-
public abstract Builder createOption(String createOption);
-
public abstract Builder vhd(VHD vhd);
-
+ public abstract Builder image(VHD image);
public abstract OSDisk build();
}
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageProfile.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageProfile.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageProfile.java
index 7c693ef..bcb62ee 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageProfile.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/StorageProfile.java
@@ -29,6 +29,7 @@ public abstract class StorageProfile {
/**
* The image reference of the storage profile
*/
+ @Nullable
public abstract ImageReference imageReference();
/**
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/TemplateParameterType.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/TemplateParameterType.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/TemplateParameterType.java
new file mode 100644
index 0000000..d0ccc71
--- /dev/null
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/TemplateParameterType.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.domain;
+
+import com.google.auto.value.AutoValue;
+import org.jclouds.javax.annotation.Nullable;
+import org.jclouds.json.SerializedNames;
+
+// Simple helper class to serialize / deserialize id reference.
+
+@AutoValue
+public abstract class TemplateParameterType {
+ @Nullable
+ public abstract String type();
+
+ @SerializedNames({"type"})
+ public static TemplateParameterType create(final String type) {
+ return new AutoValue_TemplateParameterType(type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
index 6909a7b..c663944 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMDeployment.java
@@ -18,6 +18,7 @@ package org.jclouds.azurecompute.arm.domain;
import java.util.List;
+import java.util.Map;
public class VMDeployment {
@@ -28,4 +29,8 @@ public class VMDeployment {
public VirtualMachineInstance vm;
public VirtualMachine virtualMachine;
+
+ public Map<String, String> userMetaData;
+
+ public Iterable<String> tags;
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
index d338327..f0aa77e 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMHardware.java
@@ -17,6 +17,7 @@
package org.jclouds.azurecompute.arm.domain;
import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
/**
* A VM Size that is available in a region for a given subscription.
@@ -24,45 +25,51 @@ import com.google.auto.value.AutoValue;
* @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt269440.aspx" >api</a>
*/
@AutoValue
-public class VMHardware {
+public abstract class VMHardware {
/**
* The name of the VM size.
*/
- public String name;
+ public abstract String name();
/**
* The number of cores that are available in the VM size.
*/
- public Integer numberOfCores;
+ public abstract Integer numberOfCores();
/**
* Specifies the size in MB of the OS Disk.
*/
- public Integer osDiskSizeInMB;
+ public abstract Integer osDiskSizeInMB();
/**
* The size of the resource disk.
*/
- public Integer resourceDiskSizeInMB;
+ public abstract Integer resourceDiskSizeInMB();
/**
* Specifies the available RAM in MB.
*/
- public Integer memoryInMB;
+ public abstract Integer memoryInMB();
/**
* Specifies the maximum number of data disks that can be attached to the VM size.
*/
- public Integer maxDataDiskCount;
+ public abstract Integer maxDataDiskCount();
/**
* Specifies the location of the HW resource
*/
- public String location;
+ public abstract String location();
/**
* Specifies if this HW is globally available
*/
- public boolean globallyAvailable;
+ public abstract boolean globallyAvailable();
+
+ @SerializedNames({ "name", "numberOfCores", "osDiskSizeInMB", "resourceDiskSizeInMB", "memoryInMB", "maxDataDiskCount", "location", "globallyAvailable"})
+ public static VMHardware create(String name, Integer numberOfCores, Integer osDiskSizeInMB, Integer resourceDiskSizeInMB, Integer memoryInMB, Integer maxDataDiskCount, String location, boolean globallyAvailable) {
+
+ return new AutoValue_VMHardware(name, numberOfCores, osDiskSizeInMB, resourceDiskSizeInMB, memoryInMB, maxDataDiskCount, location, globallyAvailable);
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
index ccfb05a..2d4fc91 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/domain/VMImage.java
@@ -17,37 +17,44 @@
package org.jclouds.azurecompute.arm.domain;
import com.google.auto.value.AutoValue;
+import org.jclouds.json.SerializedNames;
@AutoValue
-public class VMImage {
+public abstract class VMImage {
/**
* The publisher of the image reference.
*/
- public String publisher;
+ public abstract String publisher();
/**
* The offer of the image reference.
*/
- public String offer;
+ public abstract String offer();
/**
* The sku of the image reference.
*/
- public String sku;
+ public abstract String sku();
/**
* The version of the image reference.
*/
- public String version;
+ public abstract String version();
/**
* The location from where Image was fetched
*/
- public String location;
+ public abstract String location();
/**
* Specifies if this image is globally available
*/
- public boolean globallyAvailable;
+ public abstract boolean globallyAvailable();
+
+ @SerializedNames({ "publisher", "offer", "sku", "version", "location", "globallyAvailable"})
+ public static VMImage create(String publisher, String offer, String sku, String version, String location, boolean globallyAvailable) {
+
+ return new AutoValue_VMImage(publisher, offer, sku, version, location, globallyAvailable);
+ }
}
http://git-wip-us.apache.org/repos/asf/jclouds-labs/blob/2b36a75f/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
----------------------------------------------------------------------
diff --git a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
index 7dd75a9..f2858d9 100644
--- a/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
+++ b/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/features/JobApi.java
@@ -17,15 +17,21 @@
package org.jclouds.azurecompute.arm.features;
import java.io.Closeable;
import java.net.URI;
+import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.GET;
+
+import org.jclouds.Fallbacks;
+import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
import org.jclouds.oauth.v2.filters.OAuthFilter;
import org.jclouds.rest.annotations.EndpointParam;
+import org.jclouds.rest.annotations.Fallback;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.ResponseParser;
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
import org.jclouds.azurecompute.arm.functions.ParseJobStatus.JobStatus;
+import org.jclouds.rest.annotations.SelectJson;
/**
* The Azure Resource Manager API checks for job status and progress.
@@ -37,5 +43,14 @@ public interface JobApi extends Closeable{
@GET
@ResponseParser(ParseJobStatus.class)
JobStatus jobStatus(@EndpointParam URI jobURI);
+
+ /**
+ * Get status of captured custom image after capture call
+ */
+ @GET
+ @Fallback(Fallbacks.EmptyListOnNotFoundOr404.class)
+ @SelectJson("resources")
+ List<ResourceDefinition> captureStatus(@EndpointParam URI jobURI);
+
}