You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by na...@apache.org on 2018/01/11 15:40:55 UTC

[12/50] [abbrv] jclouds git commit: Add Azure KeyVault support

Add Azure KeyVault support


Project: http://git-wip-us.apache.org/repos/asf/jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/jclouds/commit/a2dee2f8
Tree: http://git-wip-us.apache.org/repos/asf/jclouds/tree/a2dee2f8
Diff: http://git-wip-us.apache.org/repos/asf/jclouds/diff/a2dee2f8

Branch: refs/heads/keystonev3
Commit: a2dee2f84c96ba743e1fa81bd225b066473ea26d
Parents: ac5f3a1
Author: Jim Spring <jm...@gmail.com>
Authored: Fri Dec 22 18:37:08 2017 -0800
Committer: Ignasi Barrera <na...@apache.org>
Committed: Thu Jan 4 01:44:48 2018 +0100

----------------------------------------------------------------------
 .../azurecompute/arm/AzureComputeApi.java       |   12 +-
 .../arm/AzureComputeProviderMetadata.java       |    2 +
 .../arm/AzureManagementApiMetadata.java         |    2 +
 .../arm/compute/AzureComputeServiceAdapter.java |    2 +-
 .../AzureComputeServiceContextModule.java       |  269 ---
 .../compute/config/AzurePredicatesModule.java   |  602 +++++++
 .../ResourceGroupAndNameAndIngressRules.java    |    5 +-
 .../extensions/AzureComputeImageExtension.java  |    4 +-
 .../AzureComputeSecurityGroupExtension.java     |    2 +-
 .../loaders/CreateSecurityGroupIfNeeded.java    |    2 +-
 .../arm/config/AzureComputeProperties.java      |    9 +
 .../azurecompute/arm/domain/Certificate.java    |  638 +++++++
 .../jclouds/azurecompute/arm/domain/Key.java    |  229 +++
 .../jclouds/azurecompute/arm/domain/SKU.java    |   27 +-
 .../jclouds/azurecompute/arm/domain/Secret.java |  186 ++
 .../jclouds/azurecompute/arm/domain/Vault.java  |  112 ++
 .../arm/domain/VaultProperties.java             |  131 ++
 .../azurecompute/arm/features/VaultApi.java     |  635 +++++++
 .../arm/features/LoadBalancerApiLiveTest.java   |    2 +-
 .../arm/features/VaultApiLiveTest.java          | 1057 ++++++++++++
 .../arm/features/VaultApiMockTest.java          | 1619 ++++++++++++++++++
 .../internal/BaseAzureComputeApiLiveTest.java   |   60 +-
 .../internal/BaseAzureComputeApiMockTest.java   |   16 +-
 .../src/test/resources/getvault.json            |   60 +
 .../src/test/resources/vaultbackupkey.json      |    3 +
 .../src/test/resources/vaultbackupsecret.json   |    3 +
 .../src/test/resources/vaultcreate.json         |   26 +
 .../test/resources/vaultcreatecertificate.json  |   11 +
 .../vaultcreatecertificaterequestbody.json      |   21 +
 .../src/test/resources/vaultcreatekey.json      |   15 +
 .../resources/vaultcreatekeyrequestbody.json    |    7 +
 .../test/resources/vaultcreaterequestbody.json  |   21 +
 .../test/resources/vaultdeletecertificate.json  |   58 +
 .../vaultdeletecertificatecontacts.json         |    8 +
 .../resources/vaultdeletecertificateissuer.json |   21 +
 .../vaultdeletecertificateoperation.json        |   11 +
 .../src/test/resources/vaultdeletekey.json      |   15 +
 .../src/test/resources/vaultdeletesecret.json   |   10 +
 .../src/test/resources/vaultget.json            |   26 +
 .../src/test/resources/vaultgetcertificate.json |   55 +
 .../resources/vaultgetcertificatecontacts.json  |    8 +
 .../resources/vaultgetcertificateissuer.json    |   21 +
 .../resources/vaultgetcertificateoperation.json |   11 +
 .../resources/vaultgetcertificatepolicy.json    |   37 +
 .../src/test/resources/vaultgetdeleted.json     |   12 +
 .../resources/vaultgetdeletedcertificate.json   |   55 +
 .../src/test/resources/vaultgetdeletedkey.json  |   18 +
 .../test/resources/vaultgetdeletedsecret.json   |   13 +
 .../src/test/resources/vaultgetkey.json         |   15 +
 .../src/test/resources/vaultgetkeyversions.json |   23 +
 .../src/test/resources/vaultgetsecret.json      |   11 +
 .../test/resources/vaultgetsecretversions.json  |   25 +
 .../src/test/resources/vaultimportablecert.txt  |   58 +
 .../test/resources/vaultimportcertificate.json  |   52 +
 .../vaultimportcertificaterequestbody.json      |    9 +
 .../resources/vaultimportkeyrequestbody.json    |   18 +
 .../src/test/resources/vaultkeybackup.txt       |    1 +
 .../src/test/resources/vaultkeydecrypt.json     |    4 +
 .../resources/vaultkeydecryptrequestbody.json   |    4 +
 .../src/test/resources/vaultkeyencrypt.json     |    4 +
 .../resources/vaultkeyencryptrequestbody.json   |    4 +
 .../src/test/resources/vaultkeysign.json        |    4 +
 .../test/resources/vaultkeysignrequestbody.json |    4 +
 .../src/test/resources/vaultkeyunwrap.json      |    4 +
 .../resources/vaultkeyunwraprequestbody.json    |    4 +
 .../src/test/resources/vaultkeyverify.json      |    3 +
 .../resources/vaultkeyverifyrequestbody.json    |    5 +
 .../src/test/resources/vaultkeywrap.json        |    4 +
 .../test/resources/vaultkeywraprequestbody.json |    4 +
 .../src/test/resources/vaultlist.json           |   29 +
 .../resources/vaultlistcertificateissuers.json  |    7 +
 .../test/resources/vaultlistcertificates.json   |   27 +
 .../resources/vaultlistcertificateversions.json |   17 +
 .../src/test/resources/vaultlistdeleted.json    |   15 +
 .../resources/vaultlistdeletedcertificates.json |   18 +
 .../test/resources/vaultlistdeletedkeys.json    |   15 +
 .../test/resources/vaultlistdeletedsecrets.json |   16 +
 .../src/test/resources/vaultlistkeys.json       |   42 +
 .../src/test/resources/vaultlistsecrets.json    |   40 +
 .../test/resources/vaultmergecertificate.json   |   62 +
 .../vaultmergecertificaterequestbody.json       |   10 +
 .../src/test/resources/vaultmergex5c-1.txt      |    1 +
 .../src/test/resources/vaultmergex5c-2.txt      |    1 +
 .../src/test/resources/vaultmergex5c-3.txt      |    1 +
 .../vaultrecoverdeletedcertificate.json         |   52 +
 .../test/resources/vaultrecoverdeletedkey.json  |   15 +
 .../resources/vaultrecoverdeletedsecret.json    |   10 +
 .../src/test/resources/vaultrestorekey.json     |   15 +
 .../resources/vaultrestorekeyrequestbody.json   |    3 +
 .../src/test/resources/vaultrestoresecret.json  |   10 +
 .../vaultrestoresecretrequestbody.json          |    3 +
 .../src/test/resources/vaultsamplesecret.txt    |   27 +
 .../src/test/resources/vaultsecretbackup.txt    |    1 +
 .../resources/vaultsetcertificatecontacts.json  |    8 +
 .../vaultsetcertificatecontactsrequestbody.json |    7 +
 .../resources/vaultsetcertificateissuer.json    |   21 +
 .../vaultsetcertificateissuerrequestbody.json   |   15 +
 .../src/test/resources/vaultsetsecret.json      |   11 +
 .../resources/vaultsetsecretrequestbody.json    |    7 +
 .../test/resources/vaultupdatecertificate.json  |   58 +
 .../resources/vaultupdatecertificateissuer.json |   21 +
 ...vaultupdatecertificateissuerrequestbody.json |   15 +
 .../vaultupdatecertificateoperation.json        |   11 +
 ...ltupdatecertificateoperationrequestbody.json |    3 +
 .../resources/vaultupdatecertificatepolicy.json |   37 +
 ...vaultupdatecertificatepolicyrequestbody.json |    8 +
 .../vaultupdatecertificaterequestbody.json      |    1 +
 .../src/test/resources/vaultupdatekey.json      |   18 +
 .../resources/vaultupdatekeyrequestbody.json    |    5 +
 .../resources/vaultupdatekeywithversion.json    |   18 +
 .../src/test/resources/vaultupdatesecret.json   |   13 +
 .../resources/vaultupdatesecretrequestbody.json |    5 +
 .../resources/vaultupdatesecretwithversion.json |   13 +
 ...vaultupdatesecretwithversionrequestbody.json |    5 +
 114 files changed, 6861 insertions(+), 305 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
index 1f6b726..d62a5b7 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeApi.java
@@ -41,6 +41,7 @@ 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.VaultApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineScaleSetApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
@@ -242,7 +243,7 @@ public interface AzureComputeApi extends Closeable {
     */
    @Delegate
    MetricDefinitionsApi getMetricsDefinitionsApi(@PathParam("resourceid") String resourceid);
-   
+
    /**
     * The Azure Active Directory Graph API provides programmatic access to Azure
     * AD through REST API endpoints.
@@ -253,6 +254,15 @@ public interface AzureComputeApi extends Closeable {
    GraphRBACApi getGraphRBACApi();
    
    /**
+    * Managing your key vaults as well as the keys, secrets, and certificates within your key vaults can be 
+    * accomplished through a REST interface.
+    *
+    * @see <a href="https://docs.microsoft.com/en-us/rest/api/keyvault/">docs</a>
+    */
+   @Delegate
+   VaultApi getVaultApi(@PathParam("resourcegroup") String resourcegroup);
+   
+   /**
     * Returns the information about the current service principal.
     */
    @Provides

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
index 335de98..c85beb9 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureComputeProviderMetadata.java
@@ -57,6 +57,7 @@ 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.VaultApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineApi;
 import org.jclouds.azurecompute.arm.features.VirtualMachineScaleSetApi;
 import org.jclouds.azurecompute.arm.features.VirtualNetworkApi;
@@ -126,6 +127,7 @@ public class AzureComputeProviderMetadata extends BaseProviderMetadata {
       properties.put(API_VERSION_PREFIX + MetricsApi.class.getSimpleName(), "2016-09-01");
       properties.put(API_VERSION_PREFIX + VirtualMachineScaleSetApi.class.getSimpleName(), "2017-03-30");
       properties.put(API_VERSION_PREFIX + GraphRBACApi.class.getSimpleName(), "1.6");
+      properties.put(API_VERSION_PREFIX + VaultApi.class.getSimpleName(), "2016-10-01");
       
       return properties;
    }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
index 9c73e99..56cb788 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/AzureManagementApiMetadata.java
@@ -23,6 +23,7 @@ import java.util.Properties;
 
 import org.jclouds.apis.ApiMetadata;
 import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule;
+import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule;
 import org.jclouds.azurecompute.arm.config.AzureComputeHttpApiModule;
 import org.jclouds.azurecompute.arm.config.AzureComputeParserModule;
 import org.jclouds.azurecompute.arm.config.AzureComputeRateLimitModule;
@@ -80,6 +81,7 @@ public class AzureManagementApiMetadata extends BaseHttpApiMetadata<AzureCompute
                          .add(AzureComputeParserModule.class)
                          .add(AzureComputeHttpApiModule.class)
                          .add(AzureComputeServiceContextModule.class)
+                         .add(AzurePredicatesModule.class)
                          .add(AzureComputeRateLimitModule.class)
                          .build());
       }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
index 37585e2..cd5e0e9 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/AzureComputeServiceAdapter.java
@@ -45,7 +45,7 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.PublicIpAvailablePredicateFactory;
+import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.PublicIpAvailablePredicateFactory;
 import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName;
 import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage;
 import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
index 11d3ab1..de33fdf 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzureComputeServiceContextModule.java
@@ -16,22 +16,8 @@
  */
 package org.jclouds.azurecompute.arm.compute.config;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
-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_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.util.Predicates2.retry;
-
-import java.net.URI;
-import java.util.List;
-
-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.domain.ResourceGroupAndNameAndIngressRules;
@@ -47,20 +33,13 @@ import org.jclouds.azurecompute.arm.compute.loaders.CreateSecurityGroupIfNeeded;
 import org.jclouds.azurecompute.arm.compute.loaders.DefaultResourceGroup;
 import org.jclouds.azurecompute.arm.compute.options.AzureTemplateOptions;
 import org.jclouds.azurecompute.arm.compute.strategy.CreateResourcesThenCreateNodes;
-import org.jclouds.azurecompute.arm.domain.Image;
 import org.jclouds.azurecompute.arm.domain.Location;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityRule;
-import org.jclouds.azurecompute.arm.domain.Provisionable;
-import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
-import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
 import org.jclouds.azurecompute.arm.domain.ResourceGroup;
 import org.jclouds.azurecompute.arm.domain.VMHardware;
 import org.jclouds.azurecompute.arm.domain.VMImage;
 import org.jclouds.azurecompute.arm.domain.VirtualMachine;
-import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
-import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance.PowerState;
-import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
 import org.jclouds.compute.ComputeService;
 import org.jclouds.compute.ComputeServiceAdapter;
 import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
@@ -72,15 +51,10 @@ import org.jclouds.compute.extensions.SecurityGroupExtension;
 import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatement;
 import org.jclouds.compute.functions.NodeAndTemplateOptionsToStatementWithoutPublicKey;
 import org.jclouds.compute.options.TemplateOptions;
-import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
-import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
 import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
 import org.jclouds.net.domain.IpPermission;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.base.Supplier;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
@@ -141,247 +115,4 @@ public class AzureComputeServiceContextModule extends
    protected final LoadingCache<String, ResourceGroup> defaultResourceGroup(CacheLoader<String, ResourceGroup> in) {
       return CacheBuilder.newBuilder().build(in);
    }
-
-   @Provides
-   @Named(TIMEOUT_NODE_RUNNING)
-   protected VirtualMachineInStatePredicateFactory provideVirtualMachineRunningPredicate(final AzureComputeApi api,
-         final Timeouts timeouts, final PollPeriod pollPeriod) {
-      return new VirtualMachineInStatePredicateFactory(api, PowerState.RUNNING, timeouts.nodeRunning,
-            pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
-   }
-
-   @Provides
-   @Named(TIMEOUT_NODE_TERMINATED)
-   protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, final Timeouts timeouts,
-         final PollPeriod pollPeriod) {
-      return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
-            pollPeriod.pollMaxPeriod);
-   }
-
-   @Provides
-   @Named(TIMEOUT_IMAGE_AVAILABLE)
-   protected Predicate<URI> provideImageCapturedPredicate(final AzureComputeApi api, final Timeouts timeouts,
-         final PollPeriod pollPeriod) {
-      return retry(new ImageCapturedPredicate(api), timeouts.imageAvailable, pollPeriod.pollInitialPeriod,
-            pollPeriod.pollMaxPeriod);
-   }
-
-   @Provides
-   @Named(TIMEOUT_RESOURCE_DELETED)
-   protected Predicate<URI> provideResourceDeletedPredicate(final AzureComputeApi api, final Timeouts timeouts,
-         final PollPeriod pollPeriod) {
-      return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
-            pollPeriod.pollMaxPeriod);
-   }
-
-   @Provides
-   @Named(TIMEOUT_NODE_SUSPENDED)
-   protected VirtualMachineInStatePredicateFactory provideNodeSuspendedPredicate(final AzureComputeApi api,
-         final Timeouts timeouts, final PollPeriod pollPeriod) {
-      return new VirtualMachineInStatePredicateFactory(api, PowerState.STOPPED, timeouts.nodeTerminated,
-            pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
-   }
-
-   @Provides
-   protected PublicIpAvailablePredicateFactory providePublicIpAvailablePredicate(final AzureComputeApi api,
-         Predicate<Supplier<Provisionable>> resourceAvailable) {
-      return new PublicIpAvailablePredicateFactory(api, resourceAvailable);
-   }
-
-   @Provides
-   protected SecurityGroupAvailablePredicateFactory provideSecurityGroupAvailablePredicate(final AzureComputeApi api,
-         Predicate<Supplier<Provisionable>> resourceAvailable) {
-      return new SecurityGroupAvailablePredicateFactory(api, resourceAvailable);
-   }
-   
-   @Provides
-   protected ImageAvailablePredicateFactory provideImageAvailablePredicate(final AzureComputeApi api,
-         Predicate<Supplier<Provisionable>> resourceAvailable, final Timeouts timeouts, final PollPeriod pollPeriod) {
-      return new ImageAvailablePredicateFactory(api, retry(new ResourceInStatusPredicate("Succeeded"),
-            timeouts.imageAvailable, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod));
-   }
-
-   @Provides
-   protected Predicate<Supplier<Provisionable>> provideResourceAvailablePredicate(final AzureComputeApi api,
-         @Named(OPERATION_TIMEOUT) Integer operationTimeout, PollPeriod pollPeriod) {
-      return retry(new ResourceInStatusPredicate("Succeeded"), operationTimeout, pollPeriod.pollInitialPeriod,
-            pollPeriod.pollMaxPeriod);
-   }
-
-   @Provides
-   @Named("STORAGE")
-   protected Predicate<URI> provideStorageAccountAvailablePredicate(final AzureComputeApi api,
-         @Named(OPERATION_TIMEOUT) Integer operationTimeout, PollPeriod pollPeriod) {
-      return retry(new ActionDonePredicate(api), operationTimeout, pollPeriod.pollInitialPeriod,
-            pollPeriod.pollMaxPeriod);
-   }
-
-   @VisibleForTesting
-   static class ActionDonePredicate implements Predicate<URI> {
-
-      private final AzureComputeApi api;
-
-      public ActionDonePredicate(final AzureComputeApi api) {
-         this.api = checkNotNull(api, "api must not be null");
-      }
-
-      @Override
-      public boolean apply(final URI uri) {
-         checkNotNull(uri, "uri cannot be null");
-         return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri)
-               || ParseJobStatus.JobStatus.NO_CONTENT == api.getJobApi().jobStatus(uri);
-      }
-
-   }
-
-   @VisibleForTesting
-   static class ImageCapturedPredicate implements Predicate<URI> {
-
-      private final AzureComputeApi api;
-
-      public ImageCapturedPredicate(final AzureComputeApi api) {
-         this.api = checkNotNull(api, "api must not be null");
-      }
-
-      @Override
-      public boolean apply(final URI uri) {
-         checkNotNull(uri, "uri cannot be null");
-         if (api.getJobApi().jobStatus(uri) != ParseJobStatus.JobStatus.DONE) {
-            return false;
-         }
-         List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
-         return definitions != null;
-      }
-   }
-
-   public static class VirtualMachineInStatePredicateFactory {
-
-      private final AzureComputeApi api;
-      private final PowerState powerState;
-      private final long timeout;
-      private final long period;
-      private final long maxPeriod;
-
-      VirtualMachineInStatePredicateFactory(final AzureComputeApi api, final PowerState powerState, final long timeout,
-            final long period, final long maxPeriod) {
-         this.api = checkNotNull(api, "api cannot be null");
-         this.powerState = checkNotNull(powerState, "powerState cannot be null");
-         this.timeout = timeout;
-         this.period = period;
-         this.maxPeriod = maxPeriod;
-      }
-
-      public Predicate<String> create(final String azureGroup) {
-         return retry(new Predicate<String>() {
-            @Override
-            public boolean apply(final String name) {
-               checkNotNull(name, "name cannot be null");
-               VirtualMachineInstance vmInstance = api.getVirtualMachineApi(azureGroup).getInstanceDetails(name);
-               if (vmInstance == null) {
-                  return false;
-               }
-               return powerState == vmInstance.powerState();
-            }
-         }, timeout, period, maxPeriod);
-      }
-   }
-   
-   public static class ResourceInStatusPredicate implements Predicate<Supplier<Provisionable>> {
-      private final String expectedStatus;
-
-      ResourceInStatusPredicate(String expectedStatus) {
-         this.expectedStatus = checkNotNull(expectedStatus, "expectedStatus cannot be null");
-      }
-
-      @Override
-      public boolean apply(Supplier<Provisionable> provisionableSupplier) {
-         checkNotNull(provisionableSupplier, "provisionableSupplier supplier cannot be null");
-         Provisionable provisionable = provisionableSupplier.get();
-         return provisionable != null && provisionable.provisioningState().equalsIgnoreCase(expectedStatus);
-      }
-   }
-
-   public static class PublicIpAvailablePredicateFactory {
-      private final AzureComputeApi api;
-      private final Predicate<Supplier<Provisionable>> resourceAvailable;
-
-      PublicIpAvailablePredicateFactory(final AzureComputeApi api, Predicate<Supplier<Provisionable>> resourceAvailable) {
-         this.api = checkNotNull(api, "api cannot be null");
-         this.resourceAvailable = resourceAvailable;
-      }
-
-      public Predicate<String> create(final String azureGroup) {
-         checkNotNull(azureGroup, "azureGroup cannot be null");
-         return new Predicate<String>() {
-            @Override
-            public boolean apply(final String name) {
-               checkNotNull(name, "name cannot be null");
-               return resourceAvailable.apply(new Supplier<Provisionable>() {
-                  @Override
-                  public Provisionable get() {
-                     PublicIPAddress publicIp = api.getPublicIPAddressApi(azureGroup).get(name);
-                     return publicIp == null ? null : publicIp.properties();
-                  }
-               });
-            }
-         };
-      }
-   }
-
-   public static class SecurityGroupAvailablePredicateFactory {
-      private final AzureComputeApi api;
-      private final Predicate<Supplier<Provisionable>> resourceAvailable;
-
-      SecurityGroupAvailablePredicateFactory(final AzureComputeApi api,
-            Predicate<Supplier<Provisionable>> resourceAvailable) {
-         this.api = checkNotNull(api, "api cannot be null");
-         this.resourceAvailable = resourceAvailable;
-      }
-
-      public Predicate<String> create(final String resourceGroup) {
-         checkNotNull(resourceGroup, "resourceGroup cannot be null");
-         return new Predicate<String>() {
-            @Override
-            public boolean apply(final String name) {
-               checkNotNull(name, "name cannot be null");
-               return resourceAvailable.apply(new Supplier<Provisionable>() {
-                  @Override
-                  public Provisionable get() {
-                     NetworkSecurityGroup sg = api.getNetworkSecurityGroupApi(resourceGroup).get(name);
-                     return sg == null ? null : sg.properties();
-                  }
-               });
-            }
-         };
-      }
-   }
-   
-   public static class ImageAvailablePredicateFactory {
-      private final AzureComputeApi api;
-      private final Predicate<Supplier<Provisionable>> resourceAvailable;
-      
-      ImageAvailablePredicateFactory(final AzureComputeApi api,
-            Predicate<Supplier<Provisionable>> resourceAvailable) {
-         this.api = checkNotNull(api, "api cannot be null");
-         this.resourceAvailable = resourceAvailable;
-      }
-
-      public Predicate<String> create(final String resourceGroup) {
-         checkNotNull(resourceGroup, "resourceGroup cannot be null");
-         return new Predicate<String>() {
-            @Override
-            public boolean apply(final String name) {
-               checkNotNull(name, "name cannot be null");
-               return resourceAvailable.apply(new Supplier<Provisionable>() {
-                  @Override
-                  public Provisionable get() {
-                     Image img = api.getVirtualMachineImageApi(resourceGroup).get(name);
-                     return img == null ? null : img.properties();
-                  }
-               });
-            }
-         };
-      }
-   }
-
 }

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java
new file mode 100644
index 0000000..c8dfd6e
--- /dev/null
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/config/AzurePredicatesModule.java
@@ -0,0 +1,602 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jclouds.azurecompute.arm.compute.config;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+import com.google.common.collect.Iterables;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provides;
+import com.google.inject.name.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.reference.ComputeServiceConstants.PollPeriod;
+
+import org.jclouds.azurecompute.arm.domain.Image;
+import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
+import org.jclouds.azurecompute.arm.domain.Provisionable;
+import org.jclouds.azurecompute.arm.domain.PublicIPAddress;
+import org.jclouds.azurecompute.arm.domain.ResourceDefinition;
+import org.jclouds.azurecompute.arm.domain.Vault;
+import org.jclouds.azurecompute.arm.domain.VirtualMachineInstance;
+import org.jclouds.azurecompute.arm.functions.ParseJobStatus;
+import org.jclouds.azurecompute.arm.AzureComputeApi;
+import org.jclouds.azurecompute.arm.domain.Key.DeletedKeyBundle;
+import org.jclouds.azurecompute.arm.domain.Key.KeyBundle;
+import org.jclouds.azurecompute.arm.domain.Secret.DeletedSecretBundle;
+import org.jclouds.azurecompute.arm.domain.Secret.SecretBundle;
+import org.jclouds.azurecompute.arm.domain.Certificate.DeletedCertificateBundle;
+import org.jclouds.azurecompute.arm.domain.Certificate.CertificateBundle;
+import org.jclouds.azurecompute.arm.domain.Certificate.CertificateOperation;
+
+import java.net.URI;
+import java.util.List;
+
+import static org.jclouds.util.Predicates2.retry;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
+import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_IMAGE_AVAILABLE;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.TIMEOUT_RESOURCE_DELETED;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.OPERATION_TIMEOUT;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_DELETE_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_KEY_DELETED_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_KEY_RECOVERABLE_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_SECRET_DELETE_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_SECRET_RECOVERABLE_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_DELETE_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_RECOVERABLE_STATUS;
+import static org.jclouds.azurecompute.arm.config.AzureComputeProperties.VAULT_CERTIFICATE_OPERATION_STATUS;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+public class AzurePredicatesModule extends AbstractModule {
+    protected void configure() {
+    }
+
+    @Provides
+    @Named(TIMEOUT_NODE_RUNNING)
+    protected VirtualMachineInStatePredicateFactory provideVirtualMachineRunningPredicate(final AzureComputeApi api,
+                                                                                          final ComputeServiceConstants.Timeouts timeouts, final PollPeriod pollPeriod) {
+        return new VirtualMachineInStatePredicateFactory(api, VirtualMachineInstance.PowerState.RUNNING, timeouts.nodeRunning,
+                pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(TIMEOUT_NODE_TERMINATED)
+    protected Predicate<URI> provideNodeTerminatedPredicate(final AzureComputeApi api, final ComputeServiceConstants.Timeouts timeouts,
+                                                            final PollPeriod pollPeriod) {
+        return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
+                pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(TIMEOUT_IMAGE_AVAILABLE)
+    protected Predicate<URI> provideImageCapturedPredicate(final AzureComputeApi api, final ComputeServiceConstants.Timeouts timeouts,
+                                                           final PollPeriod pollPeriod) {
+        return retry(new ImageCapturedPredicate(api), timeouts.imageAvailable, pollPeriod.pollInitialPeriod,
+                pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(TIMEOUT_RESOURCE_DELETED)
+    protected Predicate<URI> provideResourceDeletedPredicate(final AzureComputeApi api, final ComputeServiceConstants.Timeouts timeouts,
+                                                             final PollPeriod pollPeriod) {
+        return retry(new ActionDonePredicate(api), timeouts.nodeTerminated, pollPeriod.pollInitialPeriod,
+                pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(TIMEOUT_NODE_SUSPENDED)
+    protected VirtualMachineInStatePredicateFactory provideNodeSuspendedPredicate(final AzureComputeApi api,
+                                                                                  final ComputeServiceConstants.Timeouts timeouts, final PollPeriod pollPeriod) {
+        return new VirtualMachineInStatePredicateFactory(api, VirtualMachineInstance.PowerState.STOPPED, timeouts.nodeTerminated,
+                pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    protected PublicIpAvailablePredicateFactory providePublicIpAvailablePredicate(final AzureComputeApi api,
+                                                                                  Predicate<Supplier<Provisionable>> resourceAvailable) {
+        return new PublicIpAvailablePredicateFactory(api, resourceAvailable);
+    }
+
+    @Provides
+    protected SecurityGroupAvailablePredicateFactory provideSecurityGroupAvailablePredicate(final AzureComputeApi api,
+                                                                                            Predicate<Supplier<Provisionable>> resourceAvailable) {
+        return new SecurityGroupAvailablePredicateFactory(api, resourceAvailable);
+    }
+
+    @Provides
+    protected ImageAvailablePredicateFactory provideImageAvailablePredicate(final AzureComputeApi api,
+                                                                            Predicate<Supplier<Provisionable>> resourceAvailable, final ComputeServiceConstants.Timeouts timeouts, final PollPeriod pollPeriod) {
+        return new ImageAvailablePredicateFactory(api, retry(new ResourceInStatusPredicate("Succeeded"),
+                timeouts.imageAvailable, pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod));
+    }
+
+    @Provides
+    protected Predicate<Supplier<Provisionable>> provideResourceAvailablePredicate(final AzureComputeApi api,
+                                                                                   @Named(OPERATION_TIMEOUT) Integer operationTimeout, PollPeriod pollPeriod) {
+        return retry(new ResourceInStatusPredicate("Succeeded"), operationTimeout, pollPeriod.pollInitialPeriod,
+                pollPeriod.pollMaxPeriod);
+    }
+
+    @VisibleForTesting
+    static class ActionDonePredicate implements Predicate<URI> {
+
+        private final AzureComputeApi api;
+
+        public ActionDonePredicate(final AzureComputeApi api) {
+            this.api = checkNotNull(api, "api must not be null");
+        }
+
+        @Override
+        public boolean apply(final URI uri) {
+            checkNotNull(uri, "uri cannot be null");
+            return ParseJobStatus.JobStatus.DONE == api.getJobApi().jobStatus(uri)
+                    || ParseJobStatus.JobStatus.NO_CONTENT == api.getJobApi().jobStatus(uri);
+        }
+    }
+
+    @VisibleForTesting
+    static class ImageCapturedPredicate implements Predicate<URI> {
+
+        private final AzureComputeApi api;
+
+        public ImageCapturedPredicate(final AzureComputeApi api) {
+            this.api = checkNotNull(api, "api must not be null");
+        }
+
+        @Override
+        public boolean apply(final URI uri) {
+            checkNotNull(uri, "uri cannot be null");
+            if (api.getJobApi().jobStatus(uri) != ParseJobStatus.JobStatus.DONE) {
+                return false;
+            }
+            List<ResourceDefinition> definitions = api.getJobApi().captureStatus(uri);
+            return definitions != null;
+        }
+    }
+
+    public static class VirtualMachineInStatePredicateFactory {
+
+        private final AzureComputeApi api;
+        private final VirtualMachineInstance.PowerState powerState;
+        private final long timeout;
+        private final long period;
+        private final long maxPeriod;
+
+        VirtualMachineInStatePredicateFactory(final AzureComputeApi api, final VirtualMachineInstance.PowerState powerState, final long timeout,
+                                              final long period, final long maxPeriod) {
+            this.api = checkNotNull(api, "api cannot be null");
+            this.powerState = checkNotNull(powerState, "powerState cannot be null");
+            this.timeout = timeout;
+            this.period = period;
+            this.maxPeriod = maxPeriod;
+        }
+
+        public Predicate<String> create(final String azureGroup) {
+            return retry(new Predicate<String>() {
+                @Override
+                public boolean apply(final String name) {
+                    checkNotNull(name, "name cannot be null");
+                    VirtualMachineInstance vmInstance = api.getVirtualMachineApi(azureGroup).getInstanceDetails(name);
+                    if (vmInstance == null) {
+                        return false;
+                    }
+                    return powerState == vmInstance.powerState();
+                }
+            }, timeout, period, maxPeriod);
+        }
+    }
+
+    public static class ResourceInStatusPredicate implements Predicate<Supplier<Provisionable>> {
+        private final String expectedStatus;
+
+        ResourceInStatusPredicate(String expectedStatus) {
+            this.expectedStatus = checkNotNull(expectedStatus, "expectedStatus cannot be null");
+        }
+
+        @Override
+        public boolean apply(Supplier<Provisionable> provisionableSupplier) {
+            checkNotNull(provisionableSupplier, "provisionableSupplier supplier cannot be null");
+            Provisionable provisionable = provisionableSupplier.get();
+            return provisionable != null && provisionable.provisioningState().equalsIgnoreCase(expectedStatus);
+        }
+    }
+
+    public static class PublicIpAvailablePredicateFactory {
+        private final AzureComputeApi api;
+        private final Predicate<Supplier<Provisionable>> resourceAvailable;
+
+        PublicIpAvailablePredicateFactory(final AzureComputeApi api, Predicate<Supplier<Provisionable>> resourceAvailable) {
+            this.api = checkNotNull(api, "api cannot be null");
+            this.resourceAvailable = resourceAvailable;
+        }
+
+        public Predicate<String> create(final String azureGroup) {
+            checkNotNull(azureGroup, "azureGroup cannot be null");
+            return new Predicate<String>() {
+                @Override
+                public boolean apply(final String name) {
+                    checkNotNull(name, "name cannot be null");
+                    return resourceAvailable.apply(new Supplier<Provisionable>() {
+                        @Override
+                        public Provisionable get() {
+                            PublicIPAddress publicIp = api.getPublicIPAddressApi(azureGroup).get(name);
+                            return publicIp == null ? null : publicIp.properties();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    public static class SecurityGroupAvailablePredicateFactory {
+        private final AzureComputeApi api;
+        private final Predicate<Supplier<Provisionable>> resourceAvailable;
+
+        SecurityGroupAvailablePredicateFactory(final AzureComputeApi api,
+                                               Predicate<Supplier<Provisionable>> resourceAvailable) {
+            this.api = checkNotNull(api, "api cannot be null");
+            this.resourceAvailable = resourceAvailable;
+        }
+
+        public Predicate<String> create(final String resourceGroup) {
+            checkNotNull(resourceGroup, "resourceGroup cannot be null");
+            return new Predicate<String>() {
+                @Override
+                public boolean apply(final String name) {
+                    checkNotNull(name, "name cannot be null");
+                    return resourceAvailable.apply(new Supplier<Provisionable>() {
+                        @Override
+                        public Provisionable get() {
+                            NetworkSecurityGroup sg = api.getNetworkSecurityGroupApi(resourceGroup).get(name);
+                            return sg == null ? null : sg.properties();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    public static class ImageAvailablePredicateFactory {
+        private final AzureComputeApi api;
+        private final Predicate<Supplier<Provisionable>> resourceAvailable;
+
+        ImageAvailablePredicateFactory(final AzureComputeApi api,
+                                       Predicate<Supplier<Provisionable>> resourceAvailable) {
+            this.api = checkNotNull(api, "api cannot be null");
+            this.resourceAvailable = resourceAvailable;
+        }
+
+        public Predicate<String> create(final String resourceGroup) {
+            checkNotNull(resourceGroup, "resourceGroup cannot be null");
+            return new Predicate<String>() {
+                @Override
+                public boolean apply(final String name) {
+                    checkNotNull(name, "name cannot be null");
+                    return resourceAvailable.apply(new Supplier<Provisionable>() {
+                        @Override
+                        public Provisionable get() {
+                            Image img = api.getVirtualMachineImageApi(resourceGroup).get(name);
+                            return img == null ? null : img.properties();
+                        }
+                    });
+                }
+            };
+        }
+    }
+
+    @Provides
+    @Named(VAULT_DELETE_STATUS)
+    protected VaultPredicates.DeletedVaultStatusPredicateFactory provideDeletedVaultStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                           @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                           final PollPeriod pollPeriod) {
+        return new VaultPredicates.DeletedVaultStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    public static class VaultPredicates {
+        public static class DeletedVaultStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            DeletedVaultStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final boolean shouldBePresent) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        checkNotNull(name, "name cannot be null");
+                        boolean present = false;
+                        List<Vault.DeletedVault> vaults = api.getVaultApi(resourceGroup).listDeletedVaults();
+                        return shouldBePresent == Iterables.any(vaults, new Predicate<Vault.DeletedVault>() {
+                            @Override public boolean apply(Vault.DeletedVault input) {
+                                return input.name().equals(name);
+                            }
+                        });
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+    }
+
+    @Provides
+    @Named(VAULT_KEY_DELETED_STATUS)
+    protected VaultKeyPredicates.DeletedKeyStatusPredicateFactory provideDeletedKeyStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                          @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                          final PollPeriod pollPeriod) {
+        return new VaultKeyPredicates.DeletedKeyStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(VAULT_KEY_RECOVERABLE_STATUS)
+    protected VaultKeyPredicates.RecoverableKeyStatusPredicateFactory provideRecoverableKeyStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                                  @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                                  final PollPeriod pollPeriod) {
+        return new VaultKeyPredicates.RecoverableKeyStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    public static class VaultKeyPredicates {
+        public static class DeletedKeyStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            DeletedKeyStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean shouldBePresent) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        checkNotNull(name, "name cannot be null");
+                        boolean present = false;
+                        DeletedKeyBundle key = api.getVaultApi(resourceGroup).getDeletedKey(vaultUri, name);
+                        return shouldBePresent == (key != null);
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+
+        public static class RecoverableKeyStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            RecoverableKeyStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isRecovered) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        checkNotNull(name, "name cannot be null");
+                        boolean result = false;
+                        KeyBundle key = api.getVaultApi(resourceGroup).getKey(vaultUri, name);
+                        return key != null ? (isRecovered ? true : key.attributes().recoveryLevel().contains("Recoverable")) : false;
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+    }
+
+    @Provides
+    @Named(VAULT_SECRET_DELETE_STATUS)
+    protected VaultSecretPredicates.DeletedSecretStatusPredicateFactory provideDeletedSecretStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                                   @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                                   final PollPeriod pollPeriod) {
+        return new VaultSecretPredicates.DeletedSecretStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(VAULT_SECRET_RECOVERABLE_STATUS)
+    protected VaultSecretPredicates.RecoverableSecretStatusPredicateFactory provideRecoverableSecretStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                                           @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                                           final PollPeriod pollPeriod) {
+        return new VaultSecretPredicates.RecoverableSecretStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    public static class VaultSecretPredicates {
+        public static class DeletedSecretStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            DeletedSecretStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean shouldBePresent) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        boolean present = false;
+                        checkNotNull(name, "name cannot be null");
+                        DeletedSecretBundle secret = api.getVaultApi(resourceGroup).getDeletedSecret(vaultUri, name);
+                        return shouldBePresent == (secret != null);
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+
+        public static class RecoverableSecretStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            RecoverableSecretStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isRecovered) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        checkNotNull(name, "name cannot be null");
+                        SecretBundle secret = api.getVaultApi(resourceGroup).getSecret(vaultUri, name, null);
+                        return secret != null ? (isRecovered ? true : secret.attributes().recoveryLevel().contains("Recoverable")) : false;
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+    }
+
+    @Provides
+    @Named(VAULT_CERTIFICATE_DELETE_STATUS)
+    protected VaultCertificatePredicates.DeletedCertificateStatusPredicateFactory provideDeletedCertificateStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                                                  @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                                                  final PollPeriod pollPeriod) {
+        return new VaultCertificatePredicates.DeletedCertificateStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(VAULT_CERTIFICATE_RECOVERABLE_STATUS)
+    protected VaultCertificatePredicates.RecoverableCertificateStatusPredicateFactory provideRecoverableCertificateStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                                                          @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                                                          final PollPeriod pollPeriod) {
+        return new VaultCertificatePredicates.RecoverableCertificateStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    @Provides
+    @Named(VAULT_CERTIFICATE_OPERATION_STATUS)
+    protected VaultCertificatePredicates.CertificateOperationStatusPredicateFactory provideCertificateOperationStatusPredicateFactory(final AzureComputeApi api,
+                                                                                                                                      @Named(OPERATION_TIMEOUT) Integer operationTimeout,
+                                                                                                                                      final PollPeriod pollPeriod) {
+        return new VaultCertificatePredicates.CertificateOperationStatusPredicateFactory(api, operationTimeout.longValue(), pollPeriod.pollInitialPeriod, pollPeriod.pollMaxPeriod);
+    }
+
+    public static class VaultCertificatePredicates {
+        public static class DeletedCertificateStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            DeletedCertificateStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean shouldBePresent) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        boolean present = false;
+                        checkNotNull(name, "name cannot be null");
+                        DeletedCertificateBundle cert = api.getVaultApi(resourceGroup).getDeletedCertificate(vaultUri, name);
+                        return shouldBePresent == (cert != null);
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+
+        public static class RecoverableCertificateStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            RecoverableCertificateStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isImport) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        checkNotNull(name, "name cannot be null");
+                        CertificateBundle cert = api.getVaultApi(resourceGroup).getCertificate(vaultUri, name, null);
+                        return cert != null ? (isImport ? true : cert.attributes().recoveryLevel().contains("Recoverable")) : false;
+
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+
+        public static class CertificateOperationStatusPredicateFactory {
+            private final AzureComputeApi api;
+            private final long operationTimeout;
+            private final long initialPeriod;
+            private final long maxPeriod;
+
+            CertificateOperationStatusPredicateFactory(final AzureComputeApi api, final long operationTimeout, final long initialPeriod, final long maxPeriod) {
+                this.api = checkNotNull(api, "api cannot be null");
+                this.operationTimeout = operationTimeout;
+                this.initialPeriod = initialPeriod;
+                this.maxPeriod = maxPeriod;
+            }
+
+            public Predicate<String> create(final String resourceGroup, final URI vaultUri, final boolean isCreate) {
+                checkNotNull(resourceGroup, "resourceGroup cannot be null");
+                checkNotNull(vaultUri, "vaultUri cannot be null");
+                return retry(new Predicate<String>() {
+                    @Override
+                    public boolean apply(final String name) {
+                        checkNotNull(name, "name cannot be null");
+                        boolean result = false;
+                        CertificateOperation certOp = api.getVaultApi(resourceGroup).getCertificateOperation(vaultUri, name);
+                        return isCreate ? ((certOp != null) ? !certOp.status().equals("inProgress") : false) : (certOp == null);
+                    }
+                }, operationTimeout, initialPeriod, maxPeriod);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java
index 2b07406..7c11642 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/domain/ResourceGroupAndNameAndIngressRules.java
@@ -18,6 +18,8 @@ package org.jclouds.azurecompute.arm.compute.domain;
 
 import static org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName.fromResourceGroupAndName;
 
+import java.util.Arrays;
+
 import com.google.auto.value.AutoValue;
 import com.google.common.base.Objects;
 
@@ -28,6 +30,7 @@ public abstract class ResourceGroupAndNameAndIngressRules {
    
    public abstract String location();
 
+   @SuppressWarnings("mutable")
    public abstract int[] inboundPorts();
 
    ResourceGroupAndNameAndIngressRules() {
@@ -37,7 +40,7 @@ public abstract class ResourceGroupAndNameAndIngressRules {
    public static ResourceGroupAndNameAndIngressRules create(String resourceGroup, String location, String name,
          int[] inboundPorts) {
       return new AutoValue_ResourceGroupAndNameAndIngressRules(fromResourceGroupAndName(resourceGroup, name), location,
-            inboundPorts);
+            Arrays.copyOf(inboundPorts, inboundPorts.length));
    }
 
    public String name() {

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
index d826a51..6cba2c4 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeImageExtension.java
@@ -30,8 +30,8 @@ import javax.annotation.Resource;
 
 import org.jclouds.Constants;
 import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.ImageAvailablePredicateFactory;
-import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.VirtualMachineInStatePredicateFactory;
+import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.ImageAvailablePredicateFactory;
+import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.VirtualMachineInStatePredicateFactory;
 import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName;
 import org.jclouds.azurecompute.arm.compute.functions.CustomImageToVMImage;
 import org.jclouds.azurecompute.arm.domain.IdReference;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java
index eaf820c..b31e2a0 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/extensions/AzureComputeSecurityGroupExtension.java
@@ -36,7 +36,7 @@ import javax.inject.Inject;
 import javax.inject.Named;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.SecurityGroupAvailablePredicateFactory;
+import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.SecurityGroupAvailablePredicateFactory;
 import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndName;
 import org.jclouds.azurecompute.arm.domain.NetworkInterfaceCard;
 import org.jclouds.azurecompute.arm.domain.NetworkProfile.NetworkInterface;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/loaders/CreateSecurityGroupIfNeeded.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/loaders/CreateSecurityGroupIfNeeded.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/loaders/CreateSecurityGroupIfNeeded.java
index 98732d2..baba6f9 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/loaders/CreateSecurityGroupIfNeeded.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/compute/loaders/CreateSecurityGroupIfNeeded.java
@@ -29,7 +29,7 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 
 import org.jclouds.azurecompute.arm.AzureComputeApi;
-import org.jclouds.azurecompute.arm.compute.config.AzureComputeServiceContextModule.SecurityGroupAvailablePredicateFactory;
+import org.jclouds.azurecompute.arm.compute.config.AzurePredicatesModule.SecurityGroupAvailablePredicateFactory;
 import org.jclouds.azurecompute.arm.compute.domain.ResourceGroupAndNameAndIngressRules;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroup;
 import org.jclouds.azurecompute.arm.domain.NetworkSecurityGroupProperties;

http://git-wip-us.apache.org/repos/asf/jclouds/blob/a2dee2f8/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
----------------------------------------------------------------------
diff --git a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
index 4ac5eaa..abe057d 100644
--- a/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
+++ b/providers/azurecompute-arm/src/main/java/org/jclouds/azurecompute/arm/config/AzureComputeProperties.java
@@ -34,4 +34,13 @@ public class AzureComputeProperties {
 
    public static final String API_VERSION_PREFIX = "jclouds.azurecompute.arm.apiversion.";
 
+   // Predicate constants
+   public static final String VAULT_DELETE_STATUS = "jclouds.azurecompute.arm.vault.delete_status";
+   public static final String VAULT_KEY_DELETED_STATUS = "jclouds.azurecompute.arm.vault.key.delete_status";
+   public static final String VAULT_KEY_RECOVERABLE_STATUS = "jclouds.azurecompute.arm.vault.key.recoverable_status";
+   public static final String VAULT_SECRET_DELETE_STATUS = "jclouds.azurecompute.arm.vault.secret.delete_status";
+   public static final String VAULT_SECRET_RECOVERABLE_STATUS = "jclouds.azurecompute.arm.vault.secret.recoverable_status";
+   public static final String VAULT_CERTIFICATE_DELETE_STATUS = "jclouds.azurecompute.arm.vault.certificate.delete_status";
+   public static final String VAULT_CERTIFICATE_RECOVERABLE_STATUS = "jclouds.azurecompute.arm.vault.certificate.recoverable_status";
+   public static final String VAULT_CERTIFICATE_OPERATION_STATUS = "jclouds.azurecompute.arm.vault.certificate.operation_status";
 }