Skip to content

Commit bc1cdab

Browse files
phlogistonjohnmergify[bot]
authored andcommitted
kmip: add general kmip error handling when getting keys
Add a new context manager that converts exceptions from KMIP and converts them into something keybridge friendly(er). Signed-off-by: John Mulligan <[email protected]>
1 parent 39fcbe9 commit bc1cdab

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

sambacc/kmip/scope.py

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,17 @@
2626
import time
2727
import typing
2828

29+
from kmip.core import enums as kmip_enums # type: ignore[import]
2930
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]
3132

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+
)
3340

3441

3542
_logger = logging.getLogger(__name__)
@@ -142,6 +149,44 @@ def _prune(self) -> None:
142149
len(self._kmip_cache),
143150
)
144151

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+
145190
def get(self, key: str, kind: EntryKind) -> str:
146191
"""Get a value associated with the given key from the KMIP server or
147192
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:
153198
if key in cache:
154199
_logger.debug("KMIP cache hit: %r", key)
155200
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)
159204
_logger.debug("KMIP result for: %r", key)
160205
with self._cache() as cache:
161206
cache[key] = _Value(result.value, created=self._timestamp())

0 commit comments

Comments
 (0)