mirror of https://github.com/apache/jclouds.git
Refactored Azure ARM to not use Deployments
* Simplified ImageExtension * Fixed access to deployed VMS * Made api-version configurable for all apis" * Fixed all feature live tests * Fixed the AzureComputeServiceLiveTest * Fixed the AzureTemplateBuilderLiveTest * Fixed the AzureComputeImageExtensionLiveTest
This commit is contained in:
parent
8df58654b8
commit
cd16826dca
|
@ -32,8 +32,7 @@ azure ad app create --name <name> --password <password> --home-page <home-page>
|
||||||
# Create a Service Principal
|
# Create a Service Principal
|
||||||
azure ad sp create <Application-id>
|
azure ad sp create <Application-id>
|
||||||
|
|
||||||
# Output will include a value for `Object Id`
|
# Output will include a value for `Object Id`, to be used in the next step
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Run the following commands to assign roles to the service principal
|
Run the following commands to assign roles to the service principal
|
||||||
|
@ -58,7 +57,8 @@ mvn -Dtest=<name of the live test> \
|
||||||
-Dtest.azurecompute-arm.identity="<Application-id>" \
|
-Dtest.azurecompute-arm.identity="<Application-id>" \
|
||||||
-Dtest.azurecompute-arm.credential="<password>" \
|
-Dtest.azurecompute-arm.credential="<password>" \
|
||||||
-Dtest.azurecompute-arm.endpoint="https://management.azure.com/subscriptions/<Subscription-id>" \
|
-Dtest.azurecompute-arm.endpoint="https://management.azure.com/subscriptions/<Subscription-id>" \
|
||||||
-Dtest.oauth.endpoint="https://login.microsoftonline.com/<Tenant-id>/oauth2/token" test
|
-Dtest.oauth.endpoint="https://login.microsoftonline.com/<Tenant-id>/oauth2/token"
|
||||||
|
integration-test -Plive
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.jclouds</groupId>
|
<groupId>org.apache.jclouds</groupId>
|
||||||
<artifactId>jclouds-compute</artifactId>
|
<artifactId>jclouds-compute</artifactId>
|
||||||
<version>${project.parent.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.auto.service</groupId>
|
<groupId>com.google.auto.service</groupId>
|
||||||
|
@ -76,11 +76,6 @@
|
||||||
<type>test-jar</type>
|
<type>test-jar</type>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.jclouds</groupId>
|
|
||||||
<artifactId>jclouds-compute</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.jclouds</groupId>
|
<groupId>org.apache.jclouds</groupId>
|
||||||
<artifactId>jclouds-compute</artifactId>
|
<artifactId>jclouds-compute</artifactId>
|
||||||
|
|
|
@ -16,28 +16,27 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm;
|
package org.jclouds.azurecompute.arm;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.features.DeploymentApi;
|
import org.jclouds.azurecompute.arm.features.DeploymentApi;
|
||||||
import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
|
|
||||||
import org.jclouds.azurecompute.arm.features.JobApi;
|
import org.jclouds.azurecompute.arm.features.JobApi;
|
||||||
import org.jclouds.azurecompute.arm.features.LocationApi;
|
import org.jclouds.azurecompute.arm.features.LocationApi;
|
||||||
import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
|
import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
|
||||||
import org.jclouds.azurecompute.arm.features.OSImageApi;
|
import org.jclouds.azurecompute.arm.features.OSImageApi;
|
||||||
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
|
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
|
||||||
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
|
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
|
||||||
import org.jclouds.azurecompute.arm.features.ResourceProviderApi;
|
import org.jclouds.azurecompute.arm.features.ResourceProviderApi;
|
||||||
import org.jclouds.azurecompute.arm.features.StorageAccountApi;
|
import org.jclouds.azurecompute.arm.features.StorageAccountApi;
|
||||||
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.VMSizeApi;
|
||||||
import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
|
import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
|
||||||
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
|
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
|
||||||
import org.jclouds.azurecompute.arm.features.VMSizeApi;
|
|
||||||
import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
|
|
||||||
import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
|
|
||||||
import org.jclouds.rest.annotations.Delegate;
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import java.io.Closeable;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Azure Resource Manager API is a REST API for managing your services and deployments.
|
* The Azure Resource Manager API is a REST API for managing your services and deployments.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -165,6 +164,4 @@ public interface AzureComputeApi extends Closeable {
|
||||||
@Delegate
|
@Delegate
|
||||||
ResourceProviderApi getResourceProviderApi();
|
ResourceProviderApi getResourceProviderApi();
|
||||||
|
|
||||||
@Provides
|
|
||||||
DeploymentTemplateBuilder.Factory deploymentTemplateFactory();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,31 +17,47 @@
|
||||||
package org.jclouds.azurecompute.arm;
|
package org.jclouds.azurecompute.arm;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.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_INITIAL_PERIOD;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_POLL_MAX_PERIOD;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_FORMAT;
|
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.TCP_RULE_REGEXP;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
|
import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_AUTHENTICATE_SUDO;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
|
import static org.jclouds.compute.config.ComputeServiceProperties.IMAGE_LOGIN_USER;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
|
||||||
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
|
|
||||||
|
|
||||||
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
|
import static org.jclouds.oauth.v2.config.CredentialType.CLIENT_CREDENTIALS_SECRET;
|
||||||
import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
|
|
||||||
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
|
import static org.jclouds.oauth.v2.config.OAuthProperties.CREDENTIAL_TYPE;
|
||||||
|
import static org.jclouds.oauth.v2.config.OAuthProperties.RESOURCE;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.domain.Region;
|
import org.jclouds.azurecompute.arm.domain.Region;
|
||||||
|
import org.jclouds.azurecompute.arm.features.DeploymentApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.LocationApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.NetworkInterfaceCardApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.NetworkSecurityGroupApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.NetworkSecurityRuleApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.OSImageApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.ResourceProviderApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.StorageAccountApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.VMSizeApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceProperties;
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
import org.jclouds.providers.internal.BaseProviderMetadata;
|
import org.jclouds.providers.internal.BaseProviderMetadata;
|
||||||
import org.jclouds.compute.config.ComputeServiceProperties;
|
|
||||||
|
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
|
|
||||||
|
@ -72,13 +88,37 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
|
||||||
properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
|
properties.setProperty(TCP_RULE_REGEXP, "tcp_\\d{1,5}-\\d{1,5}");
|
||||||
properties.put(RESOURCE, "https://management.azure.com/");
|
properties.put(RESOURCE, "https://management.azure.com/");
|
||||||
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
|
properties.put(CREDENTIAL_TYPE, CLIENT_CREDENTIALS_SECRET.toString());
|
||||||
properties.put(RESOURCE_GROUP_NAME, "jcloudsgroup");
|
properties.put(RESOURCE_GROUP_NAME, "jclouds");
|
||||||
properties.put(DEFAULT_VNET_ADDRESS_SPACE_PREFIX, "10.0.0.0/16");
|
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_SUBNET_ADDRESS_PREFIX, "10.0.0.0/24");
|
||||||
properties.put(DEFAULT_DATADISKSIZE, "100");
|
properties.put(DEFAULT_DATADISKSIZE, "100");
|
||||||
properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
|
properties.put(IMAGE_PUBLISHERS, "Canonical,RedHat");
|
||||||
properties.put(DEFAULT_IMAGE_LOGIN, "jclouds:Password1!");
|
// Default credentials for all images
|
||||||
|
properties.put(IMAGE_LOGIN_USER, "jclouds:Password12345!");
|
||||||
|
properties.put(IMAGE_AUTHENTICATE_SUDO, "true");
|
||||||
|
properties.put(TEMPLATE, "imageNameMatches=UbuntuServer,osVersionMatches=1[45]\\.[01][04]\\.[0-9]-LTS");
|
||||||
properties.put(TIMEOUT_NODE_TERMINATED, 60 * 10 * 1000);
|
properties.put(TIMEOUT_NODE_TERMINATED, 60 * 10 * 1000);
|
||||||
|
// Api versions used in each API
|
||||||
|
properties.put(API_VERSION_PREFIX + DeploymentApi.class.getSimpleName(), "2016-02-01");
|
||||||
|
properties.put(API_VERSION_PREFIX + LocationApi.class.getSimpleName(), "2015-11-01");
|
||||||
|
properties.put(API_VERSION_PREFIX + NetworkInterfaceCardApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + NetworkSecurityGroupApi.class.getSimpleName(), "2016-03-30");
|
||||||
|
properties.put(API_VERSION_PREFIX + NetworkSecurityRuleApi.class.getSimpleName(), "2016-03-30");
|
||||||
|
properties.put(API_VERSION_PREFIX + OSImageApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + PublicIPAddressApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + ResourceGroupApi.class.getSimpleName(), "2015-01-01");
|
||||||
|
properties.put(API_VERSION_PREFIX + ResourceProviderApi.class.getSimpleName(), "2015-01-01");
|
||||||
|
properties.put(API_VERSION_PREFIX + StorageAccountApi.class.getSimpleName(), STORAGE_API_VERSION);
|
||||||
|
properties.put(API_VERSION_PREFIX + SubnetApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + VirtualNetworkApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + VMSizeApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + VirtualMachineApi.class.getSimpleName(), "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + "GetVirtualMachine", "2016-03-30");
|
||||||
|
properties.put(API_VERSION_PREFIX + "GetVirtualMachineInstance", "2016-03-30");
|
||||||
|
properties.put(API_VERSION_PREFIX + "CreateVirtualMachine", "2016-03-30");
|
||||||
|
properties.put(API_VERSION_PREFIX + "ListVirtualMachines", "2015-06-15");
|
||||||
|
properties.put(API_VERSION_PREFIX + "DeleteVirtualMachine", "2016-03-30");
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,164 +17,139 @@
|
||||||
package org.jclouds.azurecompute.arm.compute;
|
package org.jclouds.azurecompute.arm.compute;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import static java.lang.String.format;
|
import static com.google.common.collect.Iterables.contains;
|
||||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
import static org.jclouds.util.Predicates2.retry;
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueIdCustom;
|
||||||
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.DeploymentToVMDeployment;
|
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
|
import org.jclouds.azurecompute.arm.domain.DataDisk;
|
||||||
import org.jclouds.azurecompute.arm.compute.predicates.IsDeploymentInRegions;
|
import org.jclouds.azurecompute.arm.domain.HardwareProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.Deployment;
|
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||||
import org.jclouds.azurecompute.arm.domain.DeploymentBody;
|
import org.jclouds.azurecompute.arm.domain.ImageReference;
|
||||||
import org.jclouds.azurecompute.arm.domain.DeploymentProperties;
|
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.IpConfigurationProperties;
|
||||||
import org.jclouds.azurecompute.arm.domain.Location;
|
import org.jclouds.azurecompute.arm.domain.Location;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkProfile;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.OSDisk;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.OSProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.Offer;
|
import org.jclouds.azurecompute.arm.domain.Offer;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
||||||
import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
|
import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
|
||||||
import org.jclouds.azurecompute.arm.domain.SKU;
|
import org.jclouds.azurecompute.arm.domain.SKU;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.StorageService;
|
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMDeployment;
|
import org.jclouds.azurecompute.arm.domain.StorageService.Status;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VHD;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMHardware;
|
import org.jclouds.azurecompute.arm.domain.VMHardware;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMSize;
|
import org.jclouds.azurecompute.arm.domain.VMSize;
|
||||||
import org.jclouds.azurecompute.arm.domain.Value;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.Version;
|
import org.jclouds.azurecompute.arm.domain.Version;
|
||||||
import org.jclouds.azurecompute.arm.features.DeploymentApi;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||||
import org.jclouds.azurecompute.arm.features.OSImageApi;
|
import org.jclouds.azurecompute.arm.features.OSImageApi;
|
||||||
|
import org.jclouds.azurecompute.arm.features.PublicIPAddressApi;
|
||||||
import org.jclouds.azurecompute.arm.functions.CleanupResources;
|
import org.jclouds.azurecompute.arm.functions.CleanupResources;
|
||||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||||
import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
|
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
|
||||||
import org.jclouds.domain.LoginCredentials;
|
|
||||||
import org.jclouds.location.Region;
|
import org.jclouds.location.Region;
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
|
||||||
import com.google.common.collect.FluentIterable;
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import com.google.common.net.UrlEscapers;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the connection between the {@link AzureComputeApi} implementation and the jclouds
|
* Defines the connection between the {@link AzureComputeApi} implementation and the jclouds
|
||||||
* {@link org.jclouds.compute.ComputeService}.
|
* {@link org.jclouds.compute.ComputeService}.
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeployment, VMHardware, VMImage, Location> {
|
public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location> {
|
||||||
|
|
||||||
private String azureGroup;
|
private final String azureGroup;
|
||||||
protected final CleanupResources cleanupResources;
|
private final CleanupResources cleanupResources;
|
||||||
|
|
||||||
@Resource
|
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
|
||||||
private Logger logger = Logger.NULL;
|
|
||||||
private final AzureComputeApi api;
|
private final AzureComputeApi api;
|
||||||
private final AzureComputeConstants azureComputeConstants;
|
private final AzureComputeConstants azureComputeConstants;
|
||||||
private final Supplier<Set<String>> regionIds;
|
private final Supplier<Set<String>> regionIds;
|
||||||
private final IsDeploymentInRegions isDeploymentInRegions;
|
private final Predicate<String> publicIpAvailable;
|
||||||
private final DeploymentToVMDeployment deploymentToVMDeployment;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AzureComputeServiceAdapter(final AzureComputeApi api, final AzureComputeConstants azureComputeConstants,
|
AzureComputeServiceAdapter(final AzureComputeApi api, final AzureComputeConstants azureComputeConstants,
|
||||||
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
|
CleanupResources cleanupResources, @Region Supplier<Set<String>> regionIds,
|
||||||
IsDeploymentInRegions isDeploymentInRegions, DeploymentToVMDeployment deploymentToVMDeployment) {
|
@Named("PublicIpAvailable") Predicate<String> publicIpAvailable) {
|
||||||
this.api = api;
|
this.api = api;
|
||||||
this.azureComputeConstants = azureComputeConstants;
|
this.azureComputeConstants = azureComputeConstants;
|
||||||
this.azureGroup = azureComputeConstants.azureResourceGroup();
|
this.azureGroup = azureComputeConstants.azureResourceGroup();
|
||||||
|
|
||||||
logger.debug("AzureComputeServiceAdapter set azuregroup to: " + azureGroup);
|
|
||||||
|
|
||||||
this.cleanupResources = cleanupResources;
|
this.cleanupResources = cleanupResources;
|
||||||
this.regionIds = regionIds;
|
this.regionIds = regionIds;
|
||||||
this.isDeploymentInRegions = isDeploymentInRegions;
|
this.publicIpAvailable = publicIpAvailable;
|
||||||
this.deploymentToVMDeployment = deploymentToVMDeployment;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NodeAndInitialCredentials<VMDeployment> createNodeWithGroupEncodedIntoName(
|
public NodeAndInitialCredentials<VirtualMachine> createNodeWithGroupEncodedIntoName(
|
||||||
final String group, final String name, final Template template) {
|
final String group, final String name, final Template template) {
|
||||||
|
|
||||||
DeploymentTemplateBuilder deploymentTemplateBuilder = api.deploymentTemplateFactory().create(group, name, template);
|
AzureTemplateOptions templateOptions = template.getOptions().as(AzureTemplateOptions.class);
|
||||||
|
|
||||||
final String loginUser = DeploymentTemplateBuilder.getLoginUserUsername();
|
// TODO Store group apart from the name to be able to identify nodes with custom names in the configured group
|
||||||
final String loginPassword = DeploymentTemplateBuilder.getLoginPassword();
|
// TODO ARM specific options
|
||||||
|
// TODO user metadata and tags
|
||||||
|
// TODO network ids => create one nic in each network
|
||||||
|
// TODO inbound ports
|
||||||
|
|
||||||
DeploymentBody deploymentTemplateBody = deploymentTemplateBuilder.getDeploymentTemplate();
|
String locationName = template.getLocation().getId();
|
||||||
|
String subnetId = templateOptions.getSubnetId();
|
||||||
|
NetworkInterfaceCard nic = createNetworkInterfaceCard(subnetId, name, locationName);
|
||||||
|
StorageProfile storageProfile = createStorageProfile(name, template.getImage(), templateOptions.getBlob());
|
||||||
|
HardwareProfile hardwareProfile = HardwareProfile.builder().vmSize(template.getHardware().getId()).build();
|
||||||
|
OSProfile osProfile = createOsProfile(name, template);
|
||||||
|
NetworkProfile networkProfile = NetworkProfile.builder().networkInterfaces(ImmutableList.of(IdReference.create(nic.id()))).build();
|
||||||
|
VirtualMachineProperties virtualMachineProperties = VirtualMachineProperties.builder()
|
||||||
|
.licenseType(null) // TODO
|
||||||
|
.availabilitySet(null) // TODO
|
||||||
|
.hardwareProfile(hardwareProfile)
|
||||||
|
.storageProfile(storageProfile)
|
||||||
|
.osProfile(osProfile)
|
||||||
|
.networkProfile(networkProfile)
|
||||||
|
.build();
|
||||||
|
|
||||||
DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody);
|
VirtualMachine virtualMachine = api.getVirtualMachineApi(azureGroup).create(name, template.getLocation().getId(), virtualMachineProperties);
|
||||||
|
|
||||||
final String deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplateBuilder.getDeploymentTemplateJson(properties));
|
// Safe to pass null credentials here, as jclouds will default populate the node with the default credentials from the image, or the ones in the options, if provided.
|
||||||
|
return new NodeAndInitialCredentials<VirtualMachine>(virtualMachine, name, null);
|
||||||
logger.debug("Deployment created with name: %s group: %s", name, group);
|
|
||||||
|
|
||||||
|
|
||||||
final Set<VMDeployment> deployments = Sets.newHashSet();
|
|
||||||
|
|
||||||
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) {
|
|
||||||
VMDeployment vmDeployment = VMDeployment.create(deployment);
|
|
||||||
deployments.add(vmDeployment);
|
|
||||||
} else {
|
|
||||||
logger.debug("Failed to create deployment!");
|
|
||||||
}
|
|
||||||
return !deployments.isEmpty();
|
|
||||||
}
|
|
||||||
}, azureComputeConstants.operationTimeout(), 1, SECONDS).apply(name)) {
|
|
||||||
final String illegalStateExceptionMessage = format("Deployment %s was not created within %sms so it will be destroyed.",
|
|
||||||
name, azureComputeConstants.operationTimeout());
|
|
||||||
logger.warn(illegalStateExceptionMessage);
|
|
||||||
destroyNode(name);
|
|
||||||
throw new IllegalStateException(illegalStateExceptionMessage);
|
|
||||||
}
|
|
||||||
final VMDeployment deployment = deployments.iterator().next();
|
|
||||||
NodeAndInitialCredentials<VMDeployment> credential;
|
|
||||||
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
|
@Override
|
||||||
public Iterable<VMHardware> listHardwareProfiles() {
|
public Iterable<VMHardware> listHardwareProfiles() {
|
||||||
|
|
||||||
final List<VMHardware> hwProfiles = Lists.newArrayList();
|
final List<VMHardware> hwProfiles = Lists.newArrayList();
|
||||||
final List<String> locationIds = Lists.newArrayList();
|
for (Location location : listLocations()) {
|
||||||
|
|
||||||
Iterable<Location> locations = listLocations();
|
|
||||||
for (Location location : locations){
|
|
||||||
locationIds.add(location.name());
|
|
||||||
|
|
||||||
Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
|
Iterable<VMSize> vmSizes = api.getVMSizeApi(location.name()).list();
|
||||||
|
|
||||||
for (VMSize vmSize : vmSizes){
|
for (VMSize vmSize : vmSizes){
|
||||||
VMHardware hwProfile = VMHardware.create(
|
VMHardware hwProfile = VMHardware.create(
|
||||||
vmSize.name(),
|
vmSize.name(),
|
||||||
|
@ -188,22 +163,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
hwProfiles.add(hwProfile);
|
hwProfiles.add(hwProfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAndSetHwAvailability(hwProfiles, Sets.newHashSet(locationIds));
|
|
||||||
|
|
||||||
return hwProfiles;
|
return hwProfiles;
|
||||||
}
|
}
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// TODO
|
|
||||||
// for (VMHardware hw : hwProfiles) {
|
|
||||||
// hw.globallyAvailable() = hwMap.get(hw.name()).containsAll(locations);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<VMImage> getImagesFromPublisher(String publisherName, String location) {
|
private List<VMImage> getImagesFromPublisher(String publisherName, String location) {
|
||||||
List<VMImage> osImagesRef = Lists.newArrayList();
|
List<VMImage> osImagesRef = Lists.newArrayList();
|
||||||
|
@ -216,7 +177,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
for (SKU sku : skuList) {
|
for (SKU sku : skuList) {
|
||||||
Iterable<Version> versionList = osImageApi.listVersions(publisherName, offer.name(), sku.name());
|
Iterable<Version> versionList = osImageApi.listVersions(publisherName, offer.name(), sku.name());
|
||||||
for (Version version : versionList) {
|
for (Version version : versionList) {
|
||||||
VMImage vmImage = VMImage.create(publisherName, offer.name(), sku.name(), version.name(), location);
|
VMImage vmImage = VMImage.azureImage().publisher(publisherName).offer(offer.name()).sku(sku.name())
|
||||||
|
.version(version.name()).location(location).build();
|
||||||
osImagesRef.add(vmImage);
|
osImagesRef.add(vmImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +197,6 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<VMImage> listImages() {
|
public Iterable<VMImage> listImages() {
|
||||||
|
|
||||||
final List<VMImage> osImages = Lists.newArrayList();
|
final List<VMImage> osImages = Lists.newArrayList();
|
||||||
|
|
||||||
for (Location location : listLocations()){
|
for (Location location : listLocations()){
|
||||||
|
@ -245,24 +206,51 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
List<StorageService> storages = api.getStorageAccountApi(azureGroup).list();
|
List<StorageService> storages = api.getStorageAccountApi(azureGroup).list();
|
||||||
for (StorageService storage : storages) {
|
for (StorageService storage : storages) {
|
||||||
String name = storage.name();
|
String name = storage.name();
|
||||||
|
StorageService storageService = api.getStorageAccountApi(azureGroup).get(name);
|
||||||
|
if (storageService != null
|
||||||
|
&& Status.Succeeded == storageService.storageServiceProperties().provisioningState()) {
|
||||||
String key = api.getStorageAccountApi(azureGroup).getKeys(name).key1();
|
String key = api.getStorageAccountApi(azureGroup).getKeys(name).key1();
|
||||||
List<VMImage> images = BlobHelper.getImages("jclouds", azureGroup, storage.name(), key,
|
BlobHelper blobHelper = new BlobHelper(storage.name(), key);
|
||||||
"custom", storage.location());
|
try {
|
||||||
|
List<VMImage> images = blobHelper.getImages(CONTAINER_NAME, azureGroup, CUSTOM_IMAGE_OFFER,
|
||||||
|
storage.location());
|
||||||
osImages.addAll(images);
|
osImages.addAll(images);
|
||||||
|
} finally {
|
||||||
|
closeQuietly(blobHelper);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return osImages;
|
return osImages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VMImage getImage(final String id) {
|
public VMImage getImage(final String id) {
|
||||||
VMImage image = VMImageToImage.decodeFieldsFromUniqueId(id);
|
VMImage image = decodeFieldsFromUniqueId(id);
|
||||||
if (image.custom()) {
|
if (image.custom()) {
|
||||||
String key = api.getStorageAccountApi(azureGroup).getKeys(image.storage()).key1();
|
VMImage customImage = null;
|
||||||
if (BlobHelper.customImageExists(image.storage(), key))
|
StorageServiceKeys keys = api.getStorageAccountApi(azureGroup).getKeys(image.storage());
|
||||||
return image;
|
if (keys == null) {
|
||||||
else
|
// If the storage account for the image does not exist, it means the image was deleted
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
|
||||||
|
try {
|
||||||
|
if (blobHelper.customImageExists()) {
|
||||||
|
List<VMImage> customImagesInStorage = blobHelper.getImages(CONTAINER_NAME, azureGroup,
|
||||||
|
CUSTOM_IMAGE_OFFER, image.location());
|
||||||
|
customImage = find(customImagesInStorage, new Predicate<VMImage>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(VMImage input) {
|
||||||
|
return id.equals(encodeFieldsToUniqueIdCustom(input));
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
closeQuietly(blobHelper);
|
||||||
|
}
|
||||||
|
return customImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
String location = image.location();
|
String location = image.location();
|
||||||
|
@ -273,7 +261,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
OSImageApi osImageApi = api.getOSImageApi(location);
|
OSImageApi osImageApi = api.getOSImageApi(location);
|
||||||
List<Version> versions = osImageApi.listVersions(publisher, offer, sku);
|
List<Version> versions = osImageApi.listVersions(publisher, offer, sku);
|
||||||
if (!versions.isEmpty()) {
|
if (!versions.isEmpty()) {
|
||||||
return VMImage.create(publisher, offer, sku, versions.get(0).name(), location);
|
return VMImage.azureImage().publisher(publisher).offer(offer).sku(sku).version(versions.get(0).name())
|
||||||
|
.location(location).build();
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -313,13 +302,8 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VMDeployment getNode(final String id) {
|
public VirtualMachine getNode(final String id) {
|
||||||
Deployment deployment = api.getDeploymentApi(azureGroup).get(id);
|
return api.getVirtualMachineApi(azureGroup).get(id);
|
||||||
if (deployment == null) return null;
|
|
||||||
if (isDeploymentInRegions.apply(deployment)) {
|
|
||||||
return deploymentToVMDeployment.apply(deployment);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -343,29 +327,99 @@ public class AzureComputeServiceAdapter implements ComputeServiceAdapter<VMDeplo
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<VMDeployment> listNodes() {
|
public Iterable<VirtualMachine> listNodes() {
|
||||||
return FluentIterable.from(api.getDeploymentApi(azureGroup).list())
|
return api.getVirtualMachineApi(azureGroup).list();
|
||||||
.filter(isDeploymentInRegions)
|
|
||||||
.filter(new Predicate<Deployment>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(Deployment deployment) {
|
|
||||||
Value storageAccountNameValue = deployment.properties().parameters().get("storageAccountName");
|
|
||||||
String storageAccountName = storageAccountNameValue.value();
|
|
||||||
String key = api.getStorageAccountApi(azureGroup).getKeys(storageAccountName).key1();
|
|
||||||
return !BlobHelper.customImageExists(storageAccountName, key);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.transform(deploymentToVMDeployment)
|
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<VMDeployment> listNodesByIds(final Iterable<String> ids) {
|
public Iterable<VirtualMachine> listNodesByIds(final Iterable<String> ids) {
|
||||||
return Iterables.filter(listNodes(), new Predicate<VMDeployment>() {
|
return filter(listNodes(), new Predicate<VirtualMachine>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(final VMDeployment input) {
|
public boolean apply(VirtualMachine virtualMachine) {
|
||||||
return Iterables.contains(ids, input.deployment().name());
|
return contains(ids, virtualMachine.id());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private OSProfile createOsProfile(String computerName, Template template) {
|
||||||
|
String defaultLoginUser = template.getImage().getDefaultCredentials().getUser();
|
||||||
|
String defaultLoginPassword = template.getImage().getDefaultCredentials().getOptionalPassword().get();
|
||||||
|
String adminUsername = Objects.firstNonNull(template.getOptions().getLoginUser(), defaultLoginUser);
|
||||||
|
String adminPassword = Objects.firstNonNull(template.getOptions().getLoginPassword(), defaultLoginPassword);
|
||||||
|
OSProfile.Builder builder = OSProfile.builder().adminUsername(adminUsername).computerName(computerName);
|
||||||
|
// prefer public key over password
|
||||||
|
if (template.getOptions().getPublicKey() != null) {
|
||||||
|
OSProfile.LinuxConfiguration linuxConfiguration = OSProfile.LinuxConfiguration.create("true",
|
||||||
|
OSProfile.LinuxConfiguration.SSH.create(ImmutableList.of(
|
||||||
|
OSProfile.LinuxConfiguration.SSH.SSHPublicKey.create(
|
||||||
|
String.format("/home/%s/.ssh/authorized_keys", adminUsername),
|
||||||
|
template.getOptions().getPublicKey())
|
||||||
|
))
|
||||||
|
);
|
||||||
|
builder.linuxConfiguration(linuxConfiguration);
|
||||||
|
} else {
|
||||||
|
builder.adminPassword(adminPassword);
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkInterfaceCard createNetworkInterfaceCard(String subnetId, String name, String locationName) {
|
||||||
|
final PublicIPAddressApi ipApi = api.getPublicIPAddressApi(azureGroup);
|
||||||
|
|
||||||
|
PublicIPAddressProperties properties =
|
||||||
|
PublicIPAddressProperties.builder()
|
||||||
|
.publicIPAllocationMethod("Static")
|
||||||
|
.idleTimeoutInMinutes(4)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String publicIpAddressName = "public-address-" + name;
|
||||||
|
PublicIPAddress ip = ipApi.createOrUpdate(publicIpAddressName, locationName, ImmutableMap.of("jclouds", name), properties);
|
||||||
|
|
||||||
|
checkState(publicIpAvailable.apply(publicIpAddressName),
|
||||||
|
"Public IP was not provisioned in the configured timeout");
|
||||||
|
|
||||||
|
final NetworkInterfaceCardProperties networkInterfaceCardProperties =
|
||||||
|
NetworkInterfaceCardProperties.builder()
|
||||||
|
.ipConfigurations(ImmutableList.of(
|
||||||
|
IpConfiguration.builder()
|
||||||
|
.name("ipConfig-" + name)
|
||||||
|
.properties(IpConfigurationProperties.builder()
|
||||||
|
.privateIPAllocationMethod("Dynamic")
|
||||||
|
.publicIPAddress(IdReference.create(ip.id()))
|
||||||
|
.subnet(IdReference.create(subnetId))
|
||||||
|
.build())
|
||||||
|
.build()))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String networkInterfaceCardName = "jc-nic-" + name;
|
||||||
|
return api.getNetworkInterfaceCardApi(azureGroup).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, ImmutableMap.of("jclouds", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private StorageProfile createStorageProfile(String name, Image image, String blob) {
|
||||||
|
VMImage imageRef = decodeFieldsFromUniqueId(image.getId());
|
||||||
|
ImageReference imageReference = null;
|
||||||
|
VHD sourceImage = null;
|
||||||
|
String osType = null;
|
||||||
|
|
||||||
|
if (!imageRef.custom()) {
|
||||||
|
imageReference = ImageReference.builder()
|
||||||
|
.publisher(image.getProviderId())
|
||||||
|
.offer(image.getName())
|
||||||
|
.sku(image.getVersion())
|
||||||
|
.version("latest")
|
||||||
|
.build();
|
||||||
|
} else {
|
||||||
|
sourceImage = VHD.create(image.getProviderId());
|
||||||
|
|
||||||
|
// TODO: read the ostype from the image blob
|
||||||
|
OsFamily osFamily = image.getOperatingSystem().getFamily();
|
||||||
|
osType = osFamily == OsFamily.WINDOWS ? "Windows" : "Linux";
|
||||||
|
}
|
||||||
|
|
||||||
|
VHD vhd = VHD.create(blob + "vhds/" + name + ".vhd");
|
||||||
|
OSDisk osDisk = OSDisk.create(osType, name, vhd, "ReadWrite", "FromImage", sourceImage);
|
||||||
|
|
||||||
|
return StorageProfile.create(imageReference, osDisk, ImmutableList.<DataDisk>of());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,55 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute.config;
|
package org.jclouds.azurecompute.arm.compute.config;
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.AzureComputeService;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.DeploymentToNodeMetadata;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.strategy.AzurePopulateDefaultLoginCredentialsForImageStrategy;
|
|
||||||
import org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.Location;
|
|
||||||
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.VirtualMachineInstance;
|
|
||||||
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
|
|
||||||
import org.jclouds.compute.ComputeService;
|
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
|
||||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
|
||||||
import org.jclouds.compute.extensions.ImageExtension;
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
|
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
|
||||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
|
||||||
import org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
|
||||||
import org.jclouds.logging.Logger;
|
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.Provides;
|
|
||||||
import com.google.inject.TypeLiteral;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_DATADISKSIZE;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_IMAGE_LOGIN;
|
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_SUBNET_ADDRESS_PREFIX;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.DEFAULT_VNET_ADDRESS_SPACE_PREFIX;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.IMAGE_PUBLISHERS;
|
||||||
|
@ -76,38 +29,87 @@ import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RUL
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TCP_RULE_REGEXP;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
|
||||||
|
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_SUSPENDED;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||||
import static org.jclouds.util.Predicates2.retry;
|
import static org.jclouds.util.Predicates2.retry;
|
||||||
|
|
||||||
public class AzureComputeServiceContextModule
|
import java.net.URI;
|
||||||
extends ComputeServiceAdapterContextModule<VMDeployment, VMHardware, VMImage, Location> {
|
import java.util.List;
|
||||||
|
|
||||||
@Resource
|
import javax.inject.Named;
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
import javax.inject.Singleton;
|
||||||
protected Logger logger = Logger.NULL;
|
|
||||||
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.AzureComputeService;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.AzureComputeServiceAdapter;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.functions.LocationToLocation;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.functions.VMHardwareToHardware;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.functions.VirtualMachineToNodeMetadata;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.strategy.CreateResourceGroupThenCreateNodes;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.Location;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VMHardware;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
|
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.extensions.ImageExtension;
|
||||||
|
import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatement;
|
||||||
|
import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatementWithoutPublicKey;
|
||||||
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||||
|
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Provides;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
|
||||||
|
public class AzureComputeServiceContextModule
|
||||||
|
extends ComputeServiceAdapterContextModule<VirtualMachine, VMHardware, VMImage, Location> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(new TypeLiteral<ComputeServiceAdapter<VMDeployment, VMHardware, VMImage, Location>>() {
|
|
||||||
|
bind(new TypeLiteral<ComputeServiceAdapter<VirtualMachine, VMHardware, VMImage, Location>>() {
|
||||||
}).to(AzureComputeServiceAdapter.class);
|
}).to(AzureComputeServiceAdapter.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<Function<VMImage, org.jclouds.compute.domain.Image>>() {
|
bind(new TypeLiteral<Function<VMImage, org.jclouds.compute.domain.Image>>() {
|
||||||
}).to(VMImageToImage.class);
|
}).to(VMImageToImage.class);
|
||||||
bind(new TypeLiteral<Function<VMHardware, Hardware>>() {
|
bind(new TypeLiteral<Function<VMHardware, Hardware>>() {
|
||||||
}).to(VMHardwareToHardware.class);
|
}).to(VMHardwareToHardware.class);
|
||||||
bind(new TypeLiteral<Function<VMDeployment, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<VirtualMachine, NodeMetadata>>() {
|
||||||
}).to(DeploymentToNodeMetadata.class);
|
}).to(VirtualMachineToNodeMetadata.class);
|
||||||
bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() {
|
bind(new TypeLiteral<Function<Location, org.jclouds.domain.Location>>() {
|
||||||
}).to(LocationToLocation.class);
|
}).to(LocationToLocation.class);
|
||||||
bind(ComputeService.class).to(AzureComputeService.class);
|
bind(ComputeService.class).to(AzureComputeService.class);
|
||||||
install(new LocationsFromComputeServiceAdapterModule<VMDeployment, VMHardware, VMImage, Location>() {
|
|
||||||
|
install(new LocationsFromComputeServiceAdapterModule<VirtualMachine, VMHardware, VMImage, Location>() {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
install(new FactoryModuleBuilder().build(ResourceDefinitionToCustomImage.Factory.class));
|
||||||
|
|
||||||
bind(TemplateOptions.class).to(AzureTemplateOptions.class);
|
bind(TemplateOptions.class).to(AzureTemplateOptions.class);
|
||||||
bind(PopulateDefaultLoginCredentialsForImageStrategy.class).to(AzurePopulateDefaultLoginCredentialsForImageStrategy.class);
|
bind(NodeAndTemplateOptionsToStatement.class).to(NodeAndTemplateOptionsToStatementWithoutPublicKey.class);
|
||||||
//bind(TemplateOptionsToStatement.class).to(TemplateOptionsToStatementWithoutPublicKey.class);
|
|
||||||
bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class);
|
bind(CreateNodesInGroupThenAddToSet.class).to(CreateResourceGroupThenCreateNodes.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<ImageExtension>() {
|
bind(new TypeLiteral<ImageExtension>() {
|
||||||
}).to(AzureComputeImageExtension.class);
|
}).to(AzureComputeImageExtension.class);
|
||||||
}
|
}
|
||||||
|
@ -143,10 +145,6 @@ public class AzureComputeServiceContextModule
|
||||||
@Inject
|
@Inject
|
||||||
private String azureImagePublishersProperty;
|
private String azureImagePublishersProperty;
|
||||||
|
|
||||||
@Named(DEFAULT_IMAGE_LOGIN)
|
|
||||||
@Inject
|
|
||||||
private String azureDefaultImageLoginProperty;
|
|
||||||
|
|
||||||
@Named(DEFAULT_VNET_ADDRESS_SPACE_PREFIX)
|
@Named(DEFAULT_VNET_ADDRESS_SPACE_PREFIX)
|
||||||
@Inject
|
@Inject
|
||||||
private String azureDefaultVnetAddressPrefixProperty;
|
private String azureDefaultVnetAddressPrefixProperty;
|
||||||
|
@ -171,10 +169,6 @@ public class AzureComputeServiceContextModule
|
||||||
return azureImagePublishersProperty;
|
return azureImagePublishersProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String azureDefaultImageLogin() {
|
|
||||||
return azureDefaultImageLoginProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String azureDefaultVnetAddressPrefixProperty() {
|
public String azureDefaultVnetAddressPrefixProperty() {
|
||||||
return azureDefaultVnetAddressPrefixProperty;
|
return azureDefaultVnetAddressPrefixProperty;
|
||||||
}
|
}
|
||||||
|
@ -204,6 +198,14 @@ public class AzureComputeServiceContextModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@com.google.inject.name.Named(TIMEOUT_NODE_RUNNING)
|
||||||
|
protected Predicate<String> provideVirtualMachineRunningPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants, Timeouts timeouts, PollPeriod pollPeriod) {
|
||||||
|
String azureGroup = azureComputeConstants.azureResourceGroup();
|
||||||
|
return retry(new VirtualMachineInStatePredicate(api, azureGroup, PowerState.RUNNING), timeouts.nodeRunning,
|
||||||
|
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Named(TIMEOUT_NODE_TERMINATED)
|
@Named(TIMEOUT_NODE_TERMINATED)
|
||||||
protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, Timeouts timeouts, PollPeriod pollPeriod) {
|
protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, Timeouts timeouts, PollPeriod pollPeriod) {
|
||||||
|
@ -230,7 +232,17 @@ public class AzureComputeServiceContextModule
|
||||||
protected Predicate<String> provideNodeSuspendedPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
protected Predicate<String> provideNodeSuspendedPredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
||||||
Timeouts timeouts, PollPeriod pollPeriod) {
|
Timeouts timeouts, PollPeriod pollPeriod) {
|
||||||
String azureGroup = azureComputeConstants.azureResourceGroup();
|
String azureGroup = azureComputeConstants.azureResourceGroup();
|
||||||
return retry(new NodeSuspendedPredicate(api, azureGroup), timeouts.nodeSuspended, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
|
return retry(new VirtualMachineInStatePredicate(api, azureGroup, PowerState.STOPPED), timeouts.nodeTerminated,
|
||||||
|
pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Named("PublicIpAvailable")
|
||||||
|
protected Predicate<String> providePublicIpAvailablePredicate(final AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
||||||
|
Timeouts timeouts, PollPeriod pollPeriod) {
|
||||||
|
String azureGroup = azureComputeConstants.azureResourceGroup();
|
||||||
|
return retry(new PublicIpAvailablePredicate(api, azureGroup), azureComputeConstants.operationTimeout(),
|
||||||
|
azureComputeConstants.operationPollInitialPeriod(), azureComputeConstants.operationPollMaxPeriod());
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@ -269,12 +281,34 @@ public class AzureComputeServiceContextModule
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static class NodeSuspendedPredicate implements Predicate<String> {
|
static class VirtualMachineInStatePredicate implements Predicate<String> {
|
||||||
|
|
||||||
|
private final AzureComputeApi api;
|
||||||
|
private final String azureGroup;
|
||||||
|
private final PowerState powerState;
|
||||||
|
|
||||||
|
public VirtualMachineInStatePredicate(AzureComputeApi api, String azureGroup, PowerState powerState) {
|
||||||
|
this.api = checkNotNull(api, "api must not be null");
|
||||||
|
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
|
||||||
|
this.powerState = checkNotNull(powerState, "powerState must not be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(String name) {
|
||||||
|
checkNotNull(name, "name cannot be null");
|
||||||
|
VirtualMachineInstance vmInstance = api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
|
||||||
|
if (vmInstance == null) return false;
|
||||||
|
return powerState == vmInstance.powerState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
static class PublicIpAvailablePredicate implements Predicate<String> {
|
||||||
|
|
||||||
private final AzureComputeApi api;
|
private final AzureComputeApi api;
|
||||||
private final String azureGroup;
|
private final String azureGroup;
|
||||||
|
|
||||||
public NodeSuspendedPredicate(AzureComputeApi api, String azureGroup) {
|
public PublicIpAvailablePredicate(AzureComputeApi api, String azureGroup) {
|
||||||
this.api = checkNotNull(api, "api must not be null");
|
this.api = checkNotNull(api, "api must not be null");
|
||||||
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
|
this.azureGroup = checkNotNull(azureGroup, "azuregroup must not be null");
|
||||||
}
|
}
|
||||||
|
@ -282,17 +316,10 @@ public class AzureComputeServiceContextModule
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(String name) {
|
public boolean apply(String name) {
|
||||||
checkNotNull(name, "name cannot be null");
|
checkNotNull(name, "name cannot be null");
|
||||||
String status = "";
|
PublicIPAddress publicIp = api.getPublicIPAddressApi(azureGroup).get(name);
|
||||||
VirtualMachineInstance virtualMachineInstance = api.getVirtualMachineApi(this.azureGroup).getInstanceDetails(name);
|
if (publicIp == null) return false;
|
||||||
if (virtualMachineInstance == null) return false;
|
return publicIp.properties().provisioningState().equalsIgnoreCase("Succeeded");
|
||||||
List<VirtualMachineInstance.VirtualMachineStatus> statuses = virtualMachineInstance.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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,141 +16,137 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute.extensions;
|
package org.jclouds.azurecompute.arm.compute.extensions;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import com.google.common.base.Supplier;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
|
||||||
import com.google.common.util.concurrent.UncheckedTimeoutException;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||||
import com.google.gson.internal.LinkedTreeMap;
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.name.Named;
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.View;
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
|
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||||
import org.jclouds.azurecompute.arm.compute.functions.VMImageToImage;
|
import org.jclouds.azurecompute.arm.compute.functions.ResourceDefinitionToCustomImage;
|
||||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
import org.jclouds.azurecompute.arm.functions.CleanupResources;
|
||||||
import static java.lang.String.format;
|
|
||||||
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||||
import org.jclouds.compute.domain.CloneImageTemplate;
|
import org.jclouds.compute.domain.CloneImageTemplate;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.ImageTemplate;
|
import org.jclouds.compute.domain.ImageTemplate;
|
||||||
import org.jclouds.compute.domain.ImageTemplateBuilder;
|
import org.jclouds.compute.domain.ImageTemplateBuilder;
|
||||||
import org.jclouds.compute.extensions.ImageExtension;
|
import org.jclouds.compute.extensions.ImageExtension;
|
||||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
import java.net.URI;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
|
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
|
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
public class AzureComputeImageExtension implements ImageExtension {
|
public class AzureComputeImageExtension implements ImageExtension {
|
||||||
|
public static final String CONTAINER_NAME = "jclouds";
|
||||||
|
public static final String CUSTOM_IMAGE_OFFER = "custom";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
private final AzureComputeApi api;
|
private final AzureComputeApi api;
|
||||||
private final ListeningExecutorService userExecutor;
|
|
||||||
private final Supplier<View> blobstore = null;
|
|
||||||
private final String group;
|
private final String group;
|
||||||
|
private final ListeningExecutorService userExecutor;
|
||||||
private final Predicate<URI> imageAvailablePredicate;
|
private final Predicate<URI> imageAvailablePredicate;
|
||||||
private final Predicate<String> nodeSuspendedPredicate;
|
private final Predicate<String> nodeSuspendedPredicate;
|
||||||
private final AzureComputeConstants azureComputeConstants;
|
private final ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage;
|
||||||
private final VMImageToImage imageReferenceToImage;
|
private final CleanupResources cleanupResources;
|
||||||
public static final String CONTAINER_NAME = "jclouds";
|
|
||||||
public static final String CUSTOM_IMAGE_PREFIX = "#";
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
AzureComputeImageExtension(AzureComputeApi api,
|
AzureComputeImageExtension(AzureComputeApi api,
|
||||||
@Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> imageAvailablePredicate,
|
@Named(TIMEOUT_IMAGE_AVAILABLE) Predicate<URI> imageAvailablePredicate,
|
||||||
@Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> nodeSuspendedPredicate,
|
@Named(TIMEOUT_NODE_SUSPENDED) Predicate<String> nodeSuspendedPredicate,
|
||||||
final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
AzureComputeConstants azureComputeConstants,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||||
VMImageToImage imageReferenceToImage) {
|
ResourceDefinitionToCustomImage.Factory resourceDefinitionToImage, CleanupResources cleanupResources) {
|
||||||
this.userExecutor = userExecutor;
|
this.api = api;
|
||||||
this.group = azureComputeConstants.azureResourceGroup();
|
|
||||||
this.imageReferenceToImage = imageReferenceToImage;
|
|
||||||
this.imageAvailablePredicate = imageAvailablePredicate;
|
this.imageAvailablePredicate = imageAvailablePredicate;
|
||||||
this.nodeSuspendedPredicate = nodeSuspendedPredicate;
|
this.nodeSuspendedPredicate = nodeSuspendedPredicate;
|
||||||
this.azureComputeConstants = azureComputeConstants;
|
this.group = azureComputeConstants.azureResourceGroup();
|
||||||
this.api = api;
|
this.userExecutor = userExecutor;
|
||||||
|
this.resourceDefinitionToImage = resourceDefinitionToImage;
|
||||||
|
this.cleanupResources = cleanupResources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageTemplate buildImageTemplateFromNode(String name, String id) {
|
public ImageTemplate buildImageTemplateFromNode(String name, String id) {
|
||||||
String nameLowerCase = name.toLowerCase();
|
return new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(name.toLowerCase()).build();
|
||||||
return new ImageTemplateBuilder.CloneImageTemplateBuilder().nodeId(id).name(nameLowerCase).build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<Image> createImage(ImageTemplate template) {
|
public ListenableFuture<Image> createImage(ImageTemplate template) {
|
||||||
|
|
||||||
|
|
||||||
final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
|
final CloneImageTemplate cloneTemplate = (CloneImageTemplate) template;
|
||||||
final String id = cloneTemplate.getSourceNodeId();
|
final String id = cloneTemplate.getSourceNodeId();
|
||||||
final String name = cloneTemplate.getName();
|
final String name = cloneTemplate.getName();
|
||||||
final String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "stor";
|
|
||||||
|
|
||||||
|
logger.debug(">> stopping node %s...", id);
|
||||||
api.getVirtualMachineApi(group).stop(id);
|
api.getVirtualMachineApi(group).stop(id);
|
||||||
if (nodeSuspendedPredicate.apply(id)) {
|
checkState(nodeSuspendedPredicate.apply(id), "Node %s was not suspended within the configured time limit", id);
|
||||||
|
|
||||||
return userExecutor.submit(new Callable<Image>() {
|
return userExecutor.submit(new Callable<Image>() {
|
||||||
@Override
|
@Override
|
||||||
public Image call() throws Exception {
|
public Image call() throws Exception {
|
||||||
|
logger.debug(">> generalizing virtal machine %s...", id);
|
||||||
api.getVirtualMachineApi(group).generalize(id);
|
api.getVirtualMachineApi(group).generalize(id);
|
||||||
|
|
||||||
final String[] disks = new String[2];
|
logger.debug(">> capturing virtual machine %s to container %s...", id, CONTAINER_NAME);
|
||||||
URI uri = api.getVirtualMachineApi(group).capture(id, cloneTemplate.getName(), CONTAINER_NAME);
|
URI uri = api.getVirtualMachineApi(group).capture(id, cloneTemplate.getName(), CONTAINER_NAME);
|
||||||
if (uri != null) {
|
checkState(uri != null && imageAvailablePredicate.apply(uri),
|
||||||
if (imageAvailablePredicate.apply(uri)) {
|
"Image %s was not created within the configured time limit", cloneTemplate.getName());
|
||||||
|
|
||||||
List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
|
List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
|
||||||
if (definitions != null) {
|
checkState(definitions.size() == 1,
|
||||||
for (ResourceDefinition definition : definitions) {
|
"Expected one resource definition after creating the image but %s were returned", definitions.size());
|
||||||
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");
|
Image image = resourceDefinitionToImage.create(id, name).apply(definitions.get(0));
|
||||||
disks[1] = datadiskObject.get("name");
|
logger.debug(">> created %s", image);
|
||||||
|
return image;
|
||||||
VirtualMachine vm = api.getVirtualMachineApi(group).get(id);
|
|
||||||
final VMImage ref = VMImage.create(group, storageAccountName, disks[0], disks[1], name, "custom", vm.location());
|
|
||||||
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
|
@Override
|
||||||
public boolean deleteImage(String id) {
|
public boolean deleteImage(String id) {
|
||||||
|
VMImage image = decodeFieldsFromUniqueId(id);
|
||||||
|
checkArgument(image.custom(), "Only custom images can be deleted");
|
||||||
|
|
||||||
|
logger.debug(">> deleting image %s", id);
|
||||||
|
|
||||||
VMImage image = VMImageToImage.decodeFieldsFromUniqueId(id);
|
|
||||||
if (image.custom()) {
|
|
||||||
StorageServiceKeys keys = api.getStorageAccountApi(image.group()).getKeys(image.storage());
|
StorageServiceKeys keys = api.getStorageAccountApi(image.group()).getKeys(image.storage());
|
||||||
|
BlobHelper blobHelper = new BlobHelper(image.storage(), keys.key1());
|
||||||
|
|
||||||
// This removes now all the images in this storage. At least in theory, there should be just one and if there is
|
try {
|
||||||
|
// This removes now all the images in this storage. At least in theory,
|
||||||
|
// there should be just one and if there is
|
||||||
// more, they should be copies of each other.
|
// more, they should be copies of each other.
|
||||||
BlobHelper.deleteContainerIfExists(image.storage(), keys.key1(), "system");
|
blobHelper.deleteContainerIfExists("system");
|
||||||
return !BlobHelper.customImageExists(image.storage(), keys.key1());
|
boolean result = !blobHelper.customImageExists();
|
||||||
|
|
||||||
|
if (!blobHelper.hasContainers()) {
|
||||||
|
logger.debug(">> storage account is empty after deleting the custom image. Deleting the storage account...");
|
||||||
|
api.getStorageAccountApi(image.group()).delete(image.storage());
|
||||||
|
cleanupResources.deleteResourceGroupIfEmpty(image.group());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return result;
|
||||||
|
} finally {
|
||||||
|
closeQuietly(blobHelper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,244 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.azurecompute.arm.compute.functions;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.ComputeNode;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.Deployment;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.ImageReference;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
|
||||||
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.VMSize;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
|
||||||
import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
|
|
||||||
import org.jclouds.azurecompute.arm.util.GetEnumValue;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
|
||||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
|
||||||
import org.jclouds.domain.Credentials;
|
|
||||||
import org.jclouds.domain.Location;
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import org.jclouds.domain.LoginCredentials;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
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();
|
|
||||||
|
|
||||||
private static final Map<ComputeNode.Status, NodeMetadata.Status> INSTANCESTATUS_TO_NODESTATUS =
|
|
||||||
ImmutableMap.<ComputeNode.Status, NodeMetadata.Status>builder().
|
|
||||||
put(ComputeNode.Status.GOOD, NodeMetadata.Status.RUNNING).
|
|
||||||
put(ComputeNode.Status.BAD, NodeMetadata.Status.ERROR).
|
|
||||||
put(ComputeNode.Status.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).
|
|
||||||
build();
|
|
||||||
|
|
||||||
// When using the Deployment API to deploy an ARM template, the deployment goes through
|
|
||||||
// stages. Accepted -> Running -> Succeeded. Only when the deployment has SUCCEEDED is
|
|
||||||
// the resource deployed using the template actually ready.
|
|
||||||
//
|
|
||||||
// To get details about the resource(s) deployed via template, one needs to query the
|
|
||||||
// various resources after the deployment has "SUCCEEDED".
|
|
||||||
private static final Map<Deployment.ProvisioningState, NodeMetadata.Status> STATUS_TO_NODESTATUS =
|
|
||||||
ImmutableMap.<Deployment.ProvisioningState, NodeMetadata.Status>builder().
|
|
||||||
put(Deployment.ProvisioningState.ACCEPTED, NodeMetadata.Status.PENDING).
|
|
||||||
put(Deployment.ProvisioningState.READY, NodeMetadata.Status.PENDING).
|
|
||||||
put(Deployment.ProvisioningState.RUNNING, NodeMetadata.Status.PENDING).
|
|
||||||
put(Deployment.ProvisioningState.CANCELED, NodeMetadata.Status.TERMINATED).
|
|
||||||
put(Deployment.ProvisioningState.FAILED, NodeMetadata.Status.ERROR).
|
|
||||||
put(Deployment.ProvisioningState.DELETED, NodeMetadata.Status.TERMINATED).
|
|
||||||
put(Deployment.ProvisioningState.SUCCEEDED, NodeMetadata.Status.RUNNING).
|
|
||||||
put(Deployment.ProvisioningState.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).
|
|
||||||
build();
|
|
||||||
|
|
||||||
public static Deployment.ProvisioningState provisioningStateFromString(final String text) {
|
|
||||||
return (Deployment.ProvisioningState) GetEnumValue.fromValueOrDefault(text, Deployment.ProvisioningState.UNRECOGNIZED);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final AzureComputeApi api;
|
|
||||||
|
|
||||||
private final LocationToLocation locationToLocation;
|
|
||||||
|
|
||||||
private final GroupNamingConvention nodeNamingConvention;
|
|
||||||
|
|
||||||
private final VMImageToImage vmImageToImage;
|
|
||||||
|
|
||||||
private final VMHardwareToHardware vmHardwareToHardware;
|
|
||||||
|
|
||||||
private final Map<String, Credentials> credentialStore;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
DeploymentToNodeMetadata(
|
|
||||||
AzureComputeApi api,
|
|
||||||
LocationToLocation locationToLocation,
|
|
||||||
GroupNamingConvention.Factory namingConvention, VMImageToImage vmImageToImage,
|
|
||||||
VMHardwareToHardware vmHardwareToHardware, Map<String, Credentials> credentialStore) {
|
|
||||||
|
|
||||||
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
|
|
||||||
this.locationToLocation = locationToLocation;
|
|
||||||
this.vmImageToImage = vmImageToImage;
|
|
||||||
this.vmHardwareToHardware = vmHardwareToHardware;
|
|
||||||
this.credentialStore = credentialStore;
|
|
||||||
this.api = api;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NodeMetadata apply(final VMDeployment from) {
|
|
||||||
final NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
|
||||||
final Deployment deployment = from.deployment();
|
|
||||||
builder.id(deployment.name());
|
|
||||||
builder.providerId(deployment.name());
|
|
||||||
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) {
|
|
||||||
List<VirtualMachineInstance.VirtualMachineStatus> statuses = from.vm().statuses();
|
|
||||||
for (int c = 0; c < statuses.size(); c++) {
|
|
||||||
if (statuses.get(c).code().substring(0, 10).equals("PowerState")) {
|
|
||||||
if (statuses.get(c).displayStatus().equals("VM running")) {
|
|
||||||
status = NodeMetadata.Status.RUNNING;
|
|
||||||
} else if (statuses.get(c).displayStatus().equals("VM stopped")) {
|
|
||||||
status = NodeMetadata.Status.SUSPENDED;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
builder.status(status);
|
|
||||||
|
|
||||||
if (from.vm() != null) {
|
|
||||||
builder.hostname(deployment.name() + "pc");
|
|
||||||
}
|
|
||||||
|
|
||||||
Credentials credentials = credentialStore.get("node#" + from.deployment().name());
|
|
||||||
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));
|
|
||||||
|
|
||||||
final Set<String> publicIpAddresses = Sets.newLinkedHashSet();
|
|
||||||
if (from.ipAddressList() != null) {
|
|
||||||
for (int c = 0; c < from.ipAddressList().size(); c++) {
|
|
||||||
PublicIPAddress ip = from.ipAddressList().get(c);
|
|
||||||
if (ip != null && ip.properties() != null && ip.properties().ipAddress() != null)
|
|
||||||
{
|
|
||||||
publicIpAddresses.add(ip.properties().ipAddress());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (publicIpAddresses.size() > 0)
|
|
||||||
builder.publicAddresses(publicIpAddresses);
|
|
||||||
}
|
|
||||||
final Set<String> privateIpAddresses = Sets.newLinkedHashSet();
|
|
||||||
if (from.networkInterfaceCards() != null) {
|
|
||||||
for (NetworkInterfaceCard nic : from.networkInterfaceCards()) {
|
|
||||||
if (nic != null && nic.properties() != null && nic.properties().ipConfigurations() != null) {
|
|
||||||
for (IpConfiguration ip : nic.properties().ipConfigurations()) {
|
|
||||||
if (ip != null && ip.properties() != null && ip.properties().privateIPAddress() != null) {
|
|
||||||
privateIpAddresses.add(ip.properties().privateIPAddress());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!privateIpAddresses.isEmpty()) {
|
|
||||||
builder.privateAddresses(privateIpAddresses);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
org.jclouds.azurecompute.arm.domain.Location myLocation = null;
|
|
||||||
if (from.virtualMachine() != null) {
|
|
||||||
String locationName = from.virtualMachine().location();
|
|
||||||
List<org.jclouds.azurecompute.arm.domain.Location> locations = api.getLocationApi().list();
|
|
||||||
|
|
||||||
for (org.jclouds.azurecompute.arm.domain.Location location : locations) {
|
|
||||||
if (location.name().equals(locationName)) {
|
|
||||||
myLocation = location;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Location jLocation = this.locationToLocation.apply(myLocation);
|
|
||||||
builder.location(jLocation);
|
|
||||||
|
|
||||||
ImageReference imageReference = from.virtualMachine().properties().storageProfile().imageReference();
|
|
||||||
|
|
||||||
if (imageReference != null) {
|
|
||||||
VMImage vmImage = VMImage.create(imageReference.publisher(), imageReference.offer(), imageReference.sku(),
|
|
||||||
imageReference.version(), locationName);
|
|
||||||
Image image = vmImageToImage.apply(vmImage);
|
|
||||||
builder.imageId(image.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
VMSize myVMSize = null;
|
|
||||||
String vmSizeName = from.virtualMachine().properties().hardwareProfile().vmSize();
|
|
||||||
List<VMSize> vmSizes = api.getVMSizeApi(locationName).list();
|
|
||||||
for (VMSize vmSize : vmSizes) {
|
|
||||||
if (vmSize.name().equals(vmSizeName)) {
|
|
||||||
myVMSize = vmSize;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.azurecompute.arm.compute.functions;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
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.PublicIPAddress;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VMDeployment;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts an Deployment into a VMDeployment.
|
|
||||||
*/
|
|
||||||
@Singleton
|
|
||||||
public class DeploymentToVMDeployment implements Function<Deployment, VMDeployment> {
|
|
||||||
|
|
||||||
private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
|
|
||||||
|
|
||||||
private final AzureComputeApi api;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
DeploymentToVMDeployment(AzureComputeApi api, final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
|
|
||||||
this.api = api;
|
|
||||||
this.azureComputeConstants = azureComputeConstants;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VMDeployment apply(final Deployment deployment) {
|
|
||||||
String id = deployment.id();
|
|
||||||
List<PublicIPAddress> ipAddressList = getIPAddresses(deployment);
|
|
||||||
List<NetworkInterfaceCard> networkInterfaceCards = getNetworkInterfaceCards(deployment);
|
|
||||||
VirtualMachine vm = api.getVirtualMachineApi(azureComputeConstants.azureResourceGroup()).get(id);
|
|
||||||
VirtualMachineInstance vmInstanceDetails = api.getVirtualMachineApi(azureComputeConstants.azureResourceGroup()).getInstanceDetails(id);
|
|
||||||
Map<String, String> userMetaData = null;
|
|
||||||
Iterable<String> tags = null;
|
|
||||||
if (vm != null && vm.tags() != null) {
|
|
||||||
userMetaData = vm.tags();
|
|
||||||
String tagString = userMetaData.get("tags");
|
|
||||||
tags = Arrays.asList(tagString.split(","));
|
|
||||||
}
|
|
||||||
return VMDeployment.create(deployment, ipAddressList, vmInstanceDetails, vm, networkInterfaceCards, userMetaData, tags);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<PublicIPAddress> getIPAddresses(Deployment deployment) {
|
|
||||||
List<PublicIPAddress> list = new ArrayList<PublicIPAddress>();
|
|
||||||
String resourceGroup = getResourceGroupFromId(deployment.id());
|
|
||||||
|
|
||||||
if (deployment.properties() != null && deployment.properties().dependencies() != null) {
|
|
||||||
List<Deployment.Dependency> dependencies = deployment.properties().dependencies();
|
|
||||||
for (int d = 0; d < dependencies.size(); d++) {
|
|
||||||
if (dependencies.get(d).resourceType().equals("Microsoft.Network/networkInterfaces")) {
|
|
||||||
List<Deployment.Dependency> dependsOn = dependencies.get(d).dependsOn();
|
|
||||||
for (int e = 0; e < dependsOn.size(); e++) {
|
|
||||||
if (dependsOn.get(e).resourceType().equals("Microsoft.Network/publicIPAddresses")) {
|
|
||||||
String resourceName = dependsOn.get(e).resourceName();
|
|
||||||
PublicIPAddress ip = api.getPublicIPAddressApi(resourceGroup).get(resourceName);
|
|
||||||
list.add(ip);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getResourceGroupFromId(String id) {
|
|
||||||
String searchStr = "/resourceGroups/";
|
|
||||||
int indexStart = id.lastIndexOf(searchStr) + searchStr.length();
|
|
||||||
searchStr = "/providers/";
|
|
||||||
int indexEnd = id.lastIndexOf(searchStr);
|
|
||||||
|
|
||||||
String resourceGroup = id.substring(indexStart, indexEnd);
|
|
||||||
return resourceGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<NetworkInterfaceCard> getNetworkInterfaceCards(Deployment deployment) {
|
|
||||||
List<NetworkInterfaceCard> result = new ArrayList<NetworkInterfaceCard>();
|
|
||||||
|
|
||||||
String resourceGroup = getResourceGroupFromId(deployment.id());
|
|
||||||
|
|
||||||
if (deployment.properties() != null && deployment.properties().dependencies() != null) {
|
|
||||||
for (Deployment.Dependency dependency : deployment.properties().dependencies()) {
|
|
||||||
if (dependency.resourceType().equals("Microsoft.Network/networkInterfaces")) {
|
|
||||||
String resourceName = dependency.resourceName();
|
|
||||||
NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(resourceGroup).get(resourceName);
|
|
||||||
result.add(nic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.azurecompute.arm.compute.functions;
|
||||||
|
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.inject.assistedinject.Assisted;
|
||||||
|
|
||||||
|
public class ResourceDefinitionToCustomImage implements Function<ResourceDefinition, Image> {
|
||||||
|
|
||||||
|
public interface Factory {
|
||||||
|
ResourceDefinitionToCustomImage create(@Assisted("nodeId") String nodeId, @Assisted("imageName") String imageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String resourceGroup;
|
||||||
|
private final Function<VMImage, Image> vmImageToImage;
|
||||||
|
private final String imageName;
|
||||||
|
private final String storageAccountName;
|
||||||
|
private final VirtualMachine vm;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ResourceDefinitionToCustomImage(AzureComputeApi api, AzureComputeConstants azureComputeConstants,
|
||||||
|
StorageProfileToStorageAccountName storageProfileToStorageAccountName,
|
||||||
|
Function<VMImage, Image> vmImageToImage, @Assisted("nodeId") String nodeId,
|
||||||
|
@Assisted("imageName") String imageName) {
|
||||||
|
this.vmImageToImage = vmImageToImage;
|
||||||
|
this.resourceGroup = azureComputeConstants.azureResourceGroup();
|
||||||
|
this.imageName = imageName;
|
||||||
|
this.vm = api.getVirtualMachineApi(resourceGroup).get(nodeId);
|
||||||
|
this.storageAccountName = storageProfileToStorageAccountName.apply(vm.properties().storageProfile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Image apply(ResourceDefinition input) {
|
||||||
|
VMImage.Builder builder = VMImage.customImage().group(resourceGroup).storage(storageAccountName).name(imageName)
|
||||||
|
.offer(CUSTOM_IMAGE_OFFER).location(vm.location());
|
||||||
|
|
||||||
|
Map<String, String> properties = (Map<String, String>) input.properties();
|
||||||
|
|
||||||
|
Object storageObject = properties.get("storageProfile");
|
||||||
|
Map<String, String> storageProperties = (Map<String, String>) storageObject;
|
||||||
|
|
||||||
|
Object osDiskObject = storageProperties.get("osDisk");
|
||||||
|
Map<String, String> osProperties = (Map<String, String>) osDiskObject;
|
||||||
|
builder.vhd1(osProperties.get("name"));
|
||||||
|
|
||||||
|
return vmImageToImage.apply(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,58 +16,50 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute.functions;
|
package org.jclouds.azurecompute.arm.compute.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import java.util.Set;
|
||||||
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 org.jclouds.azurecompute.arm.domain.ImageReference;
|
||||||
import com.google.common.collect.FluentIterable;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.domain.Image;
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
import org.jclouds.compute.domain.ImageBuilder;
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.compute.domain.OsFamily;
|
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.Location;
|
||||||
import org.jclouds.domain.LoginCredentials;
|
|
||||||
import org.jclouds.location.predicates.LocationPredicates;
|
import org.jclouds.location.predicates.LocationPredicates;
|
||||||
|
|
||||||
import java.util.Set;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.FluentIterable;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
public class VMImageToImage implements Function<VMImage, Image> {
|
public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
|
|
||||||
private static final String UNRECOGNIZED = "UNRECOGNIZED";
|
|
||||||
|
|
||||||
private static final String UBUNTU = "Ubuntu";
|
private static final String UBUNTU = "Ubuntu";
|
||||||
|
|
||||||
private static final String WINDOWS = "Windows";
|
private static final String WINDOWS = "Windows";
|
||||||
|
|
||||||
private static final String OPENLOGIC = "openLogic";
|
private static final String OPENLOGIC = "openLogic";
|
||||||
|
|
||||||
private static final String CENTOS = "CentOS";
|
private static final String CENTOS = "CentOS";
|
||||||
|
|
||||||
private static final String COREOS = "CoreOS";
|
private static final String COREOS = "CoreOS";
|
||||||
|
|
||||||
private static final String OPENSUSE = "openSUSE";
|
private static final String OPENSUSE = "openSUSE";
|
||||||
|
|
||||||
private static final String SUSE = "SUSE";
|
private static final String SUSE = "SUSE";
|
||||||
|
private static final String SLES = "SLES";
|
||||||
private static final String SQL_SERVER = "SQL Server";
|
private static final String ORACLE_lINUX = "Oracle-Linux";
|
||||||
|
private static final String RHEL = "RHEL";
|
||||||
private static final String ORACLE_lINUX = "Oracle Linux";
|
|
||||||
|
|
||||||
private final Supplier<Set<? extends org.jclouds.domain.Location>> locations;
|
private final Supplier<Set<? extends org.jclouds.domain.Location>> locations;
|
||||||
|
|
||||||
|
public static String encodeFieldsToUniqueId(boolean globallyAvailable, String locatioName, ImageReference imageReference){
|
||||||
|
return (globallyAvailable ? "global" : locatioName) + "/" + imageReference.publisher() + "/" + imageReference.offer() + "/" + imageReference.sku();
|
||||||
|
}
|
||||||
|
|
||||||
public static String encodeFieldsToUniqueId(VMImage imageReference){
|
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 encodeFieldsToUniqueIdCustom(VMImage imageReference){
|
public static String encodeFieldsToUniqueIdCustom(VMImage imageReference){
|
||||||
return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.group() + "/" + imageReference.storage() + "/" + imageReference.vhd1() + "/" + imageReference.offer();
|
return (imageReference.globallyAvailable() ? "global" : imageReference.location()) + "/" + imageReference.group() + "/" + imageReference.storage() + "/" + imageReference.offer() + "/" + imageReference.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VMImage decodeFieldsFromUniqueId(final String id) {
|
public static VMImage decodeFieldsFromUniqueId(final String id) {
|
||||||
|
@ -79,10 +71,10 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
0: imageReference.location) + "/" +
|
0: imageReference.location) + "/" +
|
||||||
1: imageReference.group + "/" +
|
1: imageReference.group + "/" +
|
||||||
2: imageReference.storage + "/" +
|
2: imageReference.storage + "/" +
|
||||||
3: imageReference.vhd1 + "/" +
|
3: imageReference.offer + "/" +
|
||||||
4: imageReference.offer
|
4: imageReference.name
|
||||||
*/
|
*/
|
||||||
vmImage = VMImage.create(fields[1], fields[2], fields[3], null, null, fields[4], fields[0]);
|
vmImage = VMImage.customImage().location(fields[0]).group(fields[1]).storage(fields[2]).vhd1(fields[3]).offer(fields[4]).build();
|
||||||
} else {
|
} else {
|
||||||
/* id fields indexes
|
/* id fields indexes
|
||||||
0: imageReference.location) + "/" +
|
0: imageReference.location) + "/" +
|
||||||
|
@ -90,7 +82,7 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
2: imageReference.offer + "/" +
|
2: imageReference.offer + "/" +
|
||||||
3: imageReference.sku + "/" +
|
3: imageReference.sku + "/" +
|
||||||
*/
|
*/
|
||||||
vmImage = VMImage.create(fields[1], fields[2], fields[3], null, fields[0]);
|
vmImage = VMImage.azureImage().location(fields[0]).publisher(fields[1]).offer(fields[2]).sku(fields[3]).build();
|
||||||
}
|
}
|
||||||
return vmImage;
|
return vmImage;
|
||||||
}
|
}
|
||||||
|
@ -102,26 +94,21 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Image apply(final VMImage image) {
|
public Image apply(final VMImage image) {
|
||||||
|
|
||||||
Credentials credentials = new Credentials(AZURE_LOGIN_USERNAME, AZURE_LOGIN_PASSWORD);
|
|
||||||
if (image.custom()) {
|
if (image.custom()) {
|
||||||
|
|
||||||
final ImageBuilder builder = new ImageBuilder()
|
final ImageBuilder builder = new ImageBuilder()
|
||||||
.location(FluentIterable.from(locations.get())
|
.location(FluentIterable.from(locations.get())
|
||||||
.firstMatch(LocationPredicates.idEquals(image.location()))
|
.firstMatch(LocationPredicates.idEquals(image.location()))
|
||||||
.get())
|
.get())
|
||||||
.name(image.name())
|
.name(image.name())
|
||||||
.description("#" + image.group())
|
.description(image.group())
|
||||||
.status(Image.Status.AVAILABLE)
|
.status(Image.Status.AVAILABLE)
|
||||||
.version(image.storage())
|
.version("latest")
|
||||||
.providerId(image.vhd1())
|
.providerId(image.vhd1())
|
||||||
.id(encodeFieldsToUniqueIdCustom(image))
|
.id(encodeFieldsToUniqueIdCustom(image));
|
||||||
.defaultCredentials(LoginCredentials.fromCredentials(credentials));
|
|
||||||
|
|
||||||
final OperatingSystem.Builder osBuilder = osFamily().apply(image);
|
final OperatingSystem.Builder osBuilder = osFamily().apply(image);
|
||||||
Image retimage = builder.operatingSystem(osBuilder.build()).build();
|
Image retimage = builder.operatingSystem(osBuilder.build()).build();
|
||||||
return retimage;
|
return retimage;
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final ImageBuilder builder = new ImageBuilder()
|
final ImageBuilder builder = new ImageBuilder()
|
||||||
|
@ -130,7 +117,6 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
.status(Image.Status.AVAILABLE)
|
.status(Image.Status.AVAILABLE)
|
||||||
.version(image.sku())
|
.version(image.sku())
|
||||||
.id(encodeFieldsToUniqueId(image))
|
.id(encodeFieldsToUniqueId(image))
|
||||||
.defaultCredentials(LoginCredentials.fromCredentials(credentials))
|
|
||||||
.providerId(image.publisher())
|
.providerId(image.publisher())
|
||||||
.location(image.globallyAvailable() ? null : FluentIterable.from(locations.get())
|
.location(image.globallyAvailable() ? null : FluentIterable.from(locations.get())
|
||||||
.firstMatch(LocationPredicates.idEquals(image.location()))
|
.firstMatch(LocationPredicates.idEquals(image.location()))
|
||||||
|
@ -149,11 +135,11 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
final String label = image.offer();
|
final String label = image.offer();
|
||||||
|
|
||||||
OsFamily family = OsFamily.UNRECOGNIZED;
|
OsFamily family = OsFamily.UNRECOGNIZED;
|
||||||
if (label.contains(CENTOS)) {
|
if (label.contains(CENTOS) || label.contains(OPENLOGIC)) {
|
||||||
family = OsFamily.CENTOS;
|
family = OsFamily.CENTOS;
|
||||||
} else if (label.contains(OPENLOGIC)) {
|
} else if (label.contains(COREOS)) {
|
||||||
family = OsFamily.CENTOS;
|
family = OsFamily.COREOS;
|
||||||
} else if (label.contains(SUSE)) {
|
} else if (label.contains(SUSE) || label.contains(SLES) || label.contains(OPENSUSE)) {
|
||||||
family = OsFamily.SUSE;
|
family = OsFamily.SUSE;
|
||||||
} else if (label.contains(UBUNTU)) {
|
} else if (label.contains(UBUNTU)) {
|
||||||
family = OsFamily.UBUNTU;
|
family = OsFamily.UBUNTU;
|
||||||
|
@ -161,18 +147,16 @@ public class VMImageToImage implements Function<VMImage, Image> {
|
||||||
family = OsFamily.WINDOWS;
|
family = OsFamily.WINDOWS;
|
||||||
} else if (label.contains(ORACLE_lINUX)) {
|
} else if (label.contains(ORACLE_lINUX)) {
|
||||||
family = OsFamily.OEL;
|
family = OsFamily.OEL;
|
||||||
|
} else if (label.contains(RHEL)) {
|
||||||
|
family = OsFamily.RHEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
String sku = image.sku();
|
|
||||||
if (image.custom())
|
|
||||||
sku = image.vhd1();
|
|
||||||
|
|
||||||
// only 64bit OS images are supported by Azure ARM
|
// only 64bit OS images are supported by Azure ARM
|
||||||
return OperatingSystem.builder().
|
return OperatingSystem.builder().
|
||||||
family(family).
|
family(family).
|
||||||
is64Bit(true).
|
is64Bit(true).
|
||||||
description(sku).
|
description(image.custom() ? image.vhd1() : image.sku()).
|
||||||
version(sku);
|
version(image.custom() ? "latest" : image.sku());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,279 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.azurecompute.arm.compute.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
import static com.google.common.collect.Iterables.tryFind;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CONTAINER_NAME;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.extensions.AzureComputeImageExtension.CUSTOM_IMAGE_OFFER;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.encodeFieldsToUniqueId;
|
||||||
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
|
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.AzureComputeConstants;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties.ProvisioningState;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.StorageProfileToStorageAccountName;
|
||||||
|
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||||
|
import org.jclouds.collect.Memoized;
|
||||||
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
|
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||||
|
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||||
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
|
import org.jclouds.domain.Credentials;
|
||||||
|
import org.jclouds.domain.Location;
|
||||||
|
import org.jclouds.domain.LoginCredentials;
|
||||||
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Functions;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.base.Supplier;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
public class VirtualMachineToNodeMetadata implements Function<VirtualMachine, NodeMetadata> {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
|
// When using the Deployment API to deploy an ARM template, the deployment
|
||||||
|
// goes through
|
||||||
|
// stages. Accepted -> Running -> Succeeded. Only when the deployment has
|
||||||
|
// SUCCEEDED is
|
||||||
|
// the resource deployed using the template actually ready.
|
||||||
|
//
|
||||||
|
// To get details about the resource(s) deployed via template, one needs to
|
||||||
|
// query the
|
||||||
|
// various resources after the deployment has "SUCCEEDED".
|
||||||
|
private static final Function<VirtualMachineProperties.ProvisioningState, NodeMetadata.Status> PROVISIONINGSTATE_TO_NODESTATUS = Functions
|
||||||
|
.forMap(
|
||||||
|
ImmutableMap.<VirtualMachineProperties.ProvisioningState, NodeMetadata.Status> builder()
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.ACCEPTED, NodeMetadata.Status.PENDING)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.READY, NodeMetadata.Status.PENDING)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.CREATING, NodeMetadata.Status.PENDING)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.RUNNING, NodeMetadata.Status.PENDING)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.UPDATING, NodeMetadata.Status.PENDING)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.SUCCEEDED, NodeMetadata.Status.RUNNING)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.DELETED, NodeMetadata.Status.TERMINATED)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.CANCELED, NodeMetadata.Status.TERMINATED)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.FAILED, NodeMetadata.Status.ERROR)
|
||||||
|
.put(VirtualMachineProperties.ProvisioningState.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED)
|
||||||
|
.build(), NodeMetadata.Status.UNRECOGNIZED);
|
||||||
|
|
||||||
|
private static final Function<VirtualMachineStatus.PowerState, NodeMetadata.Status> POWERSTATE_TO_NODESTATUS = Functions
|
||||||
|
.forMap(
|
||||||
|
ImmutableMap.<PowerState, NodeMetadata.Status> builder()
|
||||||
|
.put(PowerState.RUNNING, NodeMetadata.Status.RUNNING)
|
||||||
|
.put(PowerState.STOPPED, NodeMetadata.Status.SUSPENDED)
|
||||||
|
.put(PowerState.UNRECOGNIZED, NodeMetadata.Status.UNRECOGNIZED).build(),
|
||||||
|
NodeMetadata.Status.UNRECOGNIZED);
|
||||||
|
|
||||||
|
private final String azureGroup;
|
||||||
|
private final AzureComputeApi api;
|
||||||
|
private final GroupNamingConvention nodeNamingConvention;
|
||||||
|
private final Supplier<Map<String, ? extends Image>> images;
|
||||||
|
private final Supplier<Set<? extends Location>> locations;
|
||||||
|
private final Supplier<Map<String, ? extends Hardware>> hardwares;
|
||||||
|
private final Map<String, Credentials> credentialStore;
|
||||||
|
private final Function<VMImage, Image> vmImageToImge;
|
||||||
|
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
VirtualMachineToNodeMetadata(AzureComputeApi api, GroupNamingConvention.Factory namingConvention,
|
||||||
|
Supplier<Map<String, ? extends Image>> images, Supplier<Map<String, ? extends Hardware>> hardwares,
|
||||||
|
@Memoized Supplier<Set<? extends Location>> locations, Map<String, Credentials> credentialStore,
|
||||||
|
final AzureComputeConstants azureComputeConstants, Function<VMImage, Image> vmImageToImge,
|
||||||
|
StorageProfileToStorageAccountName storageProfileToStorageAccountName) {
|
||||||
|
this.api = api;
|
||||||
|
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
|
||||||
|
this.images = checkNotNull(images, "images cannot be null");
|
||||||
|
this.locations = checkNotNull(locations, "locations cannot be null");
|
||||||
|
this.hardwares = checkNotNull(hardwares, "hardwares cannot be null");
|
||||||
|
this.credentialStore = credentialStore;
|
||||||
|
this.azureGroup = azureComputeConstants.azureResourceGroup();
|
||||||
|
this.vmImageToImge = vmImageToImge;
|
||||||
|
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NodeMetadata apply(VirtualMachine virtualMachine) {
|
||||||
|
NodeMetadataBuilder builder = new NodeMetadataBuilder();
|
||||||
|
builder.id(virtualMachine.name());
|
||||||
|
builder.providerId(virtualMachine.id());
|
||||||
|
builder.name(virtualMachine.name());
|
||||||
|
builder.hostname(virtualMachine.name());
|
||||||
|
String group = this.nodeNamingConvention.extractGroup(virtualMachine.name());
|
||||||
|
builder.group(group);
|
||||||
|
|
||||||
|
ProvisioningState provisioningState = virtualMachine.properties().provisioningState();
|
||||||
|
if (ProvisioningState.SUCCEEDED.equals(provisioningState)) {
|
||||||
|
// If the provisioning succeeded, we need to query the *real* status of
|
||||||
|
// the VM
|
||||||
|
VirtualMachineInstance instanceDetails = api.getVirtualMachineApi(azureGroup).getInstanceDetails(
|
||||||
|
virtualMachine.name());
|
||||||
|
builder.status(POWERSTATE_TO_NODESTATUS.apply(instanceDetails.powerState()));
|
||||||
|
builder.backendStatus(Joiner.on(',').join(
|
||||||
|
transform(instanceDetails.statuses(), new Function<VirtualMachineStatus, String>() {
|
||||||
|
@Override
|
||||||
|
public String apply(VirtualMachineStatus input) {
|
||||||
|
return input.code();
|
||||||
|
}
|
||||||
|
})));
|
||||||
|
} else {
|
||||||
|
builder.status(PROVISIONINGSTATE_TO_NODESTATUS.apply(provisioningState));
|
||||||
|
builder.backendStatus(provisioningState.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
Credentials credentials = credentialStore.get("node#" + virtualMachine.name());
|
||||||
|
builder.credentials(LoginCredentials.fromCredentials(credentials));
|
||||||
|
|
||||||
|
builder.publicAddresses(getPublicIpAddresses(virtualMachine.properties().networkProfile().networkInterfaces()));
|
||||||
|
builder.privateAddresses(getPrivateIpAddresses(virtualMachine.properties().networkProfile().networkInterfaces()));
|
||||||
|
|
||||||
|
if (virtualMachine.tags() != null) {
|
||||||
|
Map<String, String> userMetaData = virtualMachine.tags();
|
||||||
|
builder.userMetadata(userMetaData);
|
||||||
|
builder.tags(Splitter.on(",").split(userMetaData.get("tags")));
|
||||||
|
}
|
||||||
|
String locationName = virtualMachine.location();
|
||||||
|
builder.location(getLocation(locationName));
|
||||||
|
|
||||||
|
Optional<? extends Image> image = findImage(virtualMachine.properties().storageProfile(), locationName);
|
||||||
|
if (image.isPresent()) {
|
||||||
|
builder.imageId(image.get().getId());
|
||||||
|
builder.operatingSystem(image.get().getOperatingSystem());
|
||||||
|
} else {
|
||||||
|
logger.info(">> image with id %s for virtualmachine %s was not found. "
|
||||||
|
+ "This might be because the image that was used to create the virtualmachine has a new id.",
|
||||||
|
virtualMachine.id(), virtualMachine.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.hardware(getHardware(virtualMachine.properties().hardwareProfile().vmSize()));
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<String> getPrivateIpAddresses(List<IdReference> idReferences) {
|
||||||
|
List<String> privateIpAddresses = Lists.newArrayList();
|
||||||
|
for (IdReference networkInterfaceCardIdReference : idReferences) {
|
||||||
|
NetworkInterfaceCard networkInterfaceCard = getNetworkInterfaceCard(networkInterfaceCardIdReference);
|
||||||
|
for (IpConfiguration ipConfiguration : networkInterfaceCard.properties().ipConfigurations()) {
|
||||||
|
privateIpAddresses.add(ipConfiguration.properties().privateIPAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return privateIpAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkInterfaceCard getNetworkInterfaceCard(IdReference networkInterfaceCardIdReference) {
|
||||||
|
Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 2);
|
||||||
|
String resourceGroup = Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 4);
|
||||||
|
String nicName = Iterables.getLast(Splitter.on("/").split(networkInterfaceCardIdReference.id()));
|
||||||
|
return api.getNetworkInterfaceCardApi(resourceGroup).get(nicName);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<String> getPublicIpAddresses(List<IdReference> idReferences) {
|
||||||
|
List<String> publicIpAddresses = Lists.newArrayList();
|
||||||
|
for (IdReference networkInterfaceCardIdReference : idReferences) {
|
||||||
|
NetworkInterfaceCard networkInterfaceCard = getNetworkInterfaceCard(networkInterfaceCardIdReference);
|
||||||
|
String resourceGroup = Iterables.get(Splitter.on("/").split(networkInterfaceCardIdReference.id()), 4);
|
||||||
|
for (IpConfiguration ipConfiguration : networkInterfaceCard.properties().ipConfigurations()) {
|
||||||
|
if (ipConfiguration.properties().publicIPAddress() != null) {
|
||||||
|
String publicIpId = ipConfiguration.properties().publicIPAddress().id();
|
||||||
|
publicIpAddresses.add(api.getPublicIPAddressApi(resourceGroup)
|
||||||
|
.get(Iterables.getLast(Splitter.on("/").split(publicIpId))).properties().ipAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return publicIpAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Location getLocation(final String locationName) {
|
||||||
|
return find(locations.get(), new Predicate<Location>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Location location) {
|
||||||
|
return locationName != null && locationName.equals(location.getId());
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Optional<? extends Image> findImage(final StorageProfile storageProfile, String locatioName) {
|
||||||
|
if (storageProfile.imageReference() != null) {
|
||||||
|
return Optional.fromNullable(images.get().get(
|
||||||
|
encodeFieldsToUniqueId(false, locatioName, storageProfile.imageReference())));
|
||||||
|
} else {
|
||||||
|
String storageAccountName = storageProfileToStorageAccountName.apply(storageProfile);
|
||||||
|
StorageServiceKeys keys = api.getStorageAccountApi(azureGroup).getKeys(storageAccountName);
|
||||||
|
BlobHelper blobHelper = new BlobHelper(storageAccountName, keys.key1());
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Custom image. Let's find it by uri
|
||||||
|
List<VMImage> customImagesInStorage = blobHelper.getImages(CONTAINER_NAME, azureGroup, CUSTOM_IMAGE_OFFER,
|
||||||
|
locatioName);
|
||||||
|
Optional<VMImage> customImage = tryFind(customImagesInStorage, new Predicate<VMImage>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(VMImage input) {
|
||||||
|
return input.vhd1().equals(storageProfile.osDisk().image().uri());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return customImage.isPresent() ? Optional.of(vmImageToImge.apply(customImage.get())) : Optional
|
||||||
|
.<Image> absent();
|
||||||
|
} finally {
|
||||||
|
closeQuietly(blobHelper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Hardware getHardware(final String vmSize) {
|
||||||
|
return Iterables.find(hardwares.get().values(), new Predicate<Hardware>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(Hardware input) {
|
||||||
|
return input.getId().equals(vmSize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,10 +16,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute.options;
|
package org.jclouds.azurecompute.arm.compute.options;
|
||||||
|
|
||||||
import static com.google.common.base.Objects.equal;
|
|
||||||
import org.jclouds.compute.options.TemplateOptions;
|
import org.jclouds.compute.options.TemplateOptions;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
|
import static com.google.common.base.Objects.equal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Azure ARM custom options
|
* Azure ARM custom options
|
||||||
*/
|
*/
|
||||||
|
@ -31,7 +33,9 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
private String subnetAddressPrefix;
|
private String subnetAddressPrefix;
|
||||||
private String DNSLabelPrefix;
|
private String DNSLabelPrefix;
|
||||||
private String keyVaultIdAndSecret;
|
private String keyVaultIdAndSecret;
|
||||||
|
private String virtualNetworkName;
|
||||||
|
private String subnetId;
|
||||||
|
private String blob;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom options for the Azure ARM API
|
* Custom options for the Azure ARM API
|
||||||
|
@ -40,8 +44,6 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
this.customData = customData;
|
this.customData = customData;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
private String virtualNetworkName;
|
|
||||||
private String subnetId;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the CIDR block for virtual network
|
* Sets the CIDR block for virtual network
|
||||||
|
@ -75,15 +77,6 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
return this;
|
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
|
* Sets the virtual network name
|
||||||
*/
|
*/
|
||||||
|
@ -100,6 +93,24 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the blob name
|
||||||
|
*/
|
||||||
|
public AzureTemplateOptions blob(String blob) {
|
||||||
|
this.blob = blob;
|
||||||
|
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; }
|
||||||
|
public String getBlob() { return blob; }
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AzureTemplateOptions clone() {
|
public AzureTemplateOptions clone() {
|
||||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||||
|
@ -119,12 +130,13 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
eTo.keyVaultIdAndSecret(keyVaultIdAndSecret);
|
eTo.keyVaultIdAndSecret(keyVaultIdAndSecret);
|
||||||
eTo.virtualNetworkName(virtualNetworkName);
|
eTo.virtualNetworkName(virtualNetworkName);
|
||||||
eTo.subnetId(subnetId);
|
eTo.subnetId(subnetId);
|
||||||
|
eTo.blob(blob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(super.hashCode(), virtualNetworkAddressPrefix, subnetAddressPrefix, DNSLabelPrefix, customData, keyVaultIdAndSecret, virtualNetworkName, subnetId);
|
return Objects.hashCode(super.hashCode(), virtualNetworkAddressPrefix, subnetAddressPrefix, DNSLabelPrefix, customData, keyVaultIdAndSecret, virtualNetworkName, subnetId, blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -146,7 +158,8 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
&& equal(this.DNSLabelPrefix, other.DNSLabelPrefix)
|
&& equal(this.DNSLabelPrefix, other.DNSLabelPrefix)
|
||||||
&& equal(this.keyVaultIdAndSecret, other.keyVaultIdAndSecret)
|
&& equal(this.keyVaultIdAndSecret, other.keyVaultIdAndSecret)
|
||||||
&& equal(this.virtualNetworkName, other.virtualNetworkName)
|
&& equal(this.virtualNetworkName, other.virtualNetworkName)
|
||||||
&& equal(this.subnetId, other.subnetId);
|
&& equal(this.subnetId, other.subnetId)
|
||||||
|
&& equal(this.blob, other.blob);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -159,6 +172,7 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
toString.add("keyVaultIdAndSecret", keyVaultIdAndSecret);
|
toString.add("keyVaultIdAndSecret", keyVaultIdAndSecret);
|
||||||
toString.add("virtualNetworkName", virtualNetworkName);
|
toString.add("virtualNetworkName", virtualNetworkName);
|
||||||
toString.add("subnetId", subnetId);
|
toString.add("subnetId", subnetId);
|
||||||
|
toString.add("blob", blob);
|
||||||
return toString;
|
return toString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,5 +233,13 @@ public class AzureTemplateOptions extends TemplateOptions implements Cloneable {
|
||||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||||
return options.subnetId(subnetId);
|
return options.subnetId(subnetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see AzureTemplateOptions#blob
|
||||||
|
*/
|
||||||
|
public static AzureTemplateOptions blob(String blob) {
|
||||||
|
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||||
|
return options.blob(blob);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ public class IsDeploymentInRegions implements Predicate<Deployment> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(Deployment deployment) {
|
public boolean apply(Deployment deployment) {
|
||||||
|
if (deployment.properties() == null || deployment.properties().parameters() == null || deployment.properties().parameters().get("location") == null) return false;
|
||||||
Value locationValue = deployment.properties().parameters().get("location");
|
Value locationValue = deployment.properties().parameters().get("location");
|
||||||
return regionIds.get().contains(locationValue.value());
|
return regionIds.get().contains(locationValue.value());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +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.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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -17,26 +17,36 @@
|
||||||
package org.jclouds.azurecompute.arm.compute.strategy;
|
package org.jclouds.azurecompute.arm.compute.strategy;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static org.jclouds.azurecompute.arm.compute.functions.VMImageToImage.decodeFieldsFromUniqueId;
|
||||||
|
import static org.jclouds.util.Predicates2.retry;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
|
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
|
||||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
||||||
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
|
import org.jclouds.azurecompute.arm.features.ResourceGroupApi;
|
||||||
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
import org.jclouds.azurecompute.arm.features.SubnetApi;
|
||||||
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
|
import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
|
||||||
import org.jclouds.compute.config.CustomizationResponse;
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
|
import org.jclouds.compute.domain.Image;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||||
|
@ -45,9 +55,11 @@ import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||||
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||||
import org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
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 org.jclouds.logging.Logger;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Strings;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||||
|
@ -81,7 +93,13 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
||||||
public Map<?, ListenableFuture<Void>> execute(String group, int count, Template template,
|
public Map<?, ListenableFuture<Void>> execute(String group, int count, Template template,
|
||||||
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
|
Set<NodeMetadata> goodNodes, Map<NodeMetadata, Exception> badNodes,
|
||||||
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||||
|
// If there is a script to be run on the node and public key
|
||||||
|
// authentication has been configured, warn users if the private key
|
||||||
|
// is not present
|
||||||
|
if (hasRunScriptWithKeyAuthAndNoPrivateKey(template)) {
|
||||||
|
logger.warn(">> a runScript was configured but no SSH key has been provided. " +
|
||||||
|
"Authentication will delegate to the ssh-agent");
|
||||||
|
}
|
||||||
String azureGroupName = this.azureComputeConstants.azureResourceGroup();
|
String azureGroupName = this.azureComputeConstants.azureResourceGroup();
|
||||||
|
|
||||||
AzureTemplateOptions options = template.getOptions().as(AzureTemplateOptions.class);
|
AzureTemplateOptions options = template.getOptions().as(AzureTemplateOptions.class);
|
||||||
|
@ -91,7 +109,7 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
||||||
final String location = template.getLocation().getId();
|
final String location = template.getLocation().getId();
|
||||||
|
|
||||||
if (resourceGroup == null){
|
if (resourceGroup == null){
|
||||||
final Map<String, String> tags = ImmutableMap.of("description", "jClouds managed VMs");
|
final Map<String, String> tags = ImmutableMap.of("description", "jclouds managed VMs");
|
||||||
resourceGroupApi.create(azureGroupName, location, tags).name();
|
resourceGroupApi.create(azureGroupName, location, tags).name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +122,9 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
||||||
|
|
||||||
this.getOrCreateVirtualNetworkWithSubnet(vnetName, subnetName, location, options, azureGroupName);
|
this.getOrCreateVirtualNetworkWithSubnet(vnetName, subnetName, location, options, azureGroupName);
|
||||||
|
|
||||||
|
StorageService storageService = getOrCreateStorageService(group, azureGroupName, location, template.getImage());
|
||||||
|
String blob = storageService.storageServiceProperties().primaryEndpoints().get("blob");
|
||||||
|
options.blob(blob);
|
||||||
|
|
||||||
Map<?, ListenableFuture<Void>> responses = super.execute(group, count, template, goodNodes, badNodes,
|
Map<?, ListenableFuture<Void>> responses = super.execute(group, count, template, goodNodes, badNodes,
|
||||||
customizationResponses);
|
customizationResponses);
|
||||||
|
@ -135,6 +156,70 @@ public class CreateResourceGroupThenCreateNodes extends CreateNodesWithGroupEnco
|
||||||
|
|
||||||
options.virtualNetworkName(virtualNetworkName);
|
options.virtualNetworkName(virtualNetworkName);
|
||||||
options.subnetId(subnet.id());
|
options.subnetId(subnet.id());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasRunScriptWithKeyAuthAndNoPrivateKey(Template template) {
|
||||||
|
return template.getOptions().getRunScript() != null && template.getOptions().getPublicKey() != null
|
||||||
|
&& !template.getOptions().hasLoginPrivateKeyOption();
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageService getOrCreateStorageService(String name, String resourceGroupName, String locationName, Image image) {
|
||||||
|
String storageAccountName = null;
|
||||||
|
VMImage imageRef = decodeFieldsFromUniqueId(image.getId());
|
||||||
|
if (imageRef.custom()) {
|
||||||
|
storageAccountName = imageRef.storage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Strings.isNullOrEmpty(storageAccountName)) {
|
||||||
|
storageAccountName = generateStorageAccountName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
StorageService storageService = api.getStorageAccountApi(resourceGroupName).get(storageAccountName);
|
||||||
|
if (storageService != null) return storageService;
|
||||||
|
|
||||||
|
URI uri = api.getStorageAccountApi(resourceGroupName).create(storageAccountName, locationName, ImmutableMap.of("jclouds",
|
||||||
|
name), ImmutableMap.of("accountType", StorageService.AccountType.Standard_LRS.toString()));
|
||||||
|
boolean starageAccountCreated = retry(new Predicate<URI>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(URI uri) {
|
||||||
|
return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri);
|
||||||
|
}
|
||||||
|
}, 60 * 2 * 1000 /* 2 minutes timeout */).apply(uri);
|
||||||
|
// TODO check provisioning state of the primary
|
||||||
|
checkState(starageAccountCreated, "Storage account %s was not created in the configured timeout",
|
||||||
|
storageAccountName);
|
||||||
|
return api.getStorageAccountApi(resourceGroupName).get(storageAccountName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a valid storage account
|
||||||
|
*
|
||||||
|
* Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only.
|
||||||
|
*
|
||||||
|
* @param name the node name
|
||||||
|
* @return the storage account name starting from a sanitized name (with only numbers and lowercase letters only ).
|
||||||
|
* If sanitized name is between 3 and 24 characters, storage account name is equals to sanitized name.
|
||||||
|
* If sanitized name is less than 3 characters, storage account is sanitized name plus 4 random chars.
|
||||||
|
* If sanitized name is more than 24 characters, storage account is first 10 chars of sanitized name plus 4 random chars plus last 10 chars of sanitized name.
|
||||||
|
*/
|
||||||
|
public static String generateStorageAccountName(String name) {
|
||||||
|
String random = UUID.randomUUID().toString().substring(0, 4);
|
||||||
|
String storageAccountName = new StringBuilder().append(name).append(random).toString();
|
||||||
|
String sanitizedStorageAccountName = storageAccountName.replaceAll("[^a-z0-9]", "");
|
||||||
|
int nameLength = sanitizedStorageAccountName.length();
|
||||||
|
if (nameLength >= 3 && nameLength <= 24) {
|
||||||
|
return sanitizedStorageAccountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameLength > 24) {
|
||||||
|
sanitizedStorageAccountName = shorten(storageAccountName, random);
|
||||||
|
}
|
||||||
|
return sanitizedStorageAccountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String shorten(String storageAccountName, String random) {
|
||||||
|
String prefix = storageAccountName.substring(0, 10);
|
||||||
|
String suffix = storageAccountName.substring(storageAccountName.length() - 10, storageAccountName.length());
|
||||||
|
return String.format("%s%s%s", prefix, random, suffix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,6 @@ package org.jclouds.azurecompute.arm.config;
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
import org.jclouds.azurecompute.arm.handlers.AzureComputeErrorHandler;
|
import org.jclouds.azurecompute.arm.handlers.AzureComputeErrorHandler;
|
||||||
import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
|
|
||||||
import org.jclouds.http.HttpErrorHandler;
|
import org.jclouds.http.HttpErrorHandler;
|
||||||
import org.jclouds.http.annotation.ClientError;
|
import org.jclouds.http.annotation.ClientError;
|
||||||
import org.jclouds.http.annotation.Redirection;
|
import org.jclouds.http.annotation.Redirection;
|
||||||
|
@ -30,7 +29,6 @@ import org.jclouds.rest.ConfiguresHttpApi;
|
||||||
import org.jclouds.rest.config.HttpApiModule;
|
import org.jclouds.rest.config.HttpApiModule;
|
||||||
|
|
||||||
import com.google.inject.Scopes;
|
import com.google.inject.Scopes;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
|
||||||
|
|
||||||
@ConfiguresHttpApi
|
@ConfiguresHttpApi
|
||||||
public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
|
public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
|
||||||
|
@ -51,7 +49,6 @@ public class AzureComputeHttpApiModule extends HttpApiModule<AzureComputeApi> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
install(new FactoryModuleBuilder().build(DeploymentTemplateBuilder.Factory.class));
|
|
||||||
super.configure();
|
super.configure();
|
||||||
bind(OAuthScopes.class).toInstance(OAuthScopes.NoScopes.create());
|
bind(OAuthScopes.class).toInstance(OAuthScopes.NoScopes.create());
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
package org.jclouds.azurecompute.arm.config;
|
package org.jclouds.azurecompute.arm.config;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties and constants used in Azure Resource Manager connections.
|
* Configuration properties and constants used in Azure Resource Manager
|
||||||
|
* connections.
|
||||||
*/
|
*/
|
||||||
public class AzureComputeProperties {
|
public class AzureComputeProperties {
|
||||||
|
|
||||||
|
public static final String STORAGE_API_VERSION = "2015-06-15";
|
||||||
|
|
||||||
public static final String OPERATION_TIMEOUT = "jclouds.azurecompute.arm.operation.timeout";
|
public static final String OPERATION_TIMEOUT = "jclouds.azurecompute.arm.operation.timeout";
|
||||||
|
|
||||||
public static final String OPERATION_POLL_INITIAL_PERIOD = "jclouds.azurecompute.arm.operation.poll.initial.period";
|
public static final String OPERATION_POLL_INITIAL_PERIOD = "jclouds.azurecompute.arm.operation.poll.initial.period";
|
||||||
|
@ -31,8 +34,6 @@ public class AzureComputeProperties {
|
||||||
|
|
||||||
public static final String TCP_RULE_REGEXP = "jclouds.azurecompute.arm.tcp.rule.regexp";
|
public static final String TCP_RULE_REGEXP = "jclouds.azurecompute.arm.tcp.rule.regexp";
|
||||||
|
|
||||||
public static final String STORAGE_API_VERSION = "2015-06-15";
|
|
||||||
|
|
||||||
public static final String RESOURCE_GROUP_NAME = "jclouds.azurecompute.arm.operation.resourcegroup";
|
public static final String RESOURCE_GROUP_NAME = "jclouds.azurecompute.arm.operation.resourcegroup";
|
||||||
|
|
||||||
public static final String IMAGE_PUBLISHERS = "jclouds.azurecompute.arm.publishers";
|
public static final String IMAGE_PUBLISHERS = "jclouds.azurecompute.arm.publishers";
|
||||||
|
@ -47,4 +48,6 @@ public class AzureComputeProperties {
|
||||||
|
|
||||||
public static final String DEFAULT_DATADISKSIZE = "jclouds.azurecompute.arm.datadisksize";
|
public static final String DEFAULT_DATADISKSIZE = "jclouds.azurecompute.arm.datadisksize";
|
||||||
|
|
||||||
|
public static final String API_VERSION_PREFIX = "jclouds.azurecompute.arm.apiversion.";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,43 +16,29 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.domain;
|
package org.jclouds.azurecompute.arm.domain;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.auto.value.AutoValue;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class VMDeployment {
|
public abstract class VMDeployment {
|
||||||
|
|
||||||
public abstract Deployment deployment();
|
public abstract String deploymentId();
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public abstract List<PublicIPAddress> ipAddressList();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public abstract VirtualMachineInstance vm();
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract VirtualMachine virtualMachine();
|
public abstract VirtualMachine virtualMachine();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public abstract List<PublicIPAddress> ipAddressList();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract List<NetworkInterfaceCard> networkInterfaceCards();
|
public abstract List<NetworkInterfaceCard> networkInterfaceCards();
|
||||||
|
|
||||||
@Nullable
|
public static VMDeployment create(String deploymentId, VirtualMachine virtualMachine,
|
||||||
public abstract Map<String, String> userMetaData();
|
List<PublicIPAddress> ipAddressList,
|
||||||
|
List<NetworkInterfaceCard> networkInterfaceCards) {
|
||||||
@Nullable
|
return new AutoValue_VMDeployment(deploymentId, virtualMachine, ipAddressList, networkInterfaceCards);
|
||||||
public abstract Iterable<String> tags();
|
|
||||||
|
|
||||||
public static VMDeployment create(Deployment deployment) {
|
|
||||||
return create(deployment, null, null, null, null, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static VMDeployment create(Deployment deployment, List<PublicIPAddress> ipAddressList,
|
|
||||||
VirtualMachineInstance vm, VirtualMachine virtualMachine,
|
|
||||||
List<NetworkInterfaceCard> networkInterfaceCards, Map<String, String> userMetaData,
|
|
||||||
Iterable<String> tags) {
|
|
||||||
return new AutoValue_VMDeployment(deployment, ipAddressList, vm, virtualMachine, networkInterfaceCards, userMetaData, tags);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.domain;
|
package org.jclouds.azurecompute.arm.domain;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.json.SerializedNames;
|
|
||||||
|
import com.google.auto.value.AutoValue;
|
||||||
|
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class VMImage {
|
public abstract class VMImage {
|
||||||
|
@ -92,15 +92,34 @@ public abstract class VMImage {
|
||||||
*/
|
*/
|
||||||
public abstract boolean custom();
|
public abstract boolean custom();
|
||||||
|
|
||||||
@SerializedNames({ "publisher", "offer", "sku", "version", "location"})
|
public static Builder builder() {
|
||||||
public static VMImage create(String publisher, String offer, String sku, String version, String location) {
|
return new AutoValue_VMImage.Builder();
|
||||||
|
|
||||||
return new AutoValue_VMImage(publisher, offer, sku, version, location, false, null, null, null, null, null, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SerializedNames({ "group", "storage", "vhd1", "vhd2", "name", "offer", "location"})
|
public static Builder azureImage() {
|
||||||
public static VMImage create(String group, String storage, String vhd1, String vhd2, String name, String offer, String location) {
|
return new AutoValue_VMImage.Builder().globallyAvailable(false).custom(false);
|
||||||
|
}
|
||||||
|
|
||||||
return new AutoValue_VMImage(null, offer, null, null, location, false, group, storage, vhd1, vhd2, name, true);
|
public static Builder customImage() {
|
||||||
|
return new AutoValue_VMImage.Builder().globallyAvailable(false).custom(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AutoValue.Builder
|
||||||
|
public abstract static class Builder {
|
||||||
|
|
||||||
|
public abstract Builder publisher(String published);
|
||||||
|
public abstract Builder offer(String offer);
|
||||||
|
public abstract Builder sku(String sku);
|
||||||
|
public abstract Builder version(String version);
|
||||||
|
public abstract Builder location(String location);
|
||||||
|
public abstract Builder globallyAvailable(boolean globallyAvailable);
|
||||||
|
public abstract Builder group(String group);
|
||||||
|
public abstract Builder storage(String storage);
|
||||||
|
public abstract Builder vhd1(String vhd1);
|
||||||
|
public abstract Builder vhd2(String vhd2);
|
||||||
|
public abstract Builder name(String name);
|
||||||
|
public abstract Builder custom(boolean custom);
|
||||||
|
|
||||||
|
public abstract VMImage build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.domain;
|
package org.jclouds.azurecompute.arm.domain;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import java.util.Map;
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.json.SerializedNames;
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
import java.util.Map;
|
import com.google.auto.value.AutoValue;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A virtual machine that is valid for your subscription.
|
* A virtual machine that is valid for your subscription.
|
||||||
|
|
|
@ -16,13 +16,23 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.domain;
|
package org.jclouds.azurecompute.arm.domain;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
import com.google.common.collect.ImmutableList;
|
import static com.google.common.collect.Iterables.getFirst;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
import static org.jclouds.util.Predicates2.startsWith;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties.ProvisioningState;
|
||||||
|
import org.jclouds.azurecompute.arm.util.GetEnumValue;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.json.SerializedNames;
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
import java.util.Date;
|
import com.google.auto.value.AutoValue;
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A virtual machine instance view that is valid for your subscription.
|
* A virtual machine instance view that is valid for your subscription.
|
||||||
|
@ -30,9 +40,22 @@ import java.util.Date;
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class VirtualMachineInstance {
|
public abstract class VirtualMachineInstance {
|
||||||
|
|
||||||
@AutoValue
|
@com.google.auto.value.AutoValue
|
||||||
public abstract static class VirtualMachineStatus {
|
public abstract static class VirtualMachineStatus {
|
||||||
|
|
||||||
|
public static final String PROVISIONING_STATE_PREFIX = "ProvisioningState/";
|
||||||
|
public static final String POWER_STATE_PREFIX = "PowerState/";
|
||||||
|
|
||||||
|
public enum PowerState {
|
||||||
|
RUNNING,
|
||||||
|
STOPPED,
|
||||||
|
UNRECOGNIZED;
|
||||||
|
|
||||||
|
public static PowerState fromValue(final String text) {
|
||||||
|
return (PowerState) GetEnumValue.fromValueOrDefault(text, PowerState.UNRECOGNIZED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract String code();
|
public abstract String code();
|
||||||
|
|
||||||
|
@ -62,6 +85,26 @@ public abstract class VirtualMachineInstance {
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract List<VirtualMachineStatus> statuses();
|
public abstract List<VirtualMachineStatus> statuses();
|
||||||
|
|
||||||
|
public ProvisioningState provisioningState() {
|
||||||
|
return ProvisioningState.fromValue(firstStatus(VirtualMachineStatus.PROVISIONING_STATE_PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PowerState powerState() {
|
||||||
|
return PowerState.fromValue(firstStatus(VirtualMachineStatus.POWER_STATE_PREFIX));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String firstStatus(final String type) {
|
||||||
|
return getFirst(transform(filter(transform(statuses(), new Function<VirtualMachineStatus, String>() {
|
||||||
|
@Override public String apply(VirtualMachineStatus input) {
|
||||||
|
return input.code();
|
||||||
|
}
|
||||||
|
}), startsWith(type)), new Function<String, String>() {
|
||||||
|
@Override public String apply(String input) {
|
||||||
|
return input.substring(type.length());
|
||||||
|
}
|
||||||
|
}), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SerializedNames({"platformUpdateDomain", "platformFaultDomain", "statuses"})
|
@SerializedNames({"platformUpdateDomain", "platformFaultDomain", "statuses"})
|
||||||
public static VirtualMachineInstance create(final String platformUpdateDomain, final String platformFaultDomain,
|
public static VirtualMachineInstance create(final String platformUpdateDomain, final String platformFaultDomain,
|
||||||
|
|
|
@ -16,16 +16,35 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.domain;
|
package org.jclouds.azurecompute.arm.domain;
|
||||||
|
|
||||||
import com.google.auto.value.AutoValue;
|
import org.jclouds.azurecompute.arm.util.GetEnumValue;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.json.SerializedNames;
|
import org.jclouds.json.SerializedNames;
|
||||||
|
|
||||||
|
import com.google.auto.value.AutoValue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A virtual machine properties for the virtual machine.
|
* A virtual machine properties for the virtual machine.
|
||||||
*/
|
*/
|
||||||
@AutoValue
|
@AutoValue
|
||||||
public abstract class VirtualMachineProperties {
|
public abstract class VirtualMachineProperties {
|
||||||
|
|
||||||
|
public enum ProvisioningState {
|
||||||
|
ACCEPTED,
|
||||||
|
CREATING,
|
||||||
|
READY,
|
||||||
|
CANCELED,
|
||||||
|
FAILED,
|
||||||
|
DELETED,
|
||||||
|
SUCCEEDED,
|
||||||
|
RUNNING,
|
||||||
|
UPDATING,
|
||||||
|
UNRECOGNIZED;
|
||||||
|
|
||||||
|
public static ProvisioningState fromValue(final String text) {
|
||||||
|
return (ProvisioningState) GetEnumValue.fromValueOrDefault(text, ProvisioningState.UNRECOGNIZED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the virtual machine.
|
* The id of the virtual machine.
|
||||||
*/
|
*/
|
||||||
|
@ -78,7 +97,7 @@ public abstract class VirtualMachineProperties {
|
||||||
* The provisioning state of the VM
|
* The provisioning state of the VM
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public abstract String provisioningState();
|
public abstract ProvisioningState provisioningState();
|
||||||
|
|
||||||
@SerializedNames({"vmId", "licenseType", "availabilitySet", "hardwareProfile", "storageProfile", "osProfile",
|
@SerializedNames({"vmId", "licenseType", "availabilitySet", "hardwareProfile", "storageProfile", "osProfile",
|
||||||
"networkProfile", "diagnosticsProfile", "provisioningState"})
|
"networkProfile", "diagnosticsProfile", "provisioningState"})
|
||||||
|
@ -90,7 +109,7 @@ public abstract class VirtualMachineProperties {
|
||||||
final OSProfile osProfile,
|
final OSProfile osProfile,
|
||||||
final NetworkProfile networkProfile,
|
final NetworkProfile networkProfile,
|
||||||
final DiagnosticsProfile diagnosticsProfile,
|
final DiagnosticsProfile diagnosticsProfile,
|
||||||
final String provisioningState) {
|
final ProvisioningState provisioningState) {
|
||||||
return builder()
|
return builder()
|
||||||
.vmId(vmId)
|
.vmId(vmId)
|
||||||
.licenseType(licenseType)
|
.licenseType(licenseType)
|
||||||
|
@ -126,7 +145,7 @@ public abstract class VirtualMachineProperties {
|
||||||
|
|
||||||
public abstract Builder diagnosticsProfile(DiagnosticsProfile diagnosticsProfile);
|
public abstract Builder diagnosticsProfile(DiagnosticsProfile diagnosticsProfile);
|
||||||
|
|
||||||
public abstract Builder provisioningState(String provisioningState);
|
public abstract Builder provisioningState(ProvisioningState provisioningState);
|
||||||
|
|
||||||
public abstract VirtualMachineProperties build();
|
public abstract VirtualMachineProperties build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,12 +34,12 @@ import org.jclouds.Fallbacks;
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.azurecompute.arm.domain.Deployment;
|
import org.jclouds.azurecompute.arm.domain.Deployment;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.Payload;
|
import org.jclouds.rest.annotations.Payload;
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
@ -50,8 +50,7 @@ import org.jclouds.rest.annotations.SelectJson;
|
||||||
* - get information about deployment
|
* - get information about deployment
|
||||||
*/
|
*/
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/microsoft.resources/deployments")
|
@Path("/resourcegroups/{resourcegroup}/providers/microsoft.resources/deployments")
|
||||||
@QueryParams(keys = "api-version", values = "2016-02-01")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface DeploymentApi {
|
public interface DeploymentApi {
|
||||||
|
|
||||||
|
|
|
@ -18,19 +18,20 @@ package org.jclouds.azurecompute.arm.features;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import org.jclouds.Fallbacks;
|
||||||
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.ParseJobStatus.JobStatus;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.EndpointParam;
|
import org.jclouds.rest.annotations.EndpointParam;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
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;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,11 +27,11 @@ import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
import org.jclouds.azurecompute.arm.domain.Location;
|
import org.jclouds.azurecompute.arm.domain.Location;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Azure Resource Manager API provides all of the locations that are available for resource providers
|
* This Azure Resource Manager API provides all of the locations that are available for resource providers
|
||||||
|
@ -40,8 +40,7 @@ import org.jclouds.rest.annotations.Fallback;
|
||||||
* @see <a href="https://msdn.microsoft.com/en-US/library/azure/dn790540.aspx">docs</a>
|
* @see <a href="https://msdn.microsoft.com/en-US/library/azure/dn790540.aspx">docs</a>
|
||||||
*/
|
*/
|
||||||
@Path("/locations")
|
@Path("/locations")
|
||||||
@RequestFilters(OAuthFilter.class)
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@QueryParams(keys = "api-version", values = "2015-11-01")
|
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface LocationApi {
|
public interface LocationApi {
|
||||||
|
|
|
@ -16,20 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import java.net.URI;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import java.util.List;
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
import java.util.Map;
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
|
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -39,15 +28,25 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
import java.net.URI;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCardProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkInterfaces")
|
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkInterfaces")
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
|
||||||
public interface NetworkInterfaceCardApi {
|
public interface NetworkInterfaceCardApi {
|
||||||
|
|
||||||
@Named("networkinterfacecard:list")
|
@Named("networkinterfacecard:list")
|
||||||
|
|
|
@ -16,40 +16,38 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
|
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups")
|
import javax.inject.Named;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
@QueryParams(keys = "api-version", values = "2016-03-30")
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
@RequestFilters(OAuthFilter.class)
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
|
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups")
|
||||||
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface NetworkSecurityGroupApi {
|
public interface NetworkSecurityGroupApi {
|
||||||
|
|
||||||
|
@ -72,9 +70,8 @@ public interface NetworkSecurityGroupApi {
|
||||||
@MapBinder(BindToJsonPayload.class)
|
@MapBinder(BindToJsonPayload.class)
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
NetworkSecurityGroup createOrUpdate(@PathParam("networksecuritygroupname") String nsgName,
|
NetworkSecurityGroup createOrUpdate(@PathParam("networksecuritygroupname") String nsgName,
|
||||||
@PayloadParam("location") String location,
|
@PayloadParam("location") String location, @Nullable @PayloadParam("tags") Map<String, String> tags,
|
||||||
@Nullable @PayloadParam("tags") Map<String, String> tags,
|
@PayloadParam("properties") NetworkSecurityGroupProperties properties);
|
||||||
@PayloadParam("properties")NetworkSecurityGroupProperties properties);
|
|
||||||
|
|
||||||
@Named("networksecuritygroup:get")
|
@Named("networksecuritygroup:get")
|
||||||
@Path("/{networksecuritygroupname}")
|
@Path("/{networksecuritygroupname}")
|
||||||
|
@ -82,4 +79,3 @@ public interface NetworkSecurityGroupApi {
|
||||||
@Fallback(NullOnNotFoundOr404.class)
|
@Fallback(NullOnNotFoundOr404.class)
|
||||||
NetworkSecurityGroup get(@PathParam("networksecuritygroupname") String nsgName);
|
NetworkSecurityGroup get(@PathParam("networksecuritygroupname") String nsgName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,38 +16,36 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
|
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
|
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import java.util.List;
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups/{networksecuritygroup}")
|
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/networkSecurityGroups/{networksecuritygroup}")
|
||||||
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@QueryParams(keys = "api-version", values = "2016-03-30")
|
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface NetworkSecurityRuleApi {
|
public interface NetworkSecurityRuleApi {
|
||||||
@Named("networksecurityrule:createOrUpdate")
|
@Named("networksecurityrule:createOrUpdate")
|
||||||
|
|
|
@ -31,17 +31,16 @@ import org.jclouds.azurecompute.arm.domain.Offer;
|
||||||
import org.jclouds.azurecompute.arm.domain.Publisher;
|
import org.jclouds.azurecompute.arm.domain.Publisher;
|
||||||
import org.jclouds.azurecompute.arm.domain.SKU;
|
import org.jclouds.azurecompute.arm.domain.SKU;
|
||||||
import org.jclouds.azurecompute.arm.domain.Version;
|
import org.jclouds.azurecompute.arm.domain.Version;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Azure Resource Management API includes operations for managing the OS images in your subscription.
|
* The Azure Resource Management API includes operations for managing the OS images in your subscription.
|
||||||
*/
|
*/
|
||||||
@Path("/providers/Microsoft.Compute/locations/{location}")
|
@Path("/providers/Microsoft.Compute/locations/{location}")
|
||||||
@RequestFilters(OAuthFilter.class)
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
|
||||||
@Consumes(APPLICATION_JSON)
|
@Consumes(APPLICATION_JSON)
|
||||||
public interface OSImageApi {
|
public interface OSImageApi {
|
||||||
|
|
||||||
|
|
|
@ -16,20 +16,8 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import java.util.List;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import java.util.Map;
|
||||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
|
||||||
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -39,14 +27,25 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.PublicIPAddressProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/publicIPAddresses")
|
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/publicIPAddresses")
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
|
||||||
public interface PublicIPAddressApi {
|
public interface PublicIPAddressApi {
|
||||||
|
|
||||||
@Named("publicipaddress:list")
|
@Named("publicipaddress:list")
|
||||||
|
|
|
@ -19,32 +19,31 @@ import java.io.Closeable;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.PUT;
|
import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.PATCH;
|
import org.jclouds.rest.annotations.PATCH;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
|
||||||
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,9 +52,7 @@ import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
* @see <a href="https://msdn.microsoft.com/en-us/library/azure/dn790546.aspx">docs</a>
|
* @see <a href="https://msdn.microsoft.com/en-us/library/azure/dn790546.aspx">docs</a>
|
||||||
*/
|
*/
|
||||||
@Path("/resourcegroups")
|
@Path("/resourcegroups")
|
||||||
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@QueryParams(keys = "api-version", values = "2015-01-01")
|
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface ResourceGroupApi extends Closeable{
|
public interface ResourceGroupApi extends Closeable{
|
||||||
|
|
||||||
|
|
|
@ -17,14 +17,8 @@
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
import java.io.Closeable;
|
||||||
import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
|
import java.util.List;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -32,8 +26,15 @@ import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.io.Closeable;
|
|
||||||
import java.util.List;
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.ResourceProviderMetaData;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Azure Resource Provider API provides information about a resource provider and its supported resource types.
|
* The Azure Resource Provider API provides information about a resource provider and its supported resource types.
|
||||||
|
@ -42,8 +43,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Path("/providers")
|
@Path("/providers")
|
||||||
|
|
||||||
@QueryParams(keys = "api-version", values = "2015-01-01")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface ResourceProviderApi extends Closeable {
|
public interface ResourceProviderApi extends Closeable {
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import org.jclouds.Fallbacks;
|
||||||
|
@ -32,35 +36,28 @@ import org.jclouds.azurecompute.arm.domain.Availability;
|
||||||
import org.jclouds.azurecompute.arm.domain.StorageService;
|
import org.jclouds.azurecompute.arm.domain.StorageService;
|
||||||
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||||
import org.jclouds.azurecompute.arm.domain.StorageServiceUpdateParams;
|
import org.jclouds.azurecompute.arm.domain.StorageServiceUpdateParams;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.Payload;
|
|
||||||
import org.jclouds.rest.annotations.PATCH;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PATCH;
|
||||||
|
import org.jclouds.rest.annotations.Payload;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.STORAGE_API_VERSION;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Azure Resource Management API includes operations for managing the storage accounts in your subscription.
|
* The Azure Resource Management API includes operations for managing the storage accounts in your subscription.
|
||||||
*
|
*
|
||||||
* @see <a href="https://msdn.microsoft.com/en-us/library/mt163683.aspx">docs</a>
|
* @see <a href="https://msdn.microsoft.com/en-us/library/mt163683.aspx">docs</a>
|
||||||
*/
|
*/
|
||||||
@Path("/")
|
@Path("/")
|
||||||
@RequestFilters(OAuthFilter.class)
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@QueryParams(keys = "api-version", values = STORAGE_API_VERSION)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface StorageAccountApi {
|
public interface StorageAccountApi {
|
||||||
|
|
||||||
|
|
|
@ -16,20 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import java.util.List;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
|
||||||
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
|
||||||
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -39,12 +26,24 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.util.List;
|
|
||||||
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/virtualNetworks/{virtualnetwork}/subnets")
|
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/virtualNetworks/{virtualnetwork}/subnets")
|
||||||
|
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface SubnetApi {
|
public interface SubnetApi {
|
||||||
|
|
||||||
|
|
|
@ -16,24 +16,24 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import java.util.List;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMSize;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.util.List;
|
|
||||||
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VMSize;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
|
||||||
@Path("/providers/Microsoft.Compute/locations/{location}/vmSizes")
|
@Path("/providers/Microsoft.Compute/locations/{location}/vmSizes")
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface VMSizeApi {
|
public interface VMSizeApi {
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,25 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DELETE;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.PUT;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.jclouds.Fallbacks;
|
import org.jclouds.Fallbacks;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
import org.jclouds.azurecompute.arm.functions.URIParser;
|
import org.jclouds.azurecompute.arm.functions.URIParser;
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
@ -32,27 +47,13 @@ import org.jclouds.rest.annotations.ResponseParser;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
import javax.inject.Named;
|
|
||||||
import javax.ws.rs.Consumes;
|
|
||||||
import javax.ws.rs.DELETE;
|
|
||||||
import javax.ws.rs.GET;
|
|
||||||
import javax.ws.rs.POST;
|
|
||||||
import javax.ws.rs.PUT;
|
|
||||||
import javax.ws.rs.Path;
|
|
||||||
import javax.ws.rs.PathParam;
|
|
||||||
import javax.ws.rs.Produces;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Virtual Machine API includes operations for managing the virtual machines in your subscription.
|
* The Virtual Machine API includes operations for managing the virtual machines in your subscription.
|
||||||
*
|
*
|
||||||
* @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt163630.aspx">docs</a>
|
* @see <a href="https://msdn.microsoft.com/en-us/library/azure/mt163630.aspx">docs</a>
|
||||||
*/
|
*/
|
||||||
@Path("/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines")
|
@Path("/resourceGroups/{resourceGroup}/providers/Microsoft.Compute/virtualMachines")
|
||||||
@RequestFilters(OAuthFilter.class)
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface VirtualMachineApi {
|
public interface VirtualMachineApi {
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ public interface VirtualMachineApi {
|
||||||
VirtualMachine get(@PathParam("name") String name);
|
VirtualMachine get(@PathParam("name") String name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Get Virtual Machine details
|
* Get information about the model view and instance view of a virtual machine:
|
||||||
*/
|
*/
|
||||||
@Named("GetVirtualMachineInstance")
|
@Named("GetVirtualMachineInstance")
|
||||||
@GET
|
@GET
|
||||||
|
|
|
@ -15,22 +15,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
import java.util.List;
|
||||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
|
||||||
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
|
||||||
|
|
||||||
import org.jclouds.rest.annotations.Fallback;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
|
||||||
import org.jclouds.rest.annotations.RequestFilters;
|
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
|
||||||
import org.jclouds.rest.annotations.ResponseParser;
|
|
||||||
import org.jclouds.rest.annotations.PayloadParam;
|
|
||||||
import org.jclouds.rest.annotations.MapBinder;
|
|
||||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
|
||||||
|
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
|
@ -40,11 +25,23 @@ import javax.ws.rs.PUT;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import java.util.List;
|
|
||||||
|
import org.jclouds.Fallbacks.EmptyListOnNotFoundOr404;
|
||||||
|
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
||||||
|
import org.jclouds.azurecompute.arm.filters.ApiVersionFilter;
|
||||||
|
import org.jclouds.azurecompute.arm.functions.FalseOn204;
|
||||||
|
import org.jclouds.oauth.v2.filters.OAuthFilter;
|
||||||
|
import org.jclouds.rest.annotations.Fallback;
|
||||||
|
import org.jclouds.rest.annotations.MapBinder;
|
||||||
|
import org.jclouds.rest.annotations.PayloadParam;
|
||||||
|
import org.jclouds.rest.annotations.RequestFilters;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||||
|
|
||||||
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/virtualNetworks")
|
@Path("/resourcegroups/{resourcegroup}/providers/Microsoft.Network/virtualNetworks")
|
||||||
@QueryParams(keys = "api-version", values = "2015-06-15")
|
@RequestFilters({ OAuthFilter.class, ApiVersionFilter.class })
|
||||||
@RequestFilters(OAuthFilter.class)
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
public interface VirtualNetworkApi {
|
public interface VirtualNetworkApi {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* 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.filters;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
|
||||||
|
import static org.jclouds.util.Maps2.transformKeys;
|
||||||
|
import static org.jclouds.util.Predicates2.startsWith;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpException;
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpRequestFilter;
|
||||||
|
import org.jclouds.rest.config.InvocationConfig;
|
||||||
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.reflect.Invokable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow users to customize the api versions for each method call.
|
||||||
|
* <p>
|
||||||
|
* In Azure ARM, each method may have its own api version. This filter allows to
|
||||||
|
* configure the versions of each method, so there is no need to change the code
|
||||||
|
* when Azure deprecates old versions.
|
||||||
|
*/
|
||||||
|
public class ApiVersionFilter implements HttpRequestFilter {
|
||||||
|
|
||||||
|
private final InvocationConfig config;
|
||||||
|
private final Map<String, String> versions;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ApiVersionFilter(InvocationConfig config, Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
|
||||||
|
this.config = config;
|
||||||
|
this.versions = versions(filterStringsBoundByName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||||
|
checkArgument(request instanceof GeneratedHttpRequest,
|
||||||
|
"This filter can only be applied to GeneratedHttpRequest objects");
|
||||||
|
GeneratedHttpRequest generatedRequest = (GeneratedHttpRequest) request;
|
||||||
|
|
||||||
|
// Look if there is a custom api version for the current method
|
||||||
|
String commandName = config.getCommandName(generatedRequest.getInvocation());
|
||||||
|
String customApiVersion = versions.get(commandName);
|
||||||
|
|
||||||
|
if (customApiVersion == null) {
|
||||||
|
// No custom config for the specific method. Let's look for custom
|
||||||
|
// config for the class
|
||||||
|
Invokable<?, ?> invoked = generatedRequest.getInvocation().getInvokable();
|
||||||
|
String className = invoked.getOwnerType().getRawType().getSimpleName();
|
||||||
|
customApiVersion = versions.get(className);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customApiVersion != null) {
|
||||||
|
return request.toBuilder().replaceQueryParam("api-version", customApiVersion).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> versions(Function<Predicate<String>, Map<String, String>> filterStringsBoundByName) {
|
||||||
|
Map<String, String> stringBoundWithApiVersionPrefix = filterStringsBoundByName
|
||||||
|
.apply(startsWith(API_VERSION_PREFIX));
|
||||||
|
return transformKeys(stringBoundWithApiVersionPrefix, new Function<String, String>() {
|
||||||
|
public String apply(String input) {
|
||||||
|
return input.replaceFirst(API_VERSION_PREFIX, "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,125 +16,161 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.functions;
|
package org.jclouds.azurecompute.arm.functions;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.base.Predicates.notNull;
|
||||||
|
import static com.google.common.collect.Iterables.filter;
|
||||||
|
import static com.google.common.collect.Iterables.transform;
|
||||||
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
|
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||||
import org.jclouds.azurecompute.arm.domain.Deployment;
|
import org.jclouds.azurecompute.arm.domain.IpConfiguration;
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
|
import org.jclouds.azurecompute.arm.domain.ResourceGroup;
|
||||||
import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
|
import org.jclouds.azurecompute.arm.domain.StorageServiceKeys;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
|
import org.jclouds.azurecompute.arm.util.BlobHelper;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import java.net.URI;
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CleanupResources implements Function<String, Boolean> {
|
public class CleanupResources implements Function<String, Boolean> {
|
||||||
|
|
||||||
private final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
|
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
|
|
||||||
protected final AzureComputeApi api;
|
protected final AzureComputeApi api;
|
||||||
private Predicate<URI> nodeTerminated;
|
private final Predicate<URI> resourceDeleted;
|
||||||
private Predicate<URI> resourceDeleted;
|
private final StorageProfileToStorageAccountName storageProfileToStorageAccountName;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CleanupResources(AzureComputeApi azureComputeApi,
|
CleanupResources(AzureComputeApi azureComputeApi, @Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted,
|
||||||
AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants,
|
StorageProfileToStorageAccountName storageProfileToStorageAccountName) {
|
||||||
@Named(TIMEOUT_NODE_TERMINATED) Predicate<URI> nodeTerminated,
|
|
||||||
@Named(TIMEOUT_RESOURCE_DELETED) Predicate<URI> resourceDeleted) {
|
|
||||||
this.azureComputeConstants = azureComputeConstants;
|
|
||||||
this.api = azureComputeApi;
|
this.api = azureComputeApi;
|
||||||
this.nodeTerminated = nodeTerminated;
|
|
||||||
this.resourceDeleted = resourceDeleted;
|
this.resourceDeleted = resourceDeleted;
|
||||||
|
this.storageProfileToStorageAccountName = storageProfileToStorageAccountName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean apply(String id) {
|
public Boolean apply(final String id) {
|
||||||
|
logger.debug(">> destroying %s ...", id);
|
||||||
|
|
||||||
logger.debug("Destroying %s ...", id);
|
Map<String, VirtualMachine> resourceGroupNamesAndVirtualMachines = getResourceGroupNamesAndVirtualMachines(id);
|
||||||
String storageAccountName = id.replaceAll("[^A-Za-z0-9 ]", "") + "stor";
|
if (resourceGroupNamesAndVirtualMachines.isEmpty())
|
||||||
String group = azureComputeConstants.azureResourceGroup();
|
return true;
|
||||||
|
|
||||||
VirtualMachine vm = api.getVirtualMachineApi(group).get(id);
|
String group = checkNotNull(resourceGroupNamesAndVirtualMachines.entrySet().iterator().next().getKey(),
|
||||||
if (vm != null) {
|
"resourceGroup name must not be null");
|
||||||
URI uri = api.getVirtualMachineApi(group).delete(id);
|
VirtualMachine virtualMachine = checkNotNull(resourceGroupNamesAndVirtualMachines.get(group),
|
||||||
if (uri != null) {
|
"virtualMachine must not be null");
|
||||||
boolean jobDone = nodeTerminated.apply(uri);
|
|
||||||
boolean storageAcctDeleteStatus = false;
|
|
||||||
boolean deploymentDeleteStatus = false;
|
|
||||||
|
|
||||||
if (jobDone) {
|
boolean vmDeleted = deleteVirtualMachine(group, virtualMachine);
|
||||||
Deployment deployment = api.getDeploymentApi(group).get(id);
|
|
||||||
if (deployment != null) {
|
// We don't delete the network here, as it is global to the resource
|
||||||
uri = api.getDeploymentApi(group).delete(id);
|
// group. It will be deleted when the resource group is deleted
|
||||||
jobDone = resourceDeleted.apply(uri);
|
|
||||||
if (jobDone) {
|
for (String nicName : getNetworkCardInterfaceNames(virtualMachine)) {
|
||||||
deploymentDeleteStatus = true;
|
NetworkInterfaceCard nic = api.getNetworkInterfaceCardApi(group).get(nicName);
|
||||||
|
Iterable<String> publicIps = getPublicIps(group, nic);
|
||||||
|
|
||||||
|
logger.debug(">> destroying nic %s...", nicName);
|
||||||
|
URI nicDeletionURI = api.getNetworkInterfaceCardApi(group).delete(nicName);
|
||||||
|
resourceDeleted.apply(nicDeletionURI);
|
||||||
|
|
||||||
|
for (String publicIp : publicIps) {
|
||||||
|
logger.debug(">> deleting public ip nic %s...", publicIp);
|
||||||
|
api.getPublicIPAddressApi(group).delete(publicIp);
|
||||||
}
|
}
|
||||||
} 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
|
String storageAccountName = storageProfileToStorageAccountName.apply(virtualMachine.properties().storageProfile());
|
||||||
boolean nsgDeleteStatus = false;
|
StorageServiceKeys keys = api.getStorageAccountApi(group).getKeys(storageAccountName);
|
||||||
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;
|
|
||||||
|
|
||||||
|
// Remove the virtual machine files
|
||||||
|
logger.debug(">> deleting virtual machine disk storage...");
|
||||||
|
BlobHelper blobHelper = new BlobHelper(storageAccountName, keys.key1());
|
||||||
|
try {
|
||||||
|
blobHelper.deleteContainerIfExists("vhds");
|
||||||
|
|
||||||
|
if (!blobHelper.customImageExists()) {
|
||||||
|
logger.debug(">> deleting storage account %s...", storageAccountName);
|
||||||
|
api.getStorageAccountApi(group).delete(storageAccountName);
|
||||||
|
} else {
|
||||||
|
logger.debug(">> the storage account contains custom images. Will not delete it!");
|
||||||
}
|
}
|
||||||
}
|
} finally {
|
||||||
else {
|
closeQuietly(blobHelper);
|
||||||
nsgDeleteStatus = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return deploymentDeleteStatus && storageAcctDeleteStatus && ipDeleteStatus && nsgDeleteStatus;
|
deleteResourceGroupIfEmpty(group);
|
||||||
} else {
|
|
||||||
return false;
|
return vmDeleted;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return false;
|
public void deleteResourceGroupIfEmpty(String group) {
|
||||||
|
if (api.getVirtualMachineApi(group).list().isEmpty()
|
||||||
|
&& api.getStorageAccountApi(group).list().isEmpty()
|
||||||
|
&& api.getNetworkInterfaceCardApi(group).list().isEmpty()
|
||||||
|
&& api.getPublicIPAddressApi(group).list().isEmpty()) {
|
||||||
|
logger.debug(">> the resource group %s is empty. Deleting...", group);
|
||||||
|
resourceDeleted.apply(api.getResourceGroupApi().delete(group));
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return false;
|
private Iterable<String> getPublicIps(String group, NetworkInterfaceCard nic) {
|
||||||
|
return transform(
|
||||||
|
filter(transform(nic.properties().ipConfigurations(), new Function<IpConfiguration, IdReference>() {
|
||||||
|
@Override
|
||||||
|
public IdReference apply(IpConfiguration input) {
|
||||||
|
return input.properties().publicIPAddress();
|
||||||
}
|
}
|
||||||
} else {
|
}), notNull()), new Function<IdReference, String>() {
|
||||||
return false;
|
@Override
|
||||||
|
public String apply(IdReference input) {
|
||||||
|
return Iterables.getLast(Splitter.on("/").split(input.id()));
|
||||||
}
|
}
|
||||||
} else {
|
});
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> getNetworkCardInterfaceNames(VirtualMachine virtualMachine) {
|
||||||
|
List<String> nics = Lists.newArrayList();
|
||||||
|
for (IdReference idReference : virtualMachine.properties().networkProfile().networkInterfaces()) {
|
||||||
|
nics.add(Iterables.getLast(Splitter.on("/").split(idReference.id())));
|
||||||
|
}
|
||||||
|
return nics;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean deleteVirtualMachine(String group, VirtualMachine virtualMachine) {
|
||||||
|
return resourceDeleted.apply(api.getVirtualMachineApi(group).delete(virtualMachine.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, VirtualMachine> getResourceGroupNamesAndVirtualMachines(String id) {
|
||||||
|
for (ResourceGroup resourceGroup : api.getResourceGroupApi().list()) {
|
||||||
|
String group = resourceGroup.name();
|
||||||
|
VirtualMachine virtualMachine = api.getVirtualMachineApi(group).get(id);
|
||||||
|
if (virtualMachine != null) {
|
||||||
|
return ImmutableMap.of(group, virtualMachine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Maps.newHashMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 java.net.URI;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the storage account name for a given storage profile.
|
||||||
|
*/
|
||||||
|
public class StorageProfileToStorageAccountName implements Function<StorageProfile, String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apply(StorageProfile input) {
|
||||||
|
String storageAccountNameURI = input.osDisk().vhd().uri();
|
||||||
|
return Iterables.get(Splitter.on(".").split(URI.create(storageAccountNameURI).getHost()), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,76 +16,68 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.util;
|
package org.jclouds.azurecompute.arm.util;
|
||||||
|
|
||||||
|
import static org.jclouds.util.Closeables2.closeQuietly;
|
||||||
|
|
||||||
|
import java.io.Closeable;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.ContextBuilder;
|
import org.jclouds.ContextBuilder;
|
||||||
import org.jclouds.azure.storage.domain.BoundedSet;
|
|
||||||
import org.jclouds.azureblob.AzureBlobClient;
|
import org.jclouds.azureblob.AzureBlobClient;
|
||||||
import org.jclouds.azureblob.domain.BlobProperties;
|
import org.jclouds.azureblob.domain.BlobProperties;
|
||||||
import org.jclouds.azureblob.domain.ContainerProperties;
|
import org.jclouds.azureblob.domain.ContainerProperties;
|
||||||
import org.jclouds.azureblob.domain.ListBlobsResponse;
|
import org.jclouds.azureblob.domain.ListBlobsResponse;
|
||||||
import org.jclouds.azurecompute.arm.domain.VMImage;
|
import org.jclouds.azurecompute.arm.domain.VMImage;
|
||||||
import org.jclouds.util.Closeables2;
|
|
||||||
|
|
||||||
public class BlobHelper {
|
public class BlobHelper implements Closeable {
|
||||||
|
|
||||||
public static void deleteContainerIfExists(String storage, String key, String containerName) {
|
private final String storageAccount;
|
||||||
final AzureBlobClient azureBlob = ContextBuilder.newBuilder("azureblob")
|
private final AzureBlobClient azureBlob;
|
||||||
.credentials(storage, key)
|
|
||||||
|
public BlobHelper(String storageAccount, String key) {
|
||||||
|
this.storageAccount = storageAccount;
|
||||||
|
this.azureBlob = ContextBuilder.newBuilder("azureblob").credentials(storageAccount, key)
|
||||||
.buildApi(AzureBlobClient.class);
|
.buildApi(AzureBlobClient.class);
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
@Override
|
||||||
|
public void close() throws IOException {
|
||||||
|
closeQuietly(azureBlob);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteContainerIfExists(String containerName) {
|
||||||
azureBlob.deleteContainer(containerName);
|
azureBlob.deleteContainer(containerName);
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
Closeables2.closeQuietly(azureBlob);
|
public boolean hasContainers() {
|
||||||
}
|
return !azureBlob.listContainers().isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean customImageExists(String storage, String key) {
|
public boolean customImageExists() {
|
||||||
final AzureBlobClient azureBlob = ContextBuilder.newBuilder("azureblob")
|
|
||||||
.credentials(storage, key)
|
|
||||||
.buildApi(AzureBlobClient.class);
|
|
||||||
|
|
||||||
try {
|
|
||||||
return azureBlob.containerExists("system");
|
return azureBlob.containerExists("system");
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
Closeables2.closeQuietly(azureBlob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<VMImage> getImages(String containerName, String group,
|
|
||||||
String storageAccountName, String key, String offer, String location) {
|
|
||||||
final AzureBlobClient azureBlob = ContextBuilder.newBuilder("azureblob")
|
|
||||||
.credentials(storageAccountName, key)
|
|
||||||
.buildApi(AzureBlobClient.class);
|
|
||||||
|
|
||||||
|
|
||||||
|
public List<VMImage> getImages(String containerName, String group, String offer, String location) {
|
||||||
List<VMImage> list = new ArrayList<VMImage>();
|
List<VMImage> list = new ArrayList<VMImage>();
|
||||||
try {
|
|
||||||
BoundedSet<ContainerProperties> containerList = azureBlob.listContainers();
|
|
||||||
for (ContainerProperties props : containerList) {
|
|
||||||
if (props.getName().equals("system")) {
|
|
||||||
ListBlobsResponse blobList = azureBlob.listBlobs("system");
|
|
||||||
String osDisk = "";
|
|
||||||
String dataDisk = "";
|
|
||||||
|
|
||||||
|
ContainerProperties systemContainer = azureBlob.getContainerProperties("system");
|
||||||
|
if (systemContainer != null) {
|
||||||
|
ListBlobsResponse blobList = azureBlob.listBlobs(systemContainer.getName());
|
||||||
for (BlobProperties blob : blobList) {
|
for (BlobProperties blob : blobList) {
|
||||||
String name = blob.getName();
|
String name = blob.getName();
|
||||||
|
|
||||||
if (dataDisk.length() == 0) dataDisk = name.substring(1 + name.lastIndexOf('/'));
|
if (name.contains("-osDisk")) {
|
||||||
else if (osDisk.length() == 0) osDisk = name.substring(1 + name.lastIndexOf('/'));
|
String imageName = name.substring(name.lastIndexOf('/') + 1, name.indexOf("-osDisk"));
|
||||||
}
|
String imageUrl = blob.getUrl().toString();
|
||||||
final VMImage ref = VMImage.create(group, storageAccountName, osDisk, dataDisk, "test-create-image", "custom", location);
|
|
||||||
list.add(ref);
|
list.add(VMImage.customImage().group(group).storage(storageAccount).vhd1(imageUrl).name(imageName)
|
||||||
|
.offer(offer).location(location).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
Closeables2.closeQuietly(azureBlob);
|
|
||||||
}
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,573 +0,0 @@
|
||||||
/*
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
||||||
* (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.azurecompute.arm.util;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
|
|
||||||
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.NetworkSecurityGroupProperties;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkSecurityRuleProperties;
|
|
||||||
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.TemplateParameterType;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VHD;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
|
||||||
import org.jclouds.json.Json;
|
|
||||||
import org.jclouds.predicates.Validator;
|
|
||||||
import org.jclouds.predicates.validators.DnsNameValidator;
|
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.inject.Inject;
|
|
||||||
import com.google.inject.assistedinject.Assisted;
|
|
||||||
|
|
||||||
import static com.google.common.io.BaseEncoding.base64;
|
|
||||||
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 {
|
|
||||||
public interface Factory {
|
|
||||||
DeploymentTemplateBuilder create(@Assisted("group") String group, @Assisted("name") String name, Template template);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final String azureGroup;
|
|
||||||
private final String group;
|
|
||||||
private final Template template;
|
|
||||||
private final Json json;
|
|
||||||
|
|
||||||
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;
|
|
||||||
private static String loginPassword;
|
|
||||||
private String location;
|
|
||||||
private AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants;
|
|
||||||
|
|
||||||
private static final String DEPLOYMENT_MODE = "Incremental";
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
DeploymentTemplateBuilder(Json json, @Assisted("group") String group, @Assisted("name") String name, @Assisted Template template,
|
|
||||||
final AzureComputeServiceContextModule.AzureComputeConstants azureComputeConstants) {
|
|
||||||
this.name = name;
|
|
||||||
this.group = group;
|
|
||||||
this.template = template;
|
|
||||||
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;
|
|
||||||
String defaultPassword = null;
|
|
||||||
|
|
||||||
if (defaultLogin.length == 2) {
|
|
||||||
defaultUser = defaultLogin[0].trim();
|
|
||||||
defaultPassword = defaultLogin[1].trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
loginUser = options.getLoginUser() == null ? defaultUser : options.getLoginUser();
|
|
||||||
loginPassword = options.getLoginPassword() == null ? defaultPassword : options.getLoginPassword();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getLoginUserUsername() {
|
|
||||||
return loginUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getLoginPassword() {
|
|
||||||
return loginPassword;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Template getTemplate() {
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DeploymentBody getDeploymentTemplate() {
|
|
||||||
|
|
||||||
addStorageResource();
|
|
||||||
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(templateParameters)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
DeploymentBody body = DeploymentBody.create(template, DEPLOYMENT_MODE, parameters);
|
|
||||||
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDeploymentTemplateJson(DeploymentProperties properties) {
|
|
||||||
return json.toJson(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addStorageResource() {
|
|
||||||
String storageAccountName = null;
|
|
||||||
|
|
||||||
String imageName = template.getImage().getName();
|
|
||||||
if (imageName.startsWith(CUSTOM_IMAGE_PREFIX)) {
|
|
||||||
storageAccountName = template.getImage().getVersion();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Strings.isNullOrEmpty(storageAccountName)) {
|
|
||||||
storageAccountName = generateStorageAccountName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Validator<String> validator = new DnsNameValidator(3, 24);
|
|
||||||
validator.validate(storageAccountName);
|
|
||||||
|
|
||||||
variables.put("storageAccountName", storageAccountName);
|
|
||||||
|
|
||||||
ResourceDefinition storageAccount = ResourceDefinition.builder()
|
|
||||||
.name("[variables('storageAccountName')]")
|
|
||||||
.type("Microsoft.Storage/storageAccounts")
|
|
||||||
.location(location)
|
|
||||||
.apiVersion(STORAGE_API_VERSION)
|
|
||||||
.properties(
|
|
||||||
StorageServiceProperties.builder()
|
|
||||||
.accountType(StorageService.AccountType.Standard_LRS)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
resources.add(storageAccount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addPublicIpAddress() {
|
|
||||||
String publicIPAddressName = name + "publicip";
|
|
||||||
String dnsLabelPrefix = options.getDNSLabelPrefix();
|
|
||||||
|
|
||||||
PublicIPAddressProperties.Builder properties = PublicIPAddressProperties.builder();
|
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(dnsLabelPrefix)) {
|
|
||||||
properties.dnsSettings(DnsSettings.builder().domainNameLabel(dnsLabelPrefix).build());
|
|
||||||
variables.put("dnsLabelPrefix", dnsLabelPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
properties.publicIPAllocationMethod("Dynamic");
|
|
||||||
variables.put("publicIPAddressName", publicIPAddressName);
|
|
||||||
variables.put("publicIPAddressReference", "[resourceId('Microsoft.Network/publicIPAddresses',variables('publicIPAddressName'))]");
|
|
||||||
|
|
||||||
ResourceDefinition publicIpAddress = ResourceDefinition.builder()
|
|
||||||
.name("[variables('publicIPAddressName')]")
|
|
||||||
.type("Microsoft.Network/publicIPAddresses")
|
|
||||||
.location(location)
|
|
||||||
.apiVersion(STORAGE_API_VERSION)
|
|
||||||
.properties(properties.build())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
resources.add(publicIpAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addNetworkInterfaceCard() {
|
|
||||||
|
|
||||||
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()
|
|
||||||
.privateIPAllocationMethod("Dynamic")
|
|
||||||
.publicIPAddress(IdReference.create("[variables('publicIPAddressReference')]"))
|
|
||||||
.subnet(IdReference.create("[variables('subnetReference')]"))
|
|
||||||
.build());
|
|
||||||
|
|
||||||
ipConfigurations.add(ipConfig);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
variables.put("networkInterfaceCardReference", "[resourceId('Microsoft.Network/networkInterfaces',variables('networkInterfaceCardName'))]");
|
|
||||||
|
|
||||||
ResourceDefinition networkInterfaceCard = ResourceDefinition.builder()
|
|
||||||
.name("[variables('networkInterfaceCardName')]")
|
|
||||||
.type("Microsoft.Network/networkInterfaces")
|
|
||||||
.location(location)
|
|
||||||
.apiVersion(STORAGE_API_VERSION)
|
|
||||||
.dependsOn(depends)
|
|
||||||
.properties(networkInterfaceCardProperties)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
resources.add(networkInterfaceCard);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addNetworkSecurityGroup() {
|
|
||||||
int inboundPorts[] = options.getInboundPorts();
|
|
||||||
if ((inboundPorts != null) && (inboundPorts.length > 0)) {
|
|
||||||
variables.put("networkSecurityGroupName", name + "nsg");
|
|
||||||
variables.put("networkSecurityGroupNameReference", "[resourceId('Microsoft.Network/networkSecurityGroups',variables('networkSecurityGroupName'))]");
|
|
||||||
|
|
||||||
List<String> portRanges = simplifyPorts(inboundPorts);
|
|
||||||
|
|
||||||
List<NetworkSecurityRule> rules = new ArrayList<NetworkSecurityRule>();
|
|
||||||
int priority = 1234;
|
|
||||||
for (String portRange : portRanges) {
|
|
||||||
NetworkSecurityRuleProperties ruleProperties = NetworkSecurityRuleProperties.builder()
|
|
||||||
.description("default-allow-port-" + portRange)
|
|
||||||
.protocol(NetworkSecurityRuleProperties.Protocol.All)
|
|
||||||
.access(NetworkSecurityRuleProperties.Access.Allow)
|
|
||||||
.sourcePortRange("*")
|
|
||||||
.destinationPortRange(portRange)
|
|
||||||
.sourceAddressPrefix("*")
|
|
||||||
.destinationAddressPrefix("*")
|
|
||||||
.priority(priority)
|
|
||||||
.direction(NetworkSecurityRuleProperties.Direction.Inbound)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
NetworkSecurityRule networkSecurityRule = NetworkSecurityRule.create(
|
|
||||||
"default-allow-port-" + portRange,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
ruleProperties);
|
|
||||||
|
|
||||||
rules.add(networkSecurityRule);
|
|
||||||
priority++;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function for simplifying an array of ports to a list of ranges as list of strings
|
|
||||||
* @param ports array of int
|
|
||||||
* @return list of strings representing ranges
|
|
||||||
*/
|
|
||||||
public static List<String> simplifyPorts(int[] ports) {
|
|
||||||
Preconditions.checkArgument(ports != null && ports.length != 0);
|
|
||||||
ArrayList<String> output = new ArrayList<String>();
|
|
||||||
Arrays.sort(ports);
|
|
||||||
|
|
||||||
int range_start = ports[0];
|
|
||||||
int range_end = ports[0];
|
|
||||||
for (int i = 1; i < ports.length; i++) {
|
|
||||||
if ((ports[i - 1] == ports[i] - 1) || (ports[i - 1] == ports[i])){
|
|
||||||
// Range continues.
|
|
||||||
range_end = ports[i];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Range ends.
|
|
||||||
output.add(formatRange(range_start, range_end));
|
|
||||||
range_start = ports[i];
|
|
||||||
range_end = ports[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Make sure we get the last range.
|
|
||||||
output.add(formatRange(range_start, range_end));
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String formatRange(int start, int finish) {
|
|
||||||
if (start == finish){
|
|
||||||
return Integer.toString(start);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return String.format("%s-%s", Integer.toString(start), Integer.toString(finish));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addVirtualMachine() {
|
|
||||||
//Build OS Profile
|
|
||||||
final String computerName = name + "pc";
|
|
||||||
|
|
||||||
variables.put("loginUser", loginUser);
|
|
||||||
OSProfile.Builder profileBuilder = OSProfile.builder()
|
|
||||||
.adminUsername(loginUser)
|
|
||||||
.computerName(computerName);
|
|
||||||
|
|
||||||
profileBuilder.adminPassword(loginPassword);
|
|
||||||
//boolean usePublicKey = options.getPublicKey() != null;
|
|
||||||
|
|
||||||
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')]",
|
|
||||||
"[parameters('publicKeyFromAzureKeyVault')]"
|
|
||||||
))
|
|
||||||
));
|
|
||||||
profileBuilder.linuxConfiguration(configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Strings.isNullOrEmpty(options.getCustomData())){
|
|
||||||
String encodedCustomData = base64().encode(options.getCustomData().getBytes());
|
|
||||||
profileBuilder.customData(encodedCustomData);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSProfile osProfile = profileBuilder.build();
|
|
||||||
|
|
||||||
//Build OsDisk
|
|
||||||
final String storageAccountContainerName = name + "vhds";
|
|
||||||
variables.put("storageAccountContainerName", storageAccountContainerName);
|
|
||||||
|
|
||||||
final String osDiskName = name + "osdisk";
|
|
||||||
variables.put("osDiskName", osDiskName);
|
|
||||||
|
|
||||||
boolean usingMarketplaceImage = true;
|
|
||||||
String cusotomImageUri = "";
|
|
||||||
|
|
||||||
// Handle custom image case if description starts with CUSTOM_IMAGE_PREFIX
|
|
||||||
String vhd1 = template.getImage().getProviderId();
|
|
||||||
String description = template.getImage().getDescription();
|
|
||||||
if (description.substring(0, CUSTOM_IMAGE_PREFIX.length()).equals(CUSTOM_IMAGE_PREFIX)) {
|
|
||||||
String storageName = template.getImage().getVersion();
|
|
||||||
cusotomImageUri = vhd1;
|
|
||||||
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";
|
|
||||||
variables.put("dataDiskName", dataDiskName);
|
|
||||||
|
|
||||||
List<DataDisk> dataDisks = new ArrayList<DataDisk>();
|
|
||||||
DataDisk dataDisk = DataDisk.builder()
|
|
||||||
.name("[variables('dataDiskName')]")
|
|
||||||
.diskSizeGB(azureComputeConstants.azureDefaultDataDiskSizeProperty())
|
|
||||||
.lun(0)
|
|
||||||
.vhd(
|
|
||||||
VHD.create("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net/',variables('storageAccountContainerName'),'/',variables('dataDiskName'),'.vhd')]")
|
|
||||||
)
|
|
||||||
.createOption("Empty")
|
|
||||||
.build();
|
|
||||||
|
|
||||||
dataDisks.add(dataDisk);
|
|
||||||
|
|
||||||
//Create Storage Profile
|
|
||||||
StorageProfile.Builder storageProfileBuilder = StorageProfile.builder()
|
|
||||||
.osDisk(osDisk)
|
|
||||||
.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(
|
|
||||||
Arrays.asList(
|
|
||||||
IdReference.create("[variables('networkInterfaceCardReference')]")
|
|
||||||
));
|
|
||||||
|
|
||||||
//Boot Diagnostics
|
|
||||||
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(
|
|
||||||
DiagnosticsProfile.BootDiagnostics.builder()
|
|
||||||
.enabled(true)
|
|
||||||
.storageUri("[concat('http://',variables('storageAccountName'),'.blob.core.windows.net')]")
|
|
||||||
.build());
|
|
||||||
|
|
||||||
//Build VirtualMachine properties based on above properties.
|
|
||||||
final String vmSize = template.getHardware().getId();
|
|
||||||
HardwareProfile hw = HardwareProfile.create(vmSize);
|
|
||||||
|
|
||||||
VirtualMachineProperties properties = VirtualMachineProperties.builder()
|
|
||||||
.hardwareProfile(hw)
|
|
||||||
.osProfile(osProfile)
|
|
||||||
.storageProfile(storageProfile)
|
|
||||||
.networkProfile(networkProfile)
|
|
||||||
.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("2015-06-15")
|
|
||||||
.dependsOn(Arrays.asList("[concat('Microsoft.Storage/storageAccounts/', variables('storageAccountName'))]",
|
|
||||||
"[concat('Microsoft.Network/networkInterfaces/', variables('networkInterfaceCardName'))]"))
|
|
||||||
.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());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a valid storage account
|
|
||||||
*
|
|
||||||
* Storage account names must be between 3 and 24 characters in length and may contain numbers and lowercase letters only.
|
|
||||||
*
|
|
||||||
* @param name the node name
|
|
||||||
* @return the storage account name starting from a sanitized name (with only numbers and lowercase letters only ).
|
|
||||||
* If sanitized name is between 3 and 24 characters, storage account name is equals to sanitized name.
|
|
||||||
* If sanitized name is less than 3 characters, storage account is sanitized name plus 4 random chars.
|
|
||||||
* If sanitized name is more than 24 characters, storage account is first 10 chars of sanitized name plus 4 random chars plus last 10 chars of sanitized name.
|
|
||||||
*/
|
|
||||||
private static String generateStorageAccountName(String name) {
|
|
||||||
String storageAccountName = name.replaceAll("[^a-z0-9]", "");
|
|
||||||
int nameLength = storageAccountName.length();
|
|
||||||
if (nameLength >= 3 && nameLength <= 24) {
|
|
||||||
return storageAccountName;
|
|
||||||
}
|
|
||||||
|
|
||||||
String random = UUID.randomUUID().toString().replaceAll("[^a-z0-9]", "").substring(0, 4);
|
|
||||||
if (nameLength < 3) {
|
|
||||||
storageAccountName = new StringBuilder().append(storageAccountName).append(random).toString();
|
|
||||||
}
|
|
||||||
if (nameLength > 24) {
|
|
||||||
storageAccountName = shorten(storageAccountName, random);
|
|
||||||
}
|
|
||||||
return storageAccountName;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String shorten(String storageAccountName, String random) {
|
|
||||||
String prefix = storageAccountName.substring(0, 10);
|
|
||||||
String suffix = storageAccountName.substring(storageAccountName.length() - 10, storageAccountName.length());
|
|
||||||
return String.format("%s%s%s", prefix, random, suffix);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,7 +20,6 @@ import java.util.EnumSet;
|
||||||
|
|
||||||
public class GetEnumValue {
|
public class GetEnumValue {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T extends Enum<T>> Enum<T> fromValueOrDefault(String text, Enum<T> defaultValue) {
|
public static <T extends Enum<T>> Enum<T> fromValueOrDefault(String text, Enum<T> defaultValue) {
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
EnumSet<T> elements = EnumSet.allOf(defaultValue.getDeclaringClass());
|
EnumSet<T> elements = EnumSet.allOf(defaultValue.getDeclaringClass());
|
||||||
|
|
|
@ -16,21 +16,26 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute;
|
package org.jclouds.azurecompute.arm.compute;
|
||||||
|
|
||||||
import java.util.Map;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
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.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 static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||||
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||||
import org.jclouds.compute.RunScriptOnNodesException;
|
|
||||||
import org.jclouds.compute.domain.ExecResponse;
|
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
|
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
|
||||||
import org.jclouds.compute.predicates.NodePredicates;
|
|
||||||
import org.jclouds.domain.LoginCredentials;
|
|
||||||
import org.jclouds.logging.config.LoggingModule;
|
import org.jclouds.logging.config.LoggingModule;
|
||||||
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
import org.jclouds.logging.slf4j.config.SLF4JLoggingModule;
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
|
@ -41,29 +46,18 @@ import org.jclouds.scriptbuilder.statements.login.AdminAccess;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
||||||
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.compute.config.ComputeServiceProperties.TEMPLATE;
|
|
||||||
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.ComputeService} integration.
|
* Live tests for the {@link org.jclouds.compute.ComputeService} integration.
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", singleThreaded = true, testName = "AzureComputeServiceLiveTest")
|
@Test(groups = "live", singleThreaded = true, testName = "AzureComputeServiceLiveTest")
|
||||||
public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
protected int nonBlockDurationSeconds = 30;
|
|
||||||
|
|
||||||
public AzureComputeServiceLiveTest() {
|
public AzureComputeServiceLiveTest() {
|
||||||
provider = "azurecompute-arm";
|
provider = "azurecompute-arm";
|
||||||
nonBlockDurationSeconds = 300;
|
|
||||||
group = "az-u";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,21 +72,20 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ProviderMetadata createProviderMetadata() {
|
protected ProviderMetadata createProviderMetadata() {
|
||||||
AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
|
return AzureComputeProviderMetadata.builder().build();
|
||||||
return pm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
Properties properties = super.setupProperties();
|
Properties properties = super.setupProperties();
|
||||||
long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES);
|
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
|
||||||
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_PORT_OPEN, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_NODE_TERMINATED, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_NODE_SUSPENDED, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
|
||||||
properties.put(RESOURCE_GROUP_NAME, "a4");
|
properties.put(RESOURCE_GROUP_NAME, "jc");
|
||||||
properties.put(TEMPLATE, "locationId=westeurope");
|
properties.put(PROPERTY_REGIONS, "eastus");
|
||||||
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||||
|
|
||||||
AzureLiveTestUtils.defaultProperties(properties);
|
AzureLiveTestUtils.defaultProperties(properties);
|
||||||
|
@ -102,24 +95,27 @@ public class AzureComputeServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Template refreshTemplate() {
|
protected TemplateBuilder templateBuilder() {
|
||||||
return this.template = addRunScriptToTemplate(this.buildTemplate(this.client.templateBuilder()));
|
return super.templateBuilder().options(
|
||||||
|
authorizePublicKey(keyPair.get("public")).overrideLoginPrivateKey(keyPair.get("private")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Template addRunScriptToTemplate(Template template) {
|
protected Template addRunScriptToTemplate(Template template) {
|
||||||
template.getOptions().runScript(Statements.newStatementList(new Statement[]{AdminAccess.standard(), Statements.exec("sleep 50"), InstallJDK.fromOpenJDK()}));
|
template.getOptions().runScript(
|
||||||
|
Statements.newStatementList(new Statement[] { AdminAccess.standard(), Statements.exec("sleep 50"),
|
||||||
|
InstallJDK.fromOpenJDK() }));
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Test( enabled = false)
|
protected void checkUserMetadataContains(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||||
protected void weCanCancelTasks(NodeMetadata node) throws InterruptedException, ExecutionException {
|
// User metadata not yet supported
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(String group, OperatingSystem os, LoginCredentials creds) throws RunScriptOnNodesException {
|
protected void checkTagsInNodeEquals(NodeMetadata node, ImmutableSet<String> tags) {
|
||||||
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"));
|
// Tags not yet supported
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,33 +16,30 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute;
|
package org.jclouds.azurecompute.arm.compute;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.RESOURCE_GROUP_NAME;
|
||||||
|
import static org.jclouds.compute.util.ComputeServiceUtils.getCores;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.Region;
|
||||||
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||||
|
import org.jclouds.compute.domain.OsFamily;
|
||||||
|
import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest;
|
import org.jclouds.compute.internal.BaseTemplateBuilderLiveTest;
|
||||||
import org.jclouds.providers.ProviderMetadata;
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
|
|
||||||
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_SCRIPT_COMPLETE;
|
|
||||||
|
|
||||||
@Test(groups = "live", testName = "AzureTemplateBuilderLiveTest")
|
@Test(groups = "live", testName = "AzureTemplateBuilderLiveTest")
|
||||||
public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
public String azureGroup;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Set<String> getIso3166Codes() {
|
|
||||||
return ImmutableSet.of("US-IA", "US-VA", "US-IL", "US-TX", "US-CA", "IE", "NL", "HK", "SG", "JP-11", "JP-27", "BR", "AU-NSW", "AU-VIC", "IN-GA", "IN-TN", "IN-MH", "CN-SH", "CN-BJ", "CA-ON", "CA-QC");
|
|
||||||
}
|
|
||||||
|
|
||||||
public AzureTemplateBuilderLiveTest() {
|
public AzureTemplateBuilderLiveTest() {
|
||||||
provider = "azurecompute-arm";
|
provider = "azurecompute-arm";
|
||||||
|
@ -55,23 +52,33 @@ public class AzureTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ProviderMetadata createProviderMetadata() {
|
protected ProviderMetadata createProviderMetadata() {
|
||||||
AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
|
return AzureComputeProviderMetadata.builder().build();
|
||||||
return pm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
azureGroup = "jc" + System.getProperty("user.name").substring(0, 3);
|
|
||||||
Properties properties = super.setupProperties();
|
Properties properties = super.setupProperties();
|
||||||
long scriptTimeout = TimeUnit.MILLISECONDS.convert(20, TimeUnit.MINUTES);
|
properties.put(RESOURCE_GROUP_NAME, "jc");
|
||||||
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
|
|
||||||
properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + "");
|
|
||||||
properties.put(RESOURCE_GROUP_NAME, azureGroup);
|
|
||||||
|
|
||||||
AzureLiveTestUtils.defaultProperties(properties);
|
AzureLiveTestUtils.defaultProperties(properties);
|
||||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Test
|
||||||
|
public void testDefaultTemplateBuilder() throws IOException {
|
||||||
|
Template defaultTemplate = view.getComputeService().templateBuilder().build();
|
||||||
|
assertTrue(defaultTemplate.getImage().getOperatingSystem().getVersion().matches("1[45]\\.[01][04]\\.[0-9]-LTS"),
|
||||||
|
"Version mismatch, expected dd.dd.d-LTS, found: " + defaultTemplate.getImage().getOperatingSystem().getVersion());
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||||
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||||
|
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Set<String> getIso3166Codes() {
|
||||||
|
return Region.iso3166Codes();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,29 +16,35 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.compute.extensions;
|
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 com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
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.RESOURCE_GROUP_NAME;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
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_SUSPENDED;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
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_PORT_OPEN;
|
||||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
|
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_SCRIPT_COMPLETE;
|
||||||
|
import static org.jclouds.compute.options.TemplateOptions.Builder.authorizePublicKey;
|
||||||
|
import static org.jclouds.location.reference.LocationConstants.PROPERTY_REGIONS;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||||
|
import org.jclouds.azurecompute.arm.internal.AzureLiveTestUtils;
|
||||||
|
import org.jclouds.compute.ComputeTestUtils;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
|
import org.jclouds.compute.extensions.internal.BaseImageExtensionLiveTest;
|
||||||
|
import org.jclouds.providers.ProviderMetadata;
|
||||||
|
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.inject.Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Live tests for the {@link org.jclouds.compute.extensions.ImageExtension} integration.
|
* Live tests for the {@link org.jclouds.compute.extensions.ImageExtension}
|
||||||
|
* integration.
|
||||||
*/
|
*/
|
||||||
@Test(groups = "live", singleThreaded = true, testName = "AzureComputeImageExtensionLiveTest")
|
@Test(groups = "live", singleThreaded = true, testName = "AzureComputeImageExtensionLiveTest")
|
||||||
public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTest {
|
public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTest {
|
||||||
|
@ -57,34 +63,33 @@ public class AzureComputeImageExtensionLiveTest extends BaseImageExtensionLiveTe
|
||||||
@Override
|
@Override
|
||||||
protected Properties setupProperties() {
|
protected Properties setupProperties() {
|
||||||
Properties properties = super.setupProperties();
|
Properties properties = super.setupProperties();
|
||||||
long scriptTimeout = TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES);
|
String defaultTimeout = String.valueOf(TimeUnit.MILLISECONDS.convert(60, TimeUnit.MINUTES));
|
||||||
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_SCRIPT_COMPLETE, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_NODE_RUNNING, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_NODE_RUNNING, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_PORT_OPEN, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_PORT_OPEN, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_NODE_TERMINATED, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_NODE_TERMINATED, defaultTimeout);
|
||||||
properties.setProperty(TIMEOUT_NODE_SUSPENDED, scriptTimeout + "");
|
properties.setProperty(TIMEOUT_NODE_SUSPENDED, defaultTimeout);
|
||||||
properties.put(RESOURCE_GROUP_NAME, "jcloudsgroup");
|
properties.put(RESOURCE_GROUP_NAME, "jc");
|
||||||
|
properties.put(PROPERTY_REGIONS, "eastus");
|
||||||
properties.put(ComputeServiceProperties.POLL_INITIAL_PERIOD, 1000);
|
properties.put(IMAGE_PUBLISHERS, "Canonical");
|
||||||
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);
|
AzureLiveTestUtils.defaultProperties(properties);
|
||||||
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
checkNotNull(setIfTestSystemPropertyPresent(properties, "oauth.endpoint"), "test.oauth.endpoint");
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ProviderMetadata createProviderMetadata() {
|
protected ProviderMetadata createProviderMetadata() {
|
||||||
AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
|
return AzureComputeProviderMetadata.builder().build();
|
||||||
return pm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TemplateBuilder getNodeTemplate() {
|
||||||
|
Map<String, String> keyPair = ComputeTestUtils.setupKeyPair();
|
||||||
|
return super.getNodeTemplate().options(
|
||||||
|
authorizePublicKey(keyPair.get("public"))
|
||||||
|
.overrideLoginPrivateKey(keyPair.get("private")));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,30 +16,19 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
|
||||||
import org.jclouds.azurecompute.arm.domain.Deployment;
|
import org.jclouds.azurecompute.arm.domain.Deployment;
|
||||||
import org.jclouds.azurecompute.arm.domain.Deployment.ProvisioningState;
|
import org.jclouds.azurecompute.arm.domain.Deployment.ProvisioningState;
|
||||||
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.Subnet;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
import org.jclouds.azurecompute.arm.domain.VirtualNetwork;
|
||||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||||
import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
|
||||||
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;
|
|
||||||
import org.jclouds.util.Predicates2;
|
import org.jclouds.util.Predicates2;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.AfterClass;
|
import org.testng.annotations.AfterClass;
|
||||||
|
@ -49,10 +38,6 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.net.UrlEscapers;
|
import com.google.common.net.UrlEscapers;
|
||||||
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
@Test(testName = "DeploymentApiLiveTest", singleThreaded = true)
|
@Test(testName = "DeploymentApiLiveTest", singleThreaded = true)
|
||||||
public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
|
|
||||||
|
@ -112,37 +97,6 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
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(LOCATION).description("West Europe").parent(provider).build();
|
|
||||||
|
|
||||||
OperatingSystem os = OperatingSystem.builder()
|
|
||||||
.family(OsFamily.UBUNTU)
|
|
||||||
.description("14.04.3-LTS")
|
|
||||||
.is64Bit(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Image image = (new ImageBuilder())
|
|
||||||
.id("UbuntuServer14.04.3-LTS")
|
|
||||||
.providerId("Canonical")
|
|
||||||
.name("UbuntuServer")
|
|
||||||
.description("14.04.3-LTS")
|
|
||||||
.version("14.04.3-LTS")
|
|
||||||
.operatingSystem(os)
|
|
||||||
.status(Image.Status.AVAILABLE)
|
|
||||||
.location(region)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Hardware hardware = (new HardwareBuilder()).id("Standard_A0").build();
|
|
||||||
return new TemplateImpl(image, hardware, region, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getDeploymentTemplateBuilderWithOptions(TemplateOptions options) {
|
|
||||||
Template template = getTemplate(options);
|
|
||||||
DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(resourceGroupName, deploymentName, template);
|
|
||||||
return templateBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidate(){
|
public void testValidate(){
|
||||||
Deployment deploymentInvalid = null;
|
Deployment deploymentInvalid = null;
|
||||||
|
@ -168,12 +122,40 @@ public class DeploymentApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
AzureTemplateOptions options = new AzureTemplateOptions();
|
||||||
options.authorizePublicKey(rsakey);
|
options.authorizePublicKey(rsakey);
|
||||||
options.subnetId(subnetId);
|
options.subnetId(subnetId);
|
||||||
DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithOptions(options);
|
|
||||||
DeploymentBody deploymentTemplateBody = templateBuilder.getDeploymentTemplate();
|
|
||||||
|
|
||||||
DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody);
|
String deploymentTemplate = "{\n" +
|
||||||
|
" \"id\": \"/subscriptions/04f7ec88-8e28-41ed-8537-5e17766001f5/resourceGroups/jims216group/providers/Microsoft.Resources/deployments/jcdep1458344383064\",\n" +
|
||||||
String deploymentTemplate = templateBuilder.getDeploymentTemplateJson(properties);
|
" \"name\": \"jcdep1458344383064\",\n" +
|
||||||
|
" \"properties\": {\n" +
|
||||||
|
" \"parameters\": {\n" +
|
||||||
|
" \"newStorageAccountName\": {\n" +
|
||||||
|
" \"type\": \"String\",\n" +
|
||||||
|
" \"value\": \"jcres1458344383064\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"storageAccountType\": {\n" +
|
||||||
|
" \"type\": \"String\",\n" +
|
||||||
|
" \"value\": \"Standard_LRS\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"location\": {\n" +
|
||||||
|
" \"type\": \"String\",\n" +
|
||||||
|
" \"value\": \"West US\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"mode\": \"Incremental\",\n" +
|
||||||
|
" \"provisioningState\": \"Accepted\",\n" +
|
||||||
|
" \"timestamp\": \"2016-03-18T23:39:47.3048037Z\",\n" +
|
||||||
|
" \"duration\": \"PT2.4433028S\",\n" +
|
||||||
|
" \"correlationId\": \"8dee9711-8632-4948-9fe6-368bb75e6438\",\n" +
|
||||||
|
" \"providers\": [{\n" +
|
||||||
|
" \"namespace\": \"Microsoft.Storage\",\n" +
|
||||||
|
" \"resourceTypes\": [{\n" +
|
||||||
|
" \"resourceType\": \"storageAccounts\",\n" +
|
||||||
|
" \"locations\": [\"westus\"]\n" +
|
||||||
|
" }]\n" +
|
||||||
|
" }],\n" +
|
||||||
|
" \"dependencies\": []\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}";
|
||||||
deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplate);
|
deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplate);
|
||||||
|
|
||||||
Deployment deploymentValid = api().validate(deploymentName, deploymentTemplate);
|
Deployment deploymentValid = api().validate(deploymentName, deploymentTemplate);
|
||||||
|
|
|
@ -1,287 +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.features;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
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.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.internal.BaseAzureComputeApiMockTest;
|
|
||||||
import org.jclouds.azurecompute.arm.util.DeploymentTemplateBuilder;
|
|
||||||
import org.jclouds.compute.domain.Hardware;
|
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
|
||||||
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;
|
|
||||||
import org.testng.Assert;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertEquals;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
@Test(groups = "unit", testName = "DeploymentTemplateBuilderTest", singleThreaded = true)
|
|
||||||
public class DeploymentTemplateBuilderTest extends BaseAzureComputeApiMockTest {
|
|
||||||
|
|
||||||
final String group = "jcgroup";
|
|
||||||
final String vnetName = group + "virtualnetwork";
|
|
||||||
final String subnetId = "";
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testResourceGroup() {
|
|
||||||
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.Storage/storageAccounts");
|
|
||||||
|
|
||||||
StorageServiceProperties properties = (StorageServiceProperties) resource.properties();
|
|
||||||
assertEquals(properties.accountType(), StorageService.AccountType.Standard_LRS);
|
|
||||||
assertTrue(variables.containsKey(parseVariableName(resource.name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testPublicIpAddress() {
|
|
||||||
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/publicIPAddresses");
|
|
||||||
|
|
||||||
PublicIPAddressProperties properties = (PublicIPAddressProperties) resource.properties();
|
|
||||||
assertEquals(properties.publicIPAllocationMethod(), "Dynamic");
|
|
||||||
assertTrue(variables.containsKey(parseVariableName(resource.name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testNetworkInterfaceCard() {
|
|
||||||
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/networkInterfaces");
|
|
||||||
|
|
||||||
NetworkInterfaceCardProperties properties = (NetworkInterfaceCardProperties) resource.properties();
|
|
||||||
List<IpConfiguration> ipConfigs = properties.ipConfigurations();
|
|
||||||
assertTrue(ipConfigs.size() > 0);
|
|
||||||
IpConfigurationProperties ipProperties = ipConfigs.get(0).properties();
|
|
||||||
assertEquals(ipProperties.privateIPAllocationMethod(), "Dynamic");
|
|
||||||
assertNotNull(ipProperties.publicIPAddress());
|
|
||||||
assertNotNull(ipProperties.subnet());
|
|
||||||
|
|
||||||
assertTrue(variables.containsKey(parseVariableName(resource.name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testVirtualMachine() {
|
|
||||||
DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithEmptyOptions();
|
|
||||||
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);
|
|
||||||
|
|
||||||
VirtualMachineProperties properties = (VirtualMachineProperties) resource.properties();
|
|
||||||
assertEquals(properties.hardwareProfile().vmSize(), template.getHardware().getId());
|
|
||||||
|
|
||||||
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");
|
|
||||||
|
|
||||||
assertTrue(variables.containsKey(parseVariableName(resource.name())));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAddStorageResourceWhenNameIsLongerThan24Chars() {
|
|
||||||
String name = "thishasmorethan24characters";
|
|
||||||
DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithEmptyOptions(name);
|
|
||||||
|
|
||||||
DeploymentBody deploymentBody = builder.getDeploymentTemplate();
|
|
||||||
assertTrue(Iterables.contains(deploymentBody.template().variables().keySet(), "storageAccountName"));
|
|
||||||
String storageAccountName = deploymentBody.template().variables().get("storageAccountName");
|
|
||||||
assertEquals(storageAccountName.length(), 24);
|
|
||||||
assertEquals(storageAccountName.substring(0, 10), "thishasmor");
|
|
||||||
assertEquals(storageAccountName.substring(storageAccountName.length() - 10, storageAccountName.length()), "characters");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAddStorageResourceWhenNameIsExactly24Chars() {
|
|
||||||
String name = "ithasexactly24characters";
|
|
||||||
DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithEmptyOptions(name);
|
|
||||||
|
|
||||||
DeploymentBody deploymentBody = builder.getDeploymentTemplate();
|
|
||||||
assertTrue(Iterables.contains(deploymentBody.template().variables().keySet(), "storageAccountName"));
|
|
||||||
assertEquals(deploymentBody.template().variables().get("storageAccountName").length(), 24);
|
|
||||||
assertEquals(deploymentBody.template().variables().get("storageAccountName"), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAddStorageResourceWhenNameIsLessThan3Chars() {
|
|
||||||
String name = "3c";
|
|
||||||
DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithEmptyOptions(name);
|
|
||||||
|
|
||||||
DeploymentBody deploymentBody = builder.getDeploymentTemplate();
|
|
||||||
assertTrue(Iterables.contains(deploymentBody.template().variables().keySet(), "storageAccountName"));
|
|
||||||
assertEquals(deploymentBody.template().variables().get("storageAccountName").length(), 6);
|
|
||||||
assertEquals(deploymentBody.template().variables().get("storageAccountName").substring(0, 2), name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
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);
|
|
||||||
|
|
||||||
options.virtualNetworkName(vnetName);
|
|
||||||
options.subnetId(subnetId);
|
|
||||||
|
|
||||||
assertEquals(options.as(AzureTemplateOptions.class).getCustomData(), customData);
|
|
||||||
assertEquals(options.getDNSLabelPrefix(), dnsLabelPrefix);
|
|
||||||
assertEquals(options.as(AzureTemplateOptions.class).getKeyVaultIdAndSecret(), keyvaultString);
|
|
||||||
|
|
||||||
DeploymentTemplateBuilder builder = getMockDeploymentTemplateBuilderWithOptions(options);
|
|
||||||
|
|
||||||
DeploymentBody deploymentBody = builder.getDeploymentTemplate();
|
|
||||||
|
|
||||||
List<ResourceDefinition> resources = deploymentBody.template().resources();
|
|
||||||
ResourceDefinition publicIpResource = getResourceByType(resources, "Microsoft.Network/publicIPAddresses");
|
|
||||||
assertNotNull(publicIpResource);
|
|
||||||
|
|
||||||
PublicIPAddressProperties ipProperties = (PublicIPAddressProperties) publicIpResource.properties();
|
|
||||||
assertEquals(ipProperties.dnsSettings().domainNameLabel(), dnsLabelPrefix);
|
|
||||||
|
|
||||||
ResourceDefinition vmResource = getResourceByType(resources, "Microsoft.Compute/virtualMachines");
|
|
||||||
assertNotNull(vmResource);
|
|
||||||
|
|
||||||
VirtualMachineProperties virtualMachineProperties = (VirtualMachineProperties) vmResource.properties();
|
|
||||||
assertEquals(virtualMachineProperties.osProfile().customData(), customData64);
|
|
||||||
|
|
||||||
//populated when keyvault is used to get public key.
|
|
||||||
assertNotNull(virtualMachineProperties.osProfile().linuxConfiguration().ssh().publicKeys());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
|
||||||
void testSimplifyPortsWithPortsNull() {
|
|
||||||
int[] ports = null;
|
|
||||||
DeploymentTemplateBuilder.simplifyPorts(ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expectedExceptions = IllegalArgumentException.class)
|
|
||||||
void testSimplifyPortsWithPortsEmpty() {
|
|
||||||
int[] ports = new int[0];
|
|
||||||
DeploymentTemplateBuilder.simplifyPorts(ports);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSimplifyPorts() {
|
|
||||||
int[] ports = {8084, 22, 8081, 8080, 8082};
|
|
||||||
List<String> ranges = DeploymentTemplateBuilder.simplifyPorts(ports);
|
|
||||||
assertEquals(ranges.size(), 3);
|
|
||||||
assertEquals(ranges.get(0), "22");
|
|
||||||
assertEquals(ranges.get(1), "8080-8082");
|
|
||||||
assertEquals(ranges.get(2), "8084");
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
//Note that version is set to "latest"
|
|
||||||
Image image = (new ImageBuilder()).id("imageId").providerId("imageId").name("imageName").description("imageDescription").version("sku").operatingSystem(os).status(Image.Status.AVAILABLE).location(region).build();
|
|
||||||
Hardware hardware = (new HardwareBuilder()).id("Standard_A0").build();
|
|
||||||
return new TemplateImpl(image, hardware, region, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getMockDeploymentTemplateBuilderWithEmptyOptions() {
|
|
||||||
return getMockDeploymentTemplateBuilderWithEmptyOptions("mydeployment");
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getMockDeploymentTemplateBuilderWithEmptyOptions(String name) {
|
|
||||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
|
||||||
options.virtualNetworkName(vnetName);
|
|
||||||
options.subnetId(subnetId);
|
|
||||||
|
|
||||||
Template template = getMockTemplate(options);
|
|
||||||
DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(group, name, template);
|
|
||||||
return templateBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getMockDeploymentTemplateBuilderWithOptions(TemplateOptions options) {
|
|
||||||
return getMockDeploymentTemplateBuilderWithOptions("mydeployment", options);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getMockDeploymentTemplateBuilderWithOptions(String name, TemplateOptions options) {
|
|
||||||
((AzureTemplateOptions)options).virtualNetworkName(vnetName);
|
|
||||||
((AzureTemplateOptions)options).subnetId(subnetId);
|
|
||||||
|
|
||||||
Template template = getMockTemplate(options);
|
|
||||||
DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(group, name, template);
|
|
||||||
return templateBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResourceDefinition getResourceByType(List<ResourceDefinition> resources, String type) {
|
|
||||||
for (ResourceDefinition r : resources) {
|
|
||||||
if (r.type().equals(type)) {
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert.fail("Resource with type: " + type + " not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String parseVariableName(String variable) {
|
|
||||||
String[] parts = variable.split("\'");
|
|
||||||
assertTrue(parts.length == 3);
|
|
||||||
return parts[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -83,8 +83,6 @@ public class NetworkSecurityGroupApiMockTest extends BaseAzureComputeApiMockTest
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getNetworkSecurityGroup() throws InterruptedException {
|
public void getNetworkSecurityGroup() throws InterruptedException {
|
||||||
NetworkSecurityGroup nsg = createGroup();
|
|
||||||
|
|
||||||
server.enqueue(jsonResponse("/networksecuritygroupget.json").setResponseCode(200));
|
server.enqueue(jsonResponse("/networksecuritygroupget.json").setResponseCode(200));
|
||||||
|
|
||||||
final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
|
final NetworkSecurityGroupApi nsgApi = api.getNetworkSecurityGroupApi(resourcegroup);
|
||||||
|
|
|
@ -147,8 +147,7 @@ public class PublicIPAddressApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
PublicIPAddressProperties properties = PublicIPAddressProperties.create(null, null, "Static", 4, null,
|
PublicIPAddressProperties properties = PublicIPAddressProperties.create(null, null, "Static", 4, null,
|
||||||
DnsSettings.create("foobar", "foobar.northeurope.cloudapp.azure.com", null));
|
DnsSettings.create("foobar", "foobar.northeurope.cloudapp.azure.com", null));
|
||||||
|
|
||||||
PublicIPAddress ip = ipApi.createOrUpdate(publicIpName, location, tags, properties);
|
ipApi.createOrUpdate(publicIpName, location, tags, properties);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deletePublicIPAddress() throws InterruptedException {
|
public void deletePublicIPAddress() throws InterruptedException {
|
||||||
|
|
|
@ -31,7 +31,6 @@ public class ResourceProviderAPIMockTest extends BaseAzureComputeApiMockTest {
|
||||||
|
|
||||||
final String apiVersion = "2015-01-01";
|
final String apiVersion = "2015-01-01";
|
||||||
final String resource = "Microsoft.Compute";
|
final String resource = "Microsoft.Compute";
|
||||||
private final String vm_resource = "virtualMachines";
|
|
||||||
|
|
||||||
public void getPublicIPAddressInfo() throws InterruptedException {
|
public void getPublicIPAddressInfo() throws InterruptedException {
|
||||||
server.enqueue(jsonResponse("/getresourceprovidermetadata.json"));
|
server.enqueue(jsonResponse("/getresourceprovidermetadata.json"));
|
||||||
|
|
|
@ -235,41 +235,6 @@ public class StorageAccountApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
"/providers/Microsoft.Storage/storageAccounts/TESTSTORAGE?api-version=2015-06-15");
|
"/providers/Microsoft.Storage/storageAccounts/TESTSTORAGE?api-version=2015-06-15");
|
||||||
}
|
}
|
||||||
|
|
||||||
private StorageService getStrorageAccount() {
|
|
||||||
DateService DATE_SERVICE = new SimpleDateFormatDateService();
|
|
||||||
Map<String, String> endpoints = new HashMap<String, String>();
|
|
||||||
endpoints.put("blob", "https://TESTSTORAGE.blob.core.windows.net/");
|
|
||||||
endpoints.put("file", "https://TESTSTORAGE.file.core.windows.net/");
|
|
||||||
endpoints.put("queue", "https://TESTSTORAGE.queue.core.windows.net/");
|
|
||||||
endpoints.put("table", "https://TESTSTORAGE.table.core.windows.net/");
|
|
||||||
Map<String, String> secondaryEndpoints = new HashMap<String, String>();
|
|
||||||
secondaryEndpoints.put("blob", "https://TESTSTORAGE-secondary.blob.core.windows.net/");
|
|
||||||
secondaryEndpoints.put("queue", "https://TESTSTORAGE-secondary.queue.core.windows.net/");
|
|
||||||
secondaryEndpoints.put("table", "https://TESTSTORAGE-secondary.table.core.windows.net/");
|
|
||||||
|
|
||||||
|
|
||||||
String location = "westus";
|
|
||||||
String secondaryLocation = "eastus";
|
|
||||||
final StorageService.StorageServiceProperties props = StorageService.StorageServiceProperties.create(
|
|
||||||
StorageService.AccountType.Standard_RAGRS,
|
|
||||||
DATE_SERVICE.iso8601DateOrSecondsDateParse("2016-02-24T13:04:45.0890883Z"),
|
|
||||||
endpoints,
|
|
||||||
location,
|
|
||||||
StorageService.Status.Succeeded,
|
|
||||||
secondaryEndpoints, secondaryLocation,
|
|
||||||
StorageService.RegionStatus.Available,
|
|
||||||
StorageService.RegionStatus.Available);
|
|
||||||
|
|
||||||
final Map<String, String> tags = ImmutableMap.of(
|
|
||||||
"key1", "value1",
|
|
||||||
"key2", "value2");
|
|
||||||
|
|
||||||
return StorageService.create(
|
|
||||||
"/subscriptions/SUBSCRIPTIONID/resourceGroups/resourceGroup" +
|
|
||||||
"/providers/Microsoft.Storage/storageAccounts/TESTSTORAGE",
|
|
||||||
"TESTSTORAGE", location, tags, null, props);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<StorageService> expected() throws MalformedURLException {
|
private List<StorageService> expected() throws MalformedURLException {
|
||||||
DateService DATE_SERVICE = new SimpleDateFormatDateService();
|
DateService DATE_SERVICE = new SimpleDateFormatDateService();
|
||||||
Map<String, String> endpoints = new HashMap<String, String>();
|
Map<String, String> endpoints = new HashMap<String, String>();
|
||||||
|
|
|
@ -16,18 +16,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import com.squareup.okhttp.mockwebserver.RecordedRequest;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.Subnet;
|
|
||||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.isEmpty;
|
import static com.google.common.collect.Iterables.isEmpty;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertFalse;
|
import static org.testng.Assert.assertFalse;
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
import static org.testng.Assert.assertNull;
|
import static org.testng.Assert.assertNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||||
|
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
||||||
@Test(groups = "unit", testName = "SubnetApiMockTest", singleThreaded = true)
|
@Test(groups = "unit", testName = "SubnetApiMockTest", singleThreaded = true)
|
||||||
|
@ -135,6 +134,6 @@ public class SubnetApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
assertFalse(status);
|
assertFalse(status);
|
||||||
|
|
||||||
String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s?%s", subscriptionid, resourcegroup, virtualNetwork, subnetName, apiVersion);
|
String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/virtualNetworks/%s/subnets/%s?%s", subscriptionid, resourcegroup, virtualNetwork, subnetName, apiVersion);
|
||||||
RecordedRequest rr = assertSent(server, "DELETE", path);
|
assertSent(server, "DELETE", path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,281 +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.features;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
|
|
||||||
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;
|
|
||||||
import org.jclouds.compute.domain.HardwareBuilder;
|
|
||||||
import org.jclouds.compute.domain.Image;
|
|
||||||
import org.jclouds.compute.domain.ImageBuilder;
|
|
||||||
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;
|
|
||||||
import org.testng.annotations.AfterClass;
|
|
||||||
import org.testng.annotations.BeforeClass;
|
|
||||||
import org.testng.annotations.Test;
|
|
||||||
|
|
||||||
import com.google.common.net.UrlEscapers;
|
|
||||||
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
@Test(groups = "live", testName = "TemplateToDeploymentTemplateLiveTest", singleThreaded = true)
|
|
||||||
public class TemplateToDeploymentTemplateLiveTest extends BaseAzureComputeApiLiveTest {
|
|
||||||
|
|
||||||
private int maxTestDuration = 400;
|
|
||||||
private int pollingInterval = 3; // how frequently to poll for create status
|
|
||||||
private String resourceGroupName;
|
|
||||||
private String deploymentName;
|
|
||||||
private String vnetName;
|
|
||||||
private String subnetId;
|
|
||||||
private String virtualNetworkName;
|
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
@Override
|
|
||||||
public void setup() {
|
|
||||||
super.setup();
|
|
||||||
resourceGroupName = String.format("rg-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
|
|
||||||
assertNotNull(createResourceGroup(resourceGroupName));
|
|
||||||
virtualNetworkName = String.format("vn-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
|
|
||||||
|
|
||||||
//Subnets belong to a virtual network so that needs to be created first
|
|
||||||
VirtualNetwork vn = createDefaultVirtualNetwork(resourceGroupName, virtualNetworkName, "10.2.0.0/16", LOCATION);
|
|
||||||
assertNotNull(vn);
|
|
||||||
vnetName = vn.name();
|
|
||||||
|
|
||||||
//Subnet needs to be up & running before NIC can be created
|
|
||||||
String subnetName = String.format("s-%s-%s", this.getClass().getSimpleName().toLowerCase(), System.getProperty("user.name"));
|
|
||||||
Subnet subnet = createDefaultSubnet(resourceGroupName, subnetName, virtualNetworkName, "10.2.0.0/23");
|
|
||||||
assertNotNull(subnet);
|
|
||||||
assertNotNull(subnet.id());
|
|
||||||
subnetId = subnet.id();
|
|
||||||
}
|
|
||||||
|
|
||||||
@AfterClass
|
|
||||||
@Override
|
|
||||||
protected void tearDown() {
|
|
||||||
super.tearDown();
|
|
||||||
URI uri = deleteResourceGroup(resourceGroupName);
|
|
||||||
assertResourceDeleted(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
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
|
|
||||||
public void testValidateDeploymentTemplateLinuxNode() {
|
|
||||||
Long now = System.currentTimeMillis();
|
|
||||||
deploymentName = "jc" + now;
|
|
||||||
|
|
||||||
DeploymentTemplateBuilder templateBuilder = getDeploymentTemplateBuilderWithEmptyOptions();
|
|
||||||
|
|
||||||
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
|
|
||||||
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
|
|
||||||
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");
|
|
||||||
|
|
||||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
|
||||||
options.virtualNetworkName(vnetName);
|
|
||||||
options.subnetId(subnetId);
|
|
||||||
|
|
||||||
options.authorizePublicKey(rsakey);
|
|
||||||
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
|
|
||||||
public void testCreateDeploymentTemplateLinuxNode() {
|
|
||||||
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");
|
|
||||||
|
|
||||||
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();
|
|
||||||
DeploymentProperties properties = DeploymentProperties.create(deploymentTemplateBody);
|
|
||||||
|
|
||||||
String deploymentTemplate = templateBuilder.getDeploymentTemplateJson(properties);
|
|
||||||
deploymentTemplate = UrlEscapers.urlFormParameterEscaper().escape(deploymentTemplate);
|
|
||||||
|
|
||||||
//creates an actual VM using deployment template
|
|
||||||
Deployment deployment = api().create(deploymentName, deploymentTemplate);
|
|
||||||
|
|
||||||
Deployment.ProvisioningState state = Deployment.ProvisioningState.fromValue(deployment.properties().provisioningState());
|
|
||||||
int testTime = 0;
|
|
||||||
while (testTime < maxTestDuration) {
|
|
||||||
if ((state == Deployment.ProvisioningState.SUCCEEDED) ||
|
|
||||||
(state == Deployment.ProvisioningState.CANCELED) ||
|
|
||||||
(state == Deployment.ProvisioningState.DELETED) ||
|
|
||||||
(state == Deployment.ProvisioningState.FAILED)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sleep a little bit before polling, timeout after a fixed time
|
|
||||||
try {
|
|
||||||
Thread.sleep(pollingInterval * 1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
testTime += pollingInterval;
|
|
||||||
|
|
||||||
deployment = api().get(deploymentName);
|
|
||||||
assertNotNull(deployment);
|
|
||||||
state = Deployment.ProvisioningState.fromValue(deployment.properties().provisioningState());
|
|
||||||
}
|
|
||||||
assertTrue(state == Deployment.ProvisioningState.SUCCEEDED);
|
|
||||||
assertNotNull(deployment);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(LOCATION).description(LOCATIONDESCRIPTION).parent(provider).build();
|
|
||||||
|
|
||||||
OperatingSystem os = OperatingSystem.builder()
|
|
||||||
.family(OsFamily.UBUNTU)
|
|
||||||
.description("14.04.3-LTS")
|
|
||||||
.is64Bit(true)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Image image = (new ImageBuilder())
|
|
||||||
.id("UbuntuServer14.04.3-LTS")
|
|
||||||
.providerId("Canonical")
|
|
||||||
.name("UbuntuServer")
|
|
||||||
.description("14.04.3-LTS")
|
|
||||||
.version("14.04.3-LTS")
|
|
||||||
.operatingSystem(os)
|
|
||||||
.status(Image.Status.AVAILABLE)
|
|
||||||
.location(region)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Hardware hardware = (new HardwareBuilder()).id("Standard_A0").build();
|
|
||||||
return new TemplateImpl(image, hardware, region, options);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getDeploymentTemplateBuilderWithEmptyOptions() {
|
|
||||||
AzureTemplateOptions options = new AzureTemplateOptions();
|
|
||||||
options.virtualNetworkName(vnetName);
|
|
||||||
options.subnetId(subnetId);
|
|
||||||
|
|
||||||
Template template = getTemplate(options);
|
|
||||||
DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(resourceGroupName, deploymentName, template);
|
|
||||||
return templateBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentTemplateBuilder getDeploymentTemplateBuilderWithOptions(TemplateOptions options) {
|
|
||||||
Template template = getTemplate(options);
|
|
||||||
DeploymentTemplateBuilder templateBuilder = api.deploymentTemplateFactory().create(resourceGroupName, deploymentName, template);
|
|
||||||
return templateBuilder;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeploymentApi api() {
|
|
||||||
return api.getDeploymentApi(resourceGroupName);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -16,6 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
|
import static org.jclouds.util.Predicates2.retry;
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -41,6 +45,7 @@ import org.jclouds.azurecompute.arm.domain.Subnet;
|
||||||
import org.jclouds.azurecompute.arm.domain.VHD;
|
import org.jclouds.azurecompute.arm.domain.VHD;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.VirtualMachineStatus.PowerState;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiLiveTest;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
|
@ -48,16 +53,9 @@ import org.testng.annotations.AfterClass;
|
||||||
import org.testng.annotations.BeforeClass;
|
import org.testng.annotations.BeforeClass;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.collect.FluentIterable;
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.gson.internal.LinkedTreeMap;
|
|
||||||
|
|
||||||
import static org.jclouds.util.Predicates2.retry;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
|
||||||
import static org.testng.Assert.assertTrue;
|
|
||||||
|
|
||||||
@Test(groups = "live", testName = "VirtualMachineApiLiveTest")
|
@Test(groups = "live", testName = "VirtualMachineApiLiveTest")
|
||||||
public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
|
@ -125,7 +123,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
}, 60 * 20 * 1000).apply(vmName);
|
}, 60 * 20 * 1000).apply(vmName);
|
||||||
assertTrue(jobDone, "create operation did not complete in the configured timeout");
|
assertTrue(jobDone, "create operation did not complete in the configured timeout");
|
||||||
|
|
||||||
String status = api().get(vmName).properties().provisioningState();
|
VirtualMachineProperties.ProvisioningState status = api().get(vmName).properties().provisioningState();
|
||||||
// Cannot be creating anymore. Should be succeeded or running but not failed.
|
// Cannot be creating anymore. Should be succeeded or running but not failed.
|
||||||
assertTrue(!status.equals("Creating"));
|
assertTrue(!status.equals("Creating"));
|
||||||
assertTrue(!status.equals("Failed"));
|
assertTrue(!status.equals("Failed"));
|
||||||
|
@ -146,21 +144,21 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
@Test(dependsOnMethods = "testStart")
|
@Test(dependsOnMethods = "testStart")
|
||||||
public void testStop() {
|
public void testStop() {
|
||||||
api().stop(vmName);
|
api().stop(vmName);
|
||||||
assertTrue(stateReached("PowerState", "VM stopped"), "stop operation did not complete in the configured timeout");
|
assertTrue(stateReached(PowerState.STOPPED), "stop operation did not complete in the configured timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testGet")
|
@Test(dependsOnMethods = "testGet")
|
||||||
public void testStart() {
|
public void testStart() {
|
||||||
api().start(vmName);
|
api().start(vmName);
|
||||||
assertTrue(stateReached("PowerState", "VM running"), "start operation did not complete in the configured timeout");
|
assertTrue(stateReached(PowerState.RUNNING), "start operation did not complete in the configured timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testStop")
|
@Test(dependsOnMethods = "testStop")
|
||||||
public void testRestart() {
|
public void testRestart() {
|
||||||
api().start(vmName);
|
api().start(vmName);
|
||||||
assertTrue(stateReached("PowerState", "VM running"), "start operation did not complete in the configured timeout");
|
assertTrue(stateReached(PowerState.RUNNING), "start operation did not complete in the configured timeout");
|
||||||
api().restart(vmName);
|
api().restart(vmName);
|
||||||
assertTrue(stateReached("PowerState", "VM running"), "restart operation did not complete in the configured timeout");
|
assertTrue(stateReached(PowerState.RUNNING), "restart operation did not complete in the configured timeout");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testCreate")
|
@Test(dependsOnMethods = "testCreate")
|
||||||
|
@ -180,10 +178,11 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
@Test(dependsOnMethods = "testRestart")
|
@Test(dependsOnMethods = "testRestart")
|
||||||
public void testGeneralize() throws IllegalStateException {
|
public void testGeneralize() throws IllegalStateException {
|
||||||
api().stop(vmName);
|
api().stop(vmName);
|
||||||
assertTrue(stateReached("PowerState", "VM stopped"), "restart operation did not complete in the configured timeout");
|
assertTrue(stateReached(PowerState.STOPPED), "restart operation did not complete in the configured timeout");
|
||||||
api().generalize(vmName);
|
api().generalize(vmName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
@Test(dependsOnMethods = "testGeneralize")
|
@Test(dependsOnMethods = "testGeneralize")
|
||||||
public void testCapture() throws IllegalStateException {
|
public void testCapture() throws IllegalStateException {
|
||||||
URI uri = api().capture(vmName, vmName, vmName);
|
URI uri = api().capture(vmName, vmName, vmName);
|
||||||
|
@ -192,17 +191,17 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
|
List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
|
||||||
if (definitions != null) {
|
if (definitions != null) {
|
||||||
for (ResourceDefinition definition : definitions) {
|
for (ResourceDefinition definition : definitions) {
|
||||||
LinkedTreeMap<String, String> properties = (LinkedTreeMap<String, String>) definition.properties();
|
Map<String, String> properties = (Map<String, String>) definition.properties();
|
||||||
Object storageObject = properties.get("storageProfile");
|
Object storageObject = properties.get("storageProfile");
|
||||||
LinkedTreeMap<String, String> properties2 = (LinkedTreeMap<String, String>) storageObject;
|
Map<String, String> properties2 = (Map<String, String>) storageObject;
|
||||||
Object osDiskObject = properties2.get("osDisk");
|
Object osDiskObject = properties2.get("osDisk");
|
||||||
LinkedTreeMap<String, String> osProperties = (LinkedTreeMap<String, String>) osDiskObject;
|
Map<String, String> osProperties = (Map<String, String>) osDiskObject;
|
||||||
Object dataDisksObject = properties2.get("dataDisks");
|
Object dataDisksObject = properties2.get("dataDisks");
|
||||||
ArrayList<Object> dataProperties = (ArrayList<Object>) dataDisksObject;
|
List<Object> dataProperties = (List<Object>) dataDisksObject;
|
||||||
LinkedTreeMap<String, String> datadiskObject = (LinkedTreeMap<String, String>) dataProperties.get(0);
|
Map<String, String> datadiskObject = (Map<String, String>) dataProperties.get(0);
|
||||||
|
|
||||||
Assert.assertNotNull(osProperties.get("name"));
|
assertNotNull(osProperties.get("name"));
|
||||||
Assert.assertNotNull(datadiskObject.get("name"));
|
assertNotNull(datadiskObject.get("name"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,7 +244,7 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
DiagnosticsProfile.BootDiagnostics.create(true, blob);
|
DiagnosticsProfile.BootDiagnostics.create(true, blob);
|
||||||
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
|
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
|
||||||
VirtualMachineProperties properties = VirtualMachineProperties.create(null,
|
VirtualMachineProperties properties = VirtualMachineProperties.create(null,
|
||||||
null, null, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile, "Creating");
|
null, null, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile, VirtualMachineProperties.ProvisioningState.CREATING);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,37 +260,15 @@ public class VirtualMachineApiLiveTest extends BaseAzureComputeApiLiveTest {
|
||||||
return api.getNetworkInterfaceCardApi(resourceGroupName).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, tags);
|
return api.getNetworkInterfaceCardApi(resourceGroupName).createOrUpdate(networkInterfaceCardName, locationName, networkInterfaceCardProperties, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean deleteStorageService(String resourceGroupName, String storageServiceName) {
|
private boolean waitForState(String name, final PowerState state) {
|
||||||
return api.getStorageAccountApi(resourceGroupName).delete(storageServiceName);
|
return api().getInstanceDetails(name).powerState().equals(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean waitForState(String name, final String state, final String displayStatus) {
|
private boolean stateReached(final PowerState state) {
|
||||||
return FluentIterable.from(api().getInstanceDetails(name).statuses())
|
|
||||||
.filter(new Predicate<VirtualMachineInstance.VirtualMachineStatus>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(VirtualMachineInstance.VirtualMachineStatus input) {
|
|
||||||
return input.code().substring(0, 10).equals(state);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.transform(new Function<VirtualMachineInstance.VirtualMachineStatus, String>() {
|
|
||||||
@Override
|
|
||||||
public String apply(VirtualMachineInstance.VirtualMachineStatus input) {
|
|
||||||
return input.displayStatus();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.anyMatch(new Predicate<String>() {
|
|
||||||
@Override
|
|
||||||
public boolean apply(String input) {
|
|
||||||
return input.equals(displayStatus);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean stateReached(final String state, final String displayStatus) {
|
|
||||||
return retry(new Predicate<String>() {
|
return retry(new Predicate<String>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(String name) {
|
public boolean apply(String name) {
|
||||||
return waitForState(name, state, displayStatus);
|
return waitForState(name, state);
|
||||||
}
|
}
|
||||||
}, 60 * 4 * 1000).apply(vmName);
|
}, 60 * 4 * 1000).apply(vmName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,35 +16,36 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.azurecompute.arm.features;
|
package org.jclouds.azurecompute.arm.features;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import java.net.URI;
|
||||||
import com.squareup.okhttp.mockwebserver.MockResponse;
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jclouds.azurecompute.arm.domain.DataDisk;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.HardwareProfile;
|
import org.jclouds.azurecompute.arm.domain.HardwareProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.IdReference;
|
import org.jclouds.azurecompute.arm.domain.IdReference;
|
||||||
import org.jclouds.azurecompute.arm.domain.ImageReference;
|
import org.jclouds.azurecompute.arm.domain.ImageReference;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
import org.jclouds.azurecompute.arm.domain.NetworkProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.VHD;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.OSDisk;
|
import org.jclouds.azurecompute.arm.domain.OSDisk;
|
||||||
import org.jclouds.azurecompute.arm.domain.OSProfile;
|
import org.jclouds.azurecompute.arm.domain.OSProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.DiagnosticsProfile;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.NetworkProfile;
|
|
||||||
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
import org.jclouds.azurecompute.arm.domain.StorageProfile;
|
||||||
import org.jclouds.azurecompute.arm.domain.DataDisk;
|
import org.jclouds.azurecompute.arm.domain.VHD;
|
||||||
|
import org.jclouds.azurecompute.arm.domain.VirtualMachine;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
|
||||||
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
import org.jclouds.azurecompute.arm.domain.VirtualMachineProperties;
|
||||||
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
|
import org.jclouds.azurecompute.arm.internal.BaseAzureComputeApiMockTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import java.net.URI;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.ArrayList;
|
import com.squareup.okhttp.mockwebserver.MockResponse;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.text.DateFormat;
|
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.isEmpty;
|
import static com.google.common.collect.Iterables.isEmpty;
|
||||||
import static org.testng.Assert.assertEquals;
|
import static org.testng.Assert.assertEquals;
|
||||||
import static org.testng.Assert.assertNull;
|
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
import static org.testng.Assert.assertNull;
|
||||||
import static org.testng.Assert.assertTrue;
|
import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
@Test(groups = "unit", testName = "VirtualMachineApiMockTest", singleThreaded = true)
|
@Test(groups = "unit", testName = "VirtualMachineApiMockTest", singleThreaded = true)
|
||||||
|
@ -55,14 +56,14 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
final VirtualMachineApi vmAPI = api.getVirtualMachineApi("groupname");
|
final VirtualMachineApi vmAPI = api.getVirtualMachineApi("groupname");
|
||||||
assertEquals(vmAPI.get("windowsmachine"), getVM());
|
assertEquals(vmAPI.get("windowsmachine"), getVM());
|
||||||
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine?api-version=2015-06-15");
|
"/virtualMachines/windowsmachine?api-version=2016-03-30");
|
||||||
}
|
}
|
||||||
public void testGetEmpty() throws Exception {
|
public void testGetEmpty() throws Exception {
|
||||||
server.enqueue(new MockResponse().setResponseCode(404));
|
server.enqueue(new MockResponse().setResponseCode(404));
|
||||||
final VirtualMachineApi vmAPI = api.getVirtualMachineApi("groupname");
|
final VirtualMachineApi vmAPI = api.getVirtualMachineApi("groupname");
|
||||||
assertNull(vmAPI.get("windowsmachine"));
|
assertNull(vmAPI.get("windowsmachine"));
|
||||||
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine?api-version=2015-06-15");
|
"/virtualMachines/windowsmachine?api-version=2016-03-30");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetInstanceDetails() throws Exception {
|
public void testGetInstanceDetails() throws Exception {
|
||||||
|
@ -76,7 +77,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
assertEquals(actual.statuses().get(0).level(), expected.statuses().get(0).level());
|
assertEquals(actual.statuses().get(0).level(), expected.statuses().get(0).level());
|
||||||
//assertEquals(actual.statuses().get(0).time().toString(), expected.statuses().get(0).time().toString());
|
//assertEquals(actual.statuses().get(0).time().toString(), expected.statuses().get(0).time().toString());
|
||||||
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine/instanceView?api-version=2015-06-15");
|
"/virtualMachines/windowsmachine/instanceView?api-version=2016-03-30");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetInstanceDetailsEmpty() throws Exception {
|
public void testGetInstanceDetailsEmpty() throws Exception {
|
||||||
|
@ -84,7 +85,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
final VirtualMachineApi vmAPI = api.getVirtualMachineApi("groupname");
|
final VirtualMachineApi vmAPI = api.getVirtualMachineApi("groupname");
|
||||||
assertNull(vmAPI.getInstanceDetails("windowsmachine"));
|
assertNull(vmAPI.getInstanceDetails("windowsmachine"));
|
||||||
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "GET", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine/instanceView?api-version=2015-06-15");
|
"/virtualMachines/windowsmachine/instanceView?api-version=2016-03-30");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testList() throws Exception {
|
public void testList() throws Exception {
|
||||||
|
@ -109,7 +110,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
VirtualMachine vm = vmAPI.create("windowsmachine", "westus", getProperties());
|
VirtualMachine vm = vmAPI.create("windowsmachine", "westus", getProperties());
|
||||||
assertEquals(vm, getVM());
|
assertEquals(vm, getVM());
|
||||||
assertSent(server, "PUT", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "PUT", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine?api-version=2015-06-15&validating=false",
|
"/virtualMachines/windowsmachine?validating=false&api-version=2016-03-30",
|
||||||
"{\"location\":\"westus\",\"properties\":" +
|
"{\"location\":\"westus\",\"properties\":" +
|
||||||
"{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\"," +
|
"{\"vmId\":\"27ee085b-d707-xxxx-yyyy-2370e2eb1cc1\"," +
|
||||||
"\"hardwareProfile\":{\"vmSize\":\"Standard_D1\"}," +
|
"\"hardwareProfile\":{\"vmSize\":\"Standard_D1\"}," +
|
||||||
|
@ -118,7 +119,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
"\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\"},\"dataDisks\":[]}," +
|
"\"vhd\":{\"uri\":\"https://groupname2760.blob.core.windows.net/vhds/windowsmachine201624102936.vhd\"},\"caching\":\"ReadWrite\",\"createOption\":\"FromImage\"},\"dataDisks\":[]}," +
|
||||||
"\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"windowsConfiguration\":{\"provisionVMAgent\":false,\"enableAutomaticUpdates\":true}}," +
|
"\"osProfile\":{\"computerName\":\"windowsmachine\",\"adminUsername\":\"azureuser\",\"windowsConfiguration\":{\"provisionVMAgent\":false,\"enableAutomaticUpdates\":true}}," +
|
||||||
"\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167\"}]}," +
|
"\"networkProfile\":{\"networkInterfaces\":[{\"id\":\"/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Network/networkInterfaces/windowsmachine167\"}]}," +
|
||||||
"\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://groupname2760.blob.core.windows.net/\"}},\"provisioningState\":\"Creating\"}}");
|
"\"diagnosticsProfile\":{\"bootDiagnostics\":{\"enabled\":true,\"storageUri\":\"https://groupname2760.blob.core.windows.net/\"}},\"provisioningState\":\"CREATING\"}}");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +134,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
assertNull(uri);
|
assertNull(uri);
|
||||||
|
|
||||||
assertSent(server, "DELETE", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "DELETE", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine?api-version=2015-06-15");
|
"/virtualMachines/windowsmachine?api-version=2016-03-30");
|
||||||
}
|
}
|
||||||
public void testDelete() throws Exception {
|
public void testDelete() throws Exception {
|
||||||
server.enqueue(response202WithHeader());
|
server.enqueue(response202WithHeader());
|
||||||
|
@ -146,7 +147,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
assertNotNull(uri);
|
assertNotNull(uri);
|
||||||
|
|
||||||
assertSent(server, "DELETE", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
assertSent(server, "DELETE", "/subscriptions/SUBSCRIPTIONID/resourceGroups/groupname/providers/Microsoft.Compute" +
|
||||||
"/virtualMachines/windowsmachine?api-version=2015-06-15");
|
"/virtualMachines/windowsmachine?api-version=2016-03-30");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStart() throws Exception {
|
public void testStart() throws Exception {
|
||||||
|
@ -231,7 +232,7 @@ public class VirtualMachineApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
"https://groupname2760.blob.core.windows.net/");
|
"https://groupname2760.blob.core.windows.net/");
|
||||||
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
|
DiagnosticsProfile diagnosticsProfile = DiagnosticsProfile.create(bootDiagnostics);
|
||||||
VirtualMachineProperties properties = VirtualMachineProperties.create("27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
|
VirtualMachineProperties properties = VirtualMachineProperties.create("27ee085b-d707-xxxx-yyyy-2370e2eb1cc1",
|
||||||
null, null, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile, "Creating");
|
null, null, hwProf, storageProfile, osProfile, networkProfile, diagnosticsProfile, VirtualMachineProperties.ProvisioningState.CREATING);
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ public class VirtualNetworkApiMockTest extends BaseAzureComputeApiMockTest {
|
||||||
VirtualNetwork.AddressSpace.create(Arrays.asList("10.2.0.0/16")), null);
|
VirtualNetwork.AddressSpace.create(Arrays.asList("10.2.0.0/16")), null);
|
||||||
|
|
||||||
|
|
||||||
VirtualNetwork vn = vnApi.createOrUpdate(virtualNetwork, location, virtualNetworkProperties);
|
vnApi.createOrUpdate(virtualNetwork, location, virtualNetworkProperties);
|
||||||
|
|
||||||
String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/virtualNetworks/%s?%s", subscriptionid, resourcegroup, virtualNetwork, apiVersion);
|
String path = String.format("/subscriptions/%s/resourcegroups/%s/providers/Microsoft.Network/virtualNetworks/%s?%s", subscriptionid, resourcegroup, virtualNetwork, apiVersion);
|
||||||
String json = String.format("{\"location\":\"%s\",\"properties\":{\"addressSpace\":{\"addressPrefixes\":[\"%s\"]}}}", location, "10.2.0.0/16");
|
String json = String.format("{\"location\":\"%s\",\"properties\":{\"addressSpace\":{\"addressPrefixes\":[\"%s\"]}}}", location, "10.2.0.0/16");
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* 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.filters;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.createMock;
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.EasyMock.replay;
|
||||||
|
import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.API_VERSION_PREFIX;
|
||||||
|
import static org.jclouds.reflect.Reflection2.method;
|
||||||
|
import static org.testng.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import org.jclouds.http.HttpRequest;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.internal.FilterStringsBoundToInjectorByName;
|
||||||
|
import org.jclouds.reflect.Invocation;
|
||||||
|
import org.jclouds.rest.config.InvocationConfig;
|
||||||
|
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import com.google.inject.name.Names;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "ApiVersionFilterTest", singleThreaded = true)
|
||||||
|
public class ApiVersionFilterTest {
|
||||||
|
|
||||||
|
public interface VersionedApi {
|
||||||
|
HttpResponse noName();
|
||||||
|
|
||||||
|
@Named("named:get")
|
||||||
|
HttpResponse named();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Invocation noName;
|
||||||
|
private Invocation named;
|
||||||
|
private InvocationConfig config;
|
||||||
|
|
||||||
|
@BeforeMethod
|
||||||
|
public void setup() {
|
||||||
|
noName = Invocation.create(method(VersionedApi.class, "noName"), ImmutableList.of());
|
||||||
|
named = Invocation.create(method(VersionedApi.class, "named"), ImmutableList.of());
|
||||||
|
|
||||||
|
config = createMock(InvocationConfig.class);
|
||||||
|
expect(config.getCommandName(noName)).andReturn("VersionedApi.noName");
|
||||||
|
expect(config.getCommandName(named)).andReturn("named:get");
|
||||||
|
replay(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expectedExceptions = IllegalArgumentException.class)
|
||||||
|
public void testFailIfNoGeneratedHttpRequest() {
|
||||||
|
ApiVersionFilter filter = new ApiVersionFilter(config, filterStringsBoundToInjectorByName(new Properties()));
|
||||||
|
filter.filter(HttpRequest.builder().method("GET").endpoint("http://localhost").build());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOverrideMethodVersion() {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty(API_VERSION_PREFIX + "named:get", "namedversion");
|
||||||
|
props.setProperty(API_VERSION_PREFIX + "VersionedApi.noName", "noNameversion");
|
||||||
|
ApiVersionFilter filter = new ApiVersionFilter(config, filterStringsBoundToInjectorByName(props));
|
||||||
|
|
||||||
|
HttpRequest request = GeneratedHttpRequest.builder().method("GET").endpoint("http://localhost")
|
||||||
|
.invocation(noName).addQueryParam("api-version", "original", "original2").build();
|
||||||
|
HttpRequest filtered = filter.filter(request);
|
||||||
|
assertEquals(filtered.getEndpoint().getQuery(), "api-version=noNameversion");
|
||||||
|
|
||||||
|
request = GeneratedHttpRequest.builder().method("GET").endpoint("http://localhost").invocation(named)
|
||||||
|
.addQueryParam("api-version", "original", "original2").build();
|
||||||
|
filtered = filter.filter(request);
|
||||||
|
assertEquals(filtered.getEndpoint().getQuery(), "api-version=namedversion");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFallbackToClassName() {
|
||||||
|
Properties props = new Properties();
|
||||||
|
props.setProperty(API_VERSION_PREFIX + "VersionedApi", "classversion");
|
||||||
|
ApiVersionFilter filter = new ApiVersionFilter(config, filterStringsBoundToInjectorByName(props));
|
||||||
|
|
||||||
|
HttpRequest request = GeneratedHttpRequest.builder().method("GET").endpoint("http://localhost")
|
||||||
|
.invocation(noName).addQueryParam("api-version", "original", "original2").build();
|
||||||
|
HttpRequest filtered = filter.filter(request);
|
||||||
|
assertEquals(filtered.getEndpoint().getQuery(), "api-version=classversion");
|
||||||
|
|
||||||
|
request = GeneratedHttpRequest.builder().method("GET").endpoint("http://localhost").invocation(named)
|
||||||
|
.addQueryParam("api-version", "original", "original2").build();
|
||||||
|
filtered = filter.filter(request);
|
||||||
|
assertEquals(filtered.getEndpoint().getQuery(), "api-version=classversion");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNothingChangesIfNoCustomVersion() {
|
||||||
|
ApiVersionFilter filter = new ApiVersionFilter(config, filterStringsBoundToInjectorByName(new Properties()));
|
||||||
|
|
||||||
|
HttpRequest request = GeneratedHttpRequest.builder().method("GET").endpoint("http://localhost").invocation(named)
|
||||||
|
.addQueryParam("api-version", "foo").build();
|
||||||
|
HttpRequest filtered = filter.filter(request);
|
||||||
|
assertEquals(filtered.getEndpoint().getQuery(), "api-version=foo");
|
||||||
|
}
|
||||||
|
|
||||||
|
private FilterStringsBoundToInjectorByName filterStringsBoundToInjectorByName(final Properties props) {
|
||||||
|
Injector injector = Guice.createInjector(new AbstractModule() {
|
||||||
|
protected void configure() {
|
||||||
|
Names.bindProperties(binder(), props);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new FilterStringsBoundToInjectorByName(injector);
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ import org.jclouds.ContextBuilder;
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
import org.jclouds.azurecompute.arm.AzureComputeApi;
|
||||||
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
import org.jclouds.azurecompute.arm.AzureComputeProviderMetadata;
|
||||||
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
import org.jclouds.concurrent.config.ExecutorServiceModule;
|
||||||
|
import org.jclouds.rest.ApiContext;
|
||||||
import org.testng.annotations.AfterMethod;
|
import org.testng.annotations.AfterMethod;
|
||||||
import org.testng.annotations.BeforeMethod;
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
|
||||||
|
@ -50,6 +51,7 @@ public class BaseAzureComputeApiMockTest {
|
||||||
|
|
||||||
protected MockWebServer server;
|
protected MockWebServer server;
|
||||||
protected AzureComputeApi api;
|
protected AzureComputeApi api;
|
||||||
|
protected ApiContext<AzureComputeApi> context;
|
||||||
|
|
||||||
// So that we can ignore formatting.
|
// So that we can ignore formatting.
|
||||||
private final JsonParser parser = new JsonParser();
|
private final JsonParser parser = new JsonParser();
|
||||||
|
@ -58,16 +60,21 @@ public class BaseAzureComputeApiMockTest {
|
||||||
public void start() throws IOException {
|
public void start() throws IOException {
|
||||||
server = new MockWebServer();
|
server = new MockWebServer();
|
||||||
server.play();
|
server.play();
|
||||||
Properties properties = new Properties();
|
|
||||||
properties.put(CREDENTIAL_TYPE, BEARER_TOKEN_CREDENTIALS.toString());
|
|
||||||
properties.put("oauth.endpoint", "https://login.microsoftonline.com/tenant-id/oauth2/token");
|
|
||||||
AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
|
AzureComputeProviderMetadata pm = AzureComputeProviderMetadata.builder().build();
|
||||||
api = ContextBuilder.newBuilder(pm)
|
context = ContextBuilder.newBuilder(pm)
|
||||||
.credentials("", MOCK_BEARER_TOKEN)
|
.credentials("", MOCK_BEARER_TOKEN)
|
||||||
.endpoint(server.getUrl("/").toString() + "subscriptions/SUBSCRIPTIONID")
|
.endpoint(server.getUrl("/").toString() + "subscriptions/SUBSCRIPTIONID")
|
||||||
.modules(modules)
|
.modules(modules)
|
||||||
.overrides(properties)
|
.overrides(setupProperties())
|
||||||
.buildApi(AzureComputeApi.class);
|
.build();
|
||||||
|
api = context.getApi();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Properties setupProperties() {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.put(CREDENTIAL_TYPE, BEARER_TOKEN_CREDENTIALS.toString());
|
||||||
|
properties.put("oauth.endpoint", "https://login.microsoftonline.com/tenant-id/oauth2/token");
|
||||||
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterMethod(alwaysRun = true)
|
@AfterMethod(alwaysRun = true)
|
||||||
|
|
Loading…
Reference in New Issue