Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 25 additions & 17 deletions comanage_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import os
import re
import sys
import json
import time
import exceptions
import urllib.error
import urllib.request
from ldap3 import Server, Connection, ALL, ALL_ATTRIBUTES, SAFE_SYNC
Expand All @@ -26,10 +27,9 @@
TEST_UNIX_CLUSTER_ID = 10
TEST_LDAP_TARGET_ID = 9


MIN_TIMEOUT = 5
MAX_TIMEOUT = 625
TIMEOUTMULTIPLE = 5
# Value for the base of the exponential backoff
TIMEOUT_BASE = 5
MAX_RETRIES = 5


GET = "GET"
Expand Down Expand Up @@ -81,22 +81,30 @@ def call_api2(method, target, endpoint, authstr, **kw):

def call_api3(method, target, data, endpoint, authstr, **kw):
req = mkrequest(method, target, data, endpoint, authstr, **kw)
trying = True
currentTimeout = MIN_TIMEOUT
while trying:
retries = 0
current_timeout = TIMEOUT_BASE
total_timeout = 0
payload = None
while retries <= MAX_RETRIES:
try:
resp = urllib.request.urlopen(req, timeout=currentTimeout)
resp = urllib.request.urlopen(req, timeout=current_timeout)
payload = resp.read()
trying = False
except urllib.error.URLError as exception:
if currentTimeout < MAX_TIMEOUT:
currentTimeout *= TIMEOUTMULTIPLE
else:
sys.exit(
f"Exception raised after maximum number of retries and/or timeout {MAX_TIMEOUT} seconds reached. "
+ f"Exception reason: {exception.reason}.\n Request: {req.full_url}"
break
# exception catching, mainly for request timeouts and "Service Temporarily Unavailable" (Rate limiting).
except urllib.error.HTTPError as exception:
if retries >= MAX_RETRIES:
raise exceptions.URLRequestError(
"Exception raised after maximum number of retries reached after total backoff of " +
f"{total_timeout} seconds. Retries: {retries}. "
+ f"Exception reason: {exception}.\n Request: {req.full_url}"
)

print("waiting for seconds: " + str(current_timeout))
time.sleep(current_timeout)
total_timeout += current_timeout
current_timeout *= TIMEOUT_BASE
retries += 1

return json.loads(payload) if payload else None


Expand Down
11 changes: 11 additions & 0 deletions exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
""" Exceptions used in configuration script """


class Error(Exception):
"""Base exception class for all exceptions defined"""
pass


class URLRequestError(Error):
"""Class for exceptions due to not being able to fulfill a URLRequest"""
pass
Loading