diff --git a/README.md b/README.md index 844e65403..73dd01f88 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,21 @@ If you're not sure whether your OpenStack cloud uses Keystone V2 or V3 then you If you need a version of OpenStack to test against, get youself a copy of [DevStack](http://docs.openstack.org/developer/devstack/). +### Auto Retry Requests + +Failed requests can be handled to allow retries capability. + +One use case is to be able to resubmit request when facing network latency. + +By default auto retry is deactivated. +To activate auto retry set `idempotency` option to `true` + +The default values are: +- retry limit is 2 times +- retry interval is 5 seconds + +Those values can be overriden using `:retry_limit` and `:retry_interval` options. + ### Networking Gotcha Note that tenants (aka projects) in OpenStack usually require that you create a default gateway router in order to allow external access to your instances. diff --git a/lib/fog/openstack/baremetal.rb b/lib/fog/openstack/baremetal.rb index c1ba2e52e..ed1010ace 100644 --- a/lib/fog/openstack/baremetal.rb +++ b/lib/fog/openstack/baremetal.rb @@ -13,7 +13,8 @@ class Baremetal < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit ## MODELS # diff --git a/lib/fog/openstack/compute.rb b/lib/fog/openstack/compute.rb index 38bc5a2ed..54793360a 100644 --- a/lib/fog/openstack/compute.rb +++ b/lib/fog/openstack/compute.rb @@ -14,7 +14,8 @@ class Compute < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit ## MODELS # diff --git a/lib/fog/openstack/container_infra.rb b/lib/fog/openstack/container_infra.rb index 30a9f1e14..77718b767 100644 --- a/lib/fog/openstack/container_infra.rb +++ b/lib/fog/openstack/container_infra.rb @@ -14,7 +14,8 @@ class ContainerInfra < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/container_infra/models' diff --git a/lib/fog/openstack/core.rb b/lib/fog/openstack/core.rb index 86090e9ba..c5a7909f5 100644 --- a/lib/fog/openstack/core.rb +++ b/lib/fog/openstack/core.rb @@ -48,6 +48,14 @@ def initialize(options = {}) private def request(params, parse_json = true) + if @idempotent && @idempotent_verbs.include?(params[:method]) + params.merge!( + :idempotent => @idempotent, + :retry_limit => @retry_limit, + :retry_interval => @retry_interval + ) + end + retried = false begin authenticate! if @expires && (@expires - Time.now.utc).to_i < 60 @@ -172,6 +180,11 @@ def setup(options) instance_variable_set "@#{openstack_param}".to_sym, value end + @idempotent_verbs ||= %w(GET DELETE) + @idempotent ||= !!options[:idempotent] + @retry_interval ||= options[:retry_interval] || 5 # Seconds + @retry_limit ||= options[:retry_limit] || 2 + # Ensure OpenStack User's Password is always a String @openstack_api_key = @openstack_api_key.to_s if @openstack_api_key diff --git a/lib/fog/openstack/dns/v1.rb b/lib/fog/openstack/dns/v1.rb index 1788f37b4..70906c27c 100644 --- a/lib/fog/openstack/dns/v1.rb +++ b/lib/fog/openstack/dns/v1.rb @@ -14,7 +14,8 @@ class V1 < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl + :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl, + :idempotent, :retry_interval, :retry_limit request_path 'fog/openstack/dns/v1/requests' diff --git a/lib/fog/openstack/dns/v2.rb b/lib/fog/openstack/dns/v2.rb index 782ae0de0..305d920a7 100644 --- a/lib/fog/openstack/dns/v2.rb +++ b/lib/fog/openstack/dns/v2.rb @@ -16,7 +16,8 @@ class V2 < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl + :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/dns/v2/models' model :zone diff --git a/lib/fog/openstack/event.rb b/lib/fog/openstack/event.rb index b03b41593..4aaad3247 100644 --- a/lib/fog/openstack/event.rb +++ b/lib/fog/openstack/event.rb @@ -13,7 +13,8 @@ class Event < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/event/models' diff --git a/lib/fog/openstack/identity/v2.rb b/lib/fog/openstack/identity/v2.rb index 31efe3fad..cc9a29672 100644 --- a/lib/fog/openstack/identity/v2.rb +++ b/lib/fog/openstack/identity/v2.rb @@ -14,7 +14,8 @@ class V2 < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :no_path_prefix + :openstack_identity_api_version, :no_path_prefix, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/identity/v2/models' model :tenant diff --git a/lib/fog/openstack/identity/v3.rb b/lib/fog/openstack/identity/v3.rb index 3798b7c29..81b2c34b2 100644 --- a/lib/fog/openstack/identity/v3.rb +++ b/lib/fog/openstack/identity/v3.rb @@ -13,7 +13,8 @@ class V3 < Fog::Service :openstack_user_domain_id, :openstack_project_domain_id, :openstack_api_key, :openstack_current_user_id, :openstack_userid, :openstack_username, :current_user, :current_user_id, :current_tenant, - :provider, :openstack_identity_api_version, :openstack_cache_ttl + :provider, :openstack_identity_api_version, :openstack_cache_ttl, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/identity/v3/models' model :domain diff --git a/lib/fog/openstack/image/v1.rb b/lib/fog/openstack/image/v1.rb index 004677cd6..ea5e01171 100644 --- a/lib/fog/openstack/image/v1.rb +++ b/lib/fog/openstack/image/v1.rb @@ -16,7 +16,8 @@ class V1 < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/image/v1/models' diff --git a/lib/fog/openstack/image/v2.rb b/lib/fog/openstack/image/v2.rb index a2e641e77..fd470be9e 100644 --- a/lib/fog/openstack/image/v2.rb +++ b/lib/fog/openstack/image/v2.rb @@ -16,7 +16,8 @@ class V2 < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/image/v2/models' diff --git a/lib/fog/openstack/introspection.rb b/lib/fog/openstack/introspection.rb index 67430dd00..7f43ffeec 100644 --- a/lib/fog/openstack/introspection.rb +++ b/lib/fog/openstack/introspection.rb @@ -15,7 +15,8 @@ class Introspection < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit ## REQUESTS # diff --git a/lib/fog/openstack/key_manager.rb b/lib/fog/openstack/key_manager.rb index 5c411cc31..62d21bdff 100644 --- a/lib/fog/openstack/key_manager.rb +++ b/lib/fog/openstack/key_manager.rb @@ -13,7 +13,8 @@ class KeyManager < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl + :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl, + :idempotent, :retry_interval, :retry_limit ## MODELS diff --git a/lib/fog/openstack/metering.rb b/lib/fog/openstack/metering.rb index ab6d9c294..6466cb128 100644 --- a/lib/fog/openstack/metering.rb +++ b/lib/fog/openstack/metering.rb @@ -15,7 +15,8 @@ class Metering < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/metering/models' diff --git a/lib/fog/openstack/metric.rb b/lib/fog/openstack/metric.rb index 3feed8b09..c4ccd65f6 100644 --- a/lib/fog/openstack/metric.rb +++ b/lib/fog/openstack/metric.rb @@ -13,7 +13,8 @@ class Metric < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/metric/models' diff --git a/lib/fog/openstack/monitoring.rb b/lib/fog/openstack/monitoring.rb index 85f60452b..cee7eddb0 100644 --- a/lib/fog/openstack/monitoring.rb +++ b/lib/fog/openstack/monitoring.rb @@ -12,7 +12,8 @@ class Monitoring < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl + :openstack_identity_api_version, :openstack_temp_url_key, :openstack_cache_ttl, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/monitoring/models' model :metric diff --git a/lib/fog/openstack/network.rb b/lib/fog/openstack/network.rb index 10070d4d3..25593ce01 100644 --- a/lib/fog/openstack/network.rb +++ b/lib/fog/openstack/network.rb @@ -13,7 +13,8 @@ class Network < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit ## MODELS # diff --git a/lib/fog/openstack/nfv.rb b/lib/fog/openstack/nfv.rb index b0cd206fc..4c6052508 100644 --- a/lib/fog/openstack/nfv.rb +++ b/lib/fog/openstack/nfv.rb @@ -15,7 +15,8 @@ class NFV < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit ## REQUESTS # diff --git a/lib/fog/openstack/orchestration.rb b/lib/fog/openstack/orchestration.rb index 43f60569c..d4aaaf71d 100644 --- a/lib/fog/openstack/orchestration.rb +++ b/lib/fog/openstack/orchestration.rb @@ -11,7 +11,8 @@ class Orchestration < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/orchestration/models' model :stack diff --git a/lib/fog/openstack/planning.rb b/lib/fog/openstack/planning.rb index b9743c115..21e8902f3 100644 --- a/lib/fog/openstack/planning.rb +++ b/lib/fog/openstack/planning.rb @@ -13,7 +13,8 @@ class Planning < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit ## MODELS # diff --git a/lib/fog/openstack/shared_file_system.rb b/lib/fog/openstack/shared_file_system.rb index 1f70859de..f410b272d 100644 --- a/lib/fog/openstack/shared_file_system.rb +++ b/lib/fog/openstack/shared_file_system.rb @@ -14,7 +14,8 @@ class SharedFileSystem < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :openstack_shared_file_system_microversion + :openstack_identity_api_version, :openstack_shared_file_system_microversion, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/shared_file_system/models' model :network diff --git a/lib/fog/openstack/storage.rb b/lib/fog/openstack/storage.rb index c369f0753..77e375417 100644 --- a/lib/fog/openstack/storage.rb +++ b/lib/fog/openstack/storage.rb @@ -13,7 +13,8 @@ class Storage < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_cache_ttl, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version, :openstack_temp_url_key + :openstack_identity_api_version, :openstack_temp_url_key, + :idempotent, :retry_interval, :retry_limit model_path 'fog/openstack/storage/models' model :directory diff --git a/lib/fog/openstack/volume.rb b/lib/fog/openstack/volume.rb index 6fc49815c..4cbb0abe3 100644 --- a/lib/fog/openstack/volume.rb +++ b/lib/fog/openstack/volume.rb @@ -15,7 +15,8 @@ class Volume < Fog::Service :openstack_project_name, :openstack_project_id, :openstack_project_domain, :openstack_user_domain, :openstack_domain_name, :openstack_project_domain_id, :openstack_user_domain_id, :openstack_domain_id, - :openstack_identity_api_version] + :openstack_identity_api_version, + :idempotent, :retry_interval, :retry_limit] # Fog::OpenStack::Image.new() will return a Fog::OpenStack::Volume::V2 or a Fog::OpenStack::Volume::V1, # choosing the V2 by default, as V1 is deprecated since OpenStack Juno diff --git a/lib/fog/openstack/workflow/v2.rb b/lib/fog/openstack/workflow/v2.rb index 0aa747089..fa3f1840a 100644 --- a/lib/fog/openstack/workflow/v2.rb +++ b/lib/fog/openstack/workflow/v2.rb @@ -8,7 +8,8 @@ class V2 < Fog::Service requires :openstack_auth_url recognizes :openstack_username, :openstack_api_key, - :openstack_project_name, :openstack_domain_id + :openstack_project_name, :openstack_domain_id, + :idempotent, :retry_interval, :retry_limit ## REQUESTS #