diff --git a/changelogs/fragments/60529-vultry_retry_backoff.yml b/changelogs/fragments/60529-vultry_retry_backoff.yml new file mode 100644 index 00000000000..2290043a1fa --- /dev/null +++ b/changelogs/fragments/60529-vultry_retry_backoff.yml @@ -0,0 +1,2 @@ +minor_changes: + - vultr - the retry on failure functionality was changed to use an exponential backoff behaviour. diff --git a/lib/ansible/module_utils/vultr.py b/lib/ansible/module_utils/vultr.py index 5fa903f444e..b047c939bad 100644 --- a/lib/ansible/module_utils/vultr.py +++ b/lib/ansible/module_utils/vultr.py @@ -7,6 +7,7 @@ __metaclass__ = type import os import time +import random import urllib from ansible.module_utils.six.moves import configparser from ansible.module_utils._text import to_text, to_native @@ -22,6 +23,7 @@ def vultr_argument_spec(): api_key=dict(type='str', default=os.environ.get('VULTR_API_KEY'), no_log=True), api_timeout=dict(type='int', default=os.environ.get('VULTR_API_TIMEOUT')), api_retries=dict(type='int', default=os.environ.get('VULTR_API_RETRIES')), + api_retry_max_delay=dict(type='int', default=os.environ.get('VULTR_API_RETRY_MAX_DELAY')), api_account=dict(type='str', default=os.environ.get('VULTR_API_ACCOUNT') or 'default'), api_endpoint=dict(type='str', default=os.environ.get('VULTR_API_ENDPOINT')), validate_certs=dict(type='bool', default=True), @@ -59,6 +61,7 @@ class Vultr: 'api_key': self.module.params.get('api_key') or config.get('key'), 'api_timeout': self.module.params.get('api_timeout') or int(config.get('timeout') or 60), 'api_retries': self.module.params.get('api_retries') or int(config.get('retries') or 5), + 'api_retry_max_delay': self.module.params.get('api_retries') or int(config.get('retry_max_delay') or 12), 'api_endpoint': self.module.params.get('api_endpoint') or config.get('endpoint') or VULTR_API_ENDPOINT, } except ValueError as e: @@ -74,6 +77,7 @@ class Vultr: 'api_account': self.module.params.get('api_account'), 'api_timeout': self.api_config['api_timeout'], 'api_retries': self.api_config['api_retries'], + 'api_retry_max_delay': self.api_config['api_retry_max_delay'], 'api_endpoint': self.api_config['api_endpoint'], } @@ -85,7 +89,7 @@ class Vultr: } def read_env_variables(self): - keys = ['key', 'timeout', 'retries', 'endpoint'] + keys = ['key', 'timeout', 'retries', 'retry_max_delay', 'endpoint'] env_conf = {} for key in keys: if 'VULTR_API_%s' % key.upper() not in os.environ: @@ -159,7 +163,10 @@ class Vultr: except AttributeError: data = urllib.parse.urlencode(data_encoded) + data_list - for s in range(0, self.api_config['api_retries']): + retry_max_delay = self.api_config['api_retry_max_delay'] + randomness = random.randint(0, 1000) / 1000.0 + + for retry in range(0, self.api_config['api_retries']): response, info = fetch_url( module=self.module, url=url, @@ -173,7 +180,11 @@ class Vultr: break # Vultr has a rate limiting requests per second, try to be polite - time.sleep(1) + # Use exponential backoff plus a little bit of randomness + delay = 2 ** retry + randomness + if delay > retry_max_delay: + delay = retry_max_delay + randomness + time.sleep(delay) else: self.fail_json(msg="Reached API retries limit %s for URL %s, method %s with data %s. Returned %s, with body: %s %s" % ( diff --git a/lib/ansible/modules/cloud/vultr/_vultr_account_facts.py b/lib/ansible/modules/cloud/vultr/_vultr_account_facts.py index fd1aaf7c611..c814291e3f0 100644 --- a/lib/ansible/modules/cloud/vultr/_vultr_account_facts.py +++ b/lib/ansible/modules/cloud/vultr/_vultr_account_facts.py @@ -58,6 +58,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/_vultr_block_storage_facts.py b/lib/ansible/modules/cloud/vultr/_vultr_block_storage_facts.py index 0e28b2b6b32..2da66d16976 100644 --- a/lib/ansible/modules/cloud/vultr/_vultr_block_storage_facts.py +++ b/lib/ansible/modules/cloud/vultr/_vultr_block_storage_facts.py @@ -57,6 +57,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/_vultr_os_facts.py b/lib/ansible/modules/cloud/vultr/_vultr_os_facts.py index 961490d72fb..d0a001b0ec4 100644 --- a/lib/ansible/modules/cloud/vultr/_vultr_os_facts.py +++ b/lib/ansible/modules/cloud/vultr/_vultr_os_facts.py @@ -58,6 +58,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/_vultr_ssh_key_facts.py b/lib/ansible/modules/cloud/vultr/_vultr_ssh_key_facts.py index f325b03654d..c41df237316 100644 --- a/lib/ansible/modules/cloud/vultr/_vultr_ssh_key_facts.py +++ b/lib/ansible/modules/cloud/vultr/_vultr_ssh_key_facts.py @@ -58,6 +58,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/_vultr_user_facts.py b/lib/ansible/modules/cloud/vultr/_vultr_user_facts.py index b27ab4bbbcf..59095889ae9 100644 --- a/lib/ansible/modules/cloud/vultr/_vultr_user_facts.py +++ b/lib/ansible/modules/cloud/vultr/_vultr_user_facts.py @@ -57,6 +57,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_account_info.py b/lib/ansible/modules/cloud/vultr/vultr_account_info.py index 22d4dc1dcb5..a9b15f7ce68 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_account_info.py +++ b/lib/ansible/modules/cloud/vultr/vultr_account_info.py @@ -54,6 +54,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_block_storage.py b/lib/ansible/modules/cloud/vultr/vultr_block_storage.py index b17cb924c5b..c1cb5f41d1d 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_block_storage.py +++ b/lib/ansible/modules/cloud/vultr/vultr_block_storage.py @@ -78,6 +78,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_block_storage_info.py b/lib/ansible/modules/cloud/vultr/vultr_block_storage_info.py index 7ad74709a3f..2466112de30 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_block_storage_info.py +++ b/lib/ansible/modules/cloud/vultr/vultr_block_storage_info.py @@ -57,6 +57,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_dns_domain.py b/lib/ansible/modules/cloud/vultr/vultr_dns_domain.py index 985f13cbf23..9f27671d2b6 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_dns_domain.py +++ b/lib/ansible/modules/cloud/vultr/vultr_dns_domain.py @@ -74,6 +74,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_dns_domain_facts.py b/lib/ansible/modules/cloud/vultr/vultr_dns_domain_facts.py index 58c4706ed01..3a1872ab7fb 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_dns_domain_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_dns_domain_facts.py @@ -53,6 +53,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_dns_record.py b/lib/ansible/modules/cloud/vultr/vultr_dns_record.py index d341c8c286b..1aec81f60b3 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_dns_record.py +++ b/lib/ansible/modules/cloud/vultr/vultr_dns_record.py @@ -139,6 +139,22 @@ vultr_api: returned: success type: int sample: 60 + api_retries: + description: Amount of max retries for the API requests + returned: success + type: int + sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' + api_endpoint: + description: Endpoint used for the API requests + returned: success + type: str + sample: "https://api.vultr.com" vultr_dns_record: description: Response from Vultr API returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_firewall_group.py b/lib/ansible/modules/cloud/vultr/vultr_firewall_group.py index 51cd123cb82..a015e305248 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_firewall_group.py +++ b/lib/ansible/modules/cloud/vultr/vultr_firewall_group.py @@ -68,6 +68,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_firewall_group_facts.py b/lib/ansible/modules/cloud/vultr/vultr_firewall_group_facts.py index 44f900d50c9..279b4e7d0d5 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_firewall_group_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_firewall_group_facts.py @@ -53,6 +53,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_firewall_rule.py b/lib/ansible/modules/cloud/vultr/vultr_firewall_rule.py index c1fc9cdd10b..bc6f313d345 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_firewall_rule.py +++ b/lib/ansible/modules/cloud/vultr/vultr_firewall_rule.py @@ -116,6 +116,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_network.py b/lib/ansible/modules/cloud/vultr/vultr_network.py index df01b4c43a1..9d373b8bf28 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_network.py +++ b/lib/ansible/modules/cloud/vultr/vultr_network.py @@ -76,6 +76,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_network_facts.py b/lib/ansible/modules/cloud/vultr/vultr_network_facts.py index 2977f4ed560..eba45254a49 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_network_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_network_facts.py @@ -53,6 +53,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_os_info.py b/lib/ansible/modules/cloud/vultr/vultr_os_info.py index d6dc3f2f1bb..60c95bc6abf 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_os_info.py +++ b/lib/ansible/modules/cloud/vultr/vultr_os_info.py @@ -57,6 +57,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_plan_facts.py b/lib/ansible/modules/cloud/vultr/vultr_plan_facts.py index 9366c0c1d2b..75fe03e67e3 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_plan_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_plan_facts.py @@ -54,6 +54,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_region_facts.py b/lib/ansible/modules/cloud/vultr/vultr_region_facts.py index f3112972048..93738639b06 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_region_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_region_facts.py @@ -54,6 +54,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_server.py b/lib/ansible/modules/cloud/vultr/vultr_server.py index 1762ff0c711..e1a1ce36bfb 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_server.py +++ b/lib/ansible/modules/cloud/vultr/vultr_server.py @@ -184,6 +184,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_server_facts.py b/lib/ansible/modules/cloud/vultr/vultr_server_facts.py index b94ef87c54d..11e39f0ee8c 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_server_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_server_facts.py @@ -54,6 +54,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_ssh_key.py b/lib/ansible/modules/cloud/vultr/vultr_ssh_key.py index 134adbd53d9..b3d681e12cb 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_ssh_key.py +++ b/lib/ansible/modules/cloud/vultr/vultr_ssh_key.py @@ -73,6 +73,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_ssh_key_info.py b/lib/ansible/modules/cloud/vultr/vultr_ssh_key_info.py index 6abda518d57..282b484a130 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_ssh_key_info.py +++ b/lib/ansible/modules/cloud/vultr/vultr_ssh_key_info.py @@ -58,6 +58,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_startup_script.py b/lib/ansible/modules/cloud/vultr/vultr_startup_script.py index 228e8cf0dd5..0f5bf5a44ed 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_startup_script.py +++ b/lib/ansible/modules/cloud/vultr/vultr_startup_script.py @@ -86,6 +86,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_startup_script_facts.py b/lib/ansible/modules/cloud/vultr/vultr_startup_script_facts.py index cc41da43d12..65cb78ca105 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_startup_script_facts.py +++ b/lib/ansible/modules/cloud/vultr/vultr_startup_script_facts.py @@ -54,6 +54,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_user.py b/lib/ansible/modules/cloud/vultr/vultr_user.py index 3657782b05d..f1373b2bd50 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_user.py +++ b/lib/ansible/modules/cloud/vultr/vultr_user.py @@ -113,6 +113,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/modules/cloud/vultr/vultr_user_info.py b/lib/ansible/modules/cloud/vultr/vultr_user_info.py index 6675febc15e..d8435206ca6 100644 --- a/lib/ansible/modules/cloud/vultr/vultr_user_info.py +++ b/lib/ansible/modules/cloud/vultr/vultr_user_info.py @@ -57,6 +57,12 @@ vultr_api: returned: success type: int sample: 5 + api_retry_max_delay: + description: Exponential backoff delay in seconds between retries up to this max delay value. + returned: success + type: int + sample: 12 + version_added: '2.9' api_endpoint: description: Endpoint used for the API requests returned: success diff --git a/lib/ansible/plugins/doc_fragments/vultr.py b/lib/ansible/plugins/doc_fragments/vultr.py index eb9fd42aef5..c6ae7039687 100644 --- a/lib/ansible/plugins/doc_fragments/vultr.py +++ b/lib/ansible/plugins/doc_fragments/vultr.py @@ -26,6 +26,13 @@ options: - The ENV variable C(VULTR_API_RETRIES) is used as default, when defined. - Fallback value is 5 retries if not specified. type: int + api_retry_max_delay: + description: + - Retry backoff delay in seconds is exponential up to this max. value, in seconds. + - The ENV variable C(VULTR_API_RETRY_MAX_DELAY) is used as default, when defined. + - Fallback value is 12 seconds. + type: int + version_added: '2.9' api_account: description: - Name of the ini section in the C(vultr.ini) file.