26
26
import time
27
27
import typing
28
28
29
+ from kmip .core import enums as kmip_enums # type: ignore[import]
29
30
from kmip .pie .client import ProxyKmipClient # type: ignore[import]
30
- from kmip .pie .client import enums as kmip_enums
31
+ from kmip .pie .exceptions import KmipOperationFailure # type: ignore[import]
31
32
32
- from sambacc .varlink .keybridge import EntryKind , ScopeInfo
33
+ from sambacc .varlink .keybridge import (
34
+ EntryKind ,
35
+ EntryNotFoundError ,
36
+ OpKind ,
37
+ OperationFailed ,
38
+ ScopeInfo ,
39
+ )
33
40
34
41
35
42
_logger = logging .getLogger (__name__ )
@@ -142,6 +149,44 @@ def _prune(self) -> None:
142
149
len (self ._kmip_cache ),
143
150
)
144
151
152
+ @contextlib .contextmanager
153
+ def _handle_kmip_error (
154
+ self , op : OpKind , key : str
155
+ ) -> typing .Iterator [None ]:
156
+ """Catch exceptions from KMIP libs and turn them into something
157
+ more reasonable for a keybridge client.
158
+ """
159
+ try :
160
+ yield
161
+ except OSError as err :
162
+ _logger .warning ("KMIP connection failed: %s" , err )
163
+ raise OperationFailed (
164
+ op = op .value ,
165
+ name = key ,
166
+ scope = self .name (),
167
+ status = "KMIP_CONNECTION_FAILED" ,
168
+ reason = str (err ),
169
+ )
170
+ except KmipOperationFailure as kmip_err :
171
+ _logger .debug ("KMIP operation failure: %s" , kmip_err )
172
+ reason = getattr (kmip_err , "reason" , None )
173
+ if (
174
+ reason is kmip_enums .ResultReason .ITEM_NOT_FOUND
175
+ or reason is kmip_enums .ResultReason .PERMISSION_DENIED
176
+ ):
177
+ raise EntryNotFoundError (
178
+ name = key ,
179
+ scope = self .name (),
180
+ ) from kmip_err
181
+ _logger .warning ("unexpected KMIP operation failure: %s" , kmip_err )
182
+ raise OperationFailed (
183
+ op = op .value ,
184
+ name = key ,
185
+ scope = self .name (),
186
+ status = "KMIP_OPERATION_FAILED" ,
187
+ reason = str (kmip_err ),
188
+ ) from kmip_err
189
+
145
190
def get (self , key : str , kind : EntryKind ) -> str :
146
191
"""Get a value associated with the given key from the KMIP server or
147
192
cache. If entry kind is B64 the (typically) binary data will be base64
@@ -153,9 +198,9 @@ def get(self, key: str, kind: EntryKind) -> str:
153
198
if key in cache :
154
199
_logger .debug ("KMIP cache hit: %r" , key )
155
200
return _format (cache [key ].value , kind )
156
-
157
- with self ._client () as client :
158
- result = client .get (key )
201
+ with self . _handle_kmip_error ( OpKind . GET , key ):
202
+ with self ._client () as client :
203
+ result = client .get (key )
159
204
_logger .debug ("KMIP result for: %r" , key )
160
205
with self ._cache () as cache :
161
206
cache [key ] = _Value (result .value , created = self ._timestamp ())
0 commit comments