44from abc import ABC , abstractmethod
55from typing import List , MutableMapping , Optional , Any , Union , Dict
66
7- from attr import define
7+ from attr import define , field
88from retrying import retry
99from azure .core .exceptions import (
1010 ClientAuthenticationError ,
2121from azure .mgmt .resource .resources .models import GenericResource
2222
2323from fix_plugin_azure .config import AzureCredentials
24+ from fixlib .core .actions import CoreFeedback , ErrorAccumulator
2425from fixlib .types import Json
2526
2627log = logging .getLogger ("fix.plugins.azure" )
@@ -55,6 +56,7 @@ class AzureApiSpec:
5556 query_parameters : List [str ] = []
5657 access_path : Optional [str ] = None
5758 expect_array : bool = False
59+ expected_error_codes : List [str ] = field (factory = list )
5860
5961
6062class AzureClient (ABC ):
@@ -82,9 +84,13 @@ def delete_resource_tag(self, tag_name: str, resource_id: str) -> bool:
8284 def __create_management_client (
8385 credential : AzureCredentials ,
8486 subscription_id : str ,
87+ core_feedback : Optional [CoreFeedback ] = None ,
88+ error_accumulator : Optional [ErrorAccumulator ] = None ,
8589 resource_group : Optional [str ] = None ,
8690 ) -> AzureClient :
87- return AzureResourceManagementClient (credential , subscription_id , resource_group )
91+ return AzureResourceManagementClient (
92+ credential , subscription_id , resource_group , core_feedback , error_accumulator
93+ )
8894
8995 create = __create_management_client
9096
@@ -95,10 +101,14 @@ def __init__(
95101 credential : AzureCredentials ,
96102 subscription_id : str ,
97103 location : Optional [str ] = None ,
104+ core_feedback : Optional [CoreFeedback ] = None ,
105+ accumulator : Optional [ErrorAccumulator ] = None ,
98106 ) -> None :
99107 self .credential = credential
100108 self .subscription_id = subscription_id
101109 self .location = location
110+ self .core_feedback = core_feedback
111+ self .accumulator = accumulator or ErrorAccumulator ()
102112 self .client = ResourceManagementClient (self .credential , self .subscription_id )
103113
104114 def list (self , spec : AzureApiSpec , ** kwargs : Any ) -> List [Json ]:
@@ -175,10 +185,14 @@ def _list_with_retry(self, spec: AzureApiSpec, **kwargs: Any) -> Optional[List[J
175185 if error := e .error :
176186 if error .code == "NoRegisteredProviderFound" :
177187 return None # API not available in this region
188+ elif error .code in spec .expected_error_codes :
189+ return None
178190 elif error .code == "BadRequest" and spec .service == "metric" :
179191 raise MetricRequestError from e
180- log .warning (f"[Azure] Error encountered while requesting resource: { e } " )
181- raise e
192+ code = error .code or "Unknown"
193+ self .accumulator .add_error (False , code , spec .service , spec .path , str (e ), self .location )
194+ log .warning (f"[Azure] Client Error: status={ e .status_code } , error={ e .error } , message={ e } " )
195+ return None
182196 except Exception as e :
183197 log .warning (f"[Azure] called service={ spec .service } : hit unexpected error: { e } " , exc_info = e )
184198 return None
@@ -271,4 +285,4 @@ def _make_request(self, url: str, params: MutableMapping[str, Any], headers: Mut
271285 return response
272286
273287 def for_location (self , location : str ) -> AzureClient :
274- return AzureClient .create (self .credential , self .subscription_id , location )
288+ return AzureClient .create (self .credential , self .subscription_id , self . core_feedback , self . accumulator , location )
0 commit comments