2424
2525_LOGGER = logging .getLogger ("spaceone" )
2626
27- _PAGE_SIZE = 7000
27+ _PAGE_SIZE = 5000
2828
2929
3030def azure_exception_handler (func ):
@@ -33,12 +33,23 @@ def wrapper(*args, **kwargs) -> Union[dict, list]:
3333 return_type = get_type_hints (func ).get ("return" )
3434 try :
3535 return func (* args , ** kwargs )
36+ except ServiceResponseError as error :
37+ _print_error_log (error )
38+ time .sleep (10 )
39+ return func (* args , ** kwargs )
40+
3641 except ResourceNotFoundError as error :
3742 _print_error_log (error )
3843 return _get_empty_value (return_type )
3944 except HttpResponseError as error :
4045 if error .status_code in ["404" , "412" ]:
4146 _print_error_log (error )
47+ elif error .status_code == "429" :
48+ _LOGGER .error (f"(RateLimit Error) => { error .message } " )
49+
50+ wait_time = _extract_wait_time_for_retry (error .message )
51+ time .sleep (wait_time )
52+ return func (* args , ** kwargs )
4253 else :
4354 _print_error_log (error )
4455 return _get_empty_value (return_type )
@@ -49,6 +60,17 @@ def wrapper(*args, **kwargs) -> Union[dict, list]:
4960 return wrapper
5061
5162
63+ def _extract_wait_time_for_retry (message : str ) -> int :
64+ default_wait_time = 60
65+ pattern = r"\d+"
66+
67+ matches = re .findall (pattern , message )
68+
69+ if len (matches ) > 1 :
70+ default_wait_time = int (matches [1 ])
71+ return default_wait_time
72+
73+
5274def _get_empty_value (return_type : object ) -> Any :
5375 return_type_name = getattr (return_type , "__name__" )
5476 empty_values = {
@@ -65,8 +87,9 @@ def _get_empty_value(return_type: object) -> Any:
6587 return empty_values .get (return_type_name , None )
6688
6789
68- def _print_error_log (error ):
69- _LOGGER .error (f"(Error) => { error .message } { error } " , exc_info = True )
90+ def _print_error_log (error ) -> None :
91+ status_code = getattr (error , "status_code" , "Unknown" )
92+ _LOGGER .error (f"(Error) => { status_code } { error .message } { error } " , exc_info = True )
7093
7194
7295class AzureCostMgmtConnector (BaseConnector ):
@@ -154,11 +177,9 @@ def query_usage_http(
154177 BENEFIT_GROUPING + BENEFIT_GROUPING_MCA
155178 )
156179
157- _LOGGER .debug (f"[query_usage] parameters: { parameters } " )
158-
159180 while self .next_link :
160181 url = self .next_link
161- headers = self ._make_request_headers ()
182+ headers = self ._make_request_headers (secret_data )
162183
163184 _LOGGER .debug (f"[query_usage] url:{ url } , parameters: { parameters } " )
164185 response = requests .post (url = url , headers = headers , json = parameters )
@@ -298,8 +319,8 @@ def convert_nested_dictionary(self, cloud_svc_object):
298319
299320 return cloud_svc_dict
300321
301- def _make_request_headers (self , client_type = None ):
302- access_token = self ._get_access_token ()
322+ def _make_request_headers (self , secret_data : dict , client_type = None ):
323+ access_token = self ._get_access_token (secret_data )
303324 headers = {
304325 "Authorization" : f"Bearer { access_token } " ,
305326 "Content-Type" : "application/json" ,
@@ -311,7 +332,7 @@ def _make_request_headers(self, client_type=None):
311332
312333 def _retry_request (self , response , url , headers , json , retry_count , method = "post" ):
313334 try :
314- _LOGGER .error (f"{ datetime . utcnow () } [INFO] retry_request { response .headers } " )
335+ _LOGGER .error (f"[INFO] retry_request { response .headers } " )
315336 if retry_count == 0 :
316337 raise ERROR_UNKNOWN (
317338 message = f"[ERROR] retry_request failed { response .json ()} "
@@ -366,12 +387,26 @@ def _get_sleep_time(response_headers):
366387 return sleep_time + 1
367388
368389 @staticmethod
369- def _get_access_token () :
390+ def _get_access_token (secret_data : dict ) -> str :
370391 try :
371- credential = DefaultAzureCredential (logging_enable = True )
372- scopes = ["https://management.azure.com/.default" ]
373- token_info = credential .get_token (* scopes )
374- return token_info .token
392+ header = {
393+ "Content-Type" : "application/x-www-form-urlencoded" ,
394+ }
395+ data = {
396+ "client_id" : secret_data ["client_id" ],
397+ "client_secret" : secret_data ["client_secret" ],
398+ "grant_type" : "client_credentials" ,
399+ "resource" : "https://management.azure.com" ,
400+ "scope" : "https://management.azure.com/.default" ,
401+ }
402+
403+ response = requests .post (
404+ f"https://login.microsoftonline.com/{ secret_data ['tenant_id' ]} /oauth2/token" ,
405+ data = data ,
406+ headers = header ,
407+ )
408+ access_token = response .json ().get ("access_token" )
409+ return access_token
375410 except Exception as e :
376411 _LOGGER .error (f"[ERROR] _get_access_token :{ e } " )
377412 raise ERROR_INVALID_TOKEN (token = e )
0 commit comments