From 08c5e47e37f29fdc8687aff442d660b390f8ef68 Mon Sep 17 00:00:00 2001 From: Josef Handl Date: Thu, 2 May 2024 15:31:29 +0200 Subject: [PATCH 1/4] Improve exception handling for enumerating Kubernetes resources --- kubespawner/reflector.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/kubespawner/reflector.py b/kubespawner/reflector.py index c0125410..7571ea9a 100644 --- a/kubespawner/reflector.py +++ b/kubespawner/reflector.py @@ -5,7 +5,7 @@ import time from functools import partial -from kubernetes_asyncio import watch +from kubernetes_asyncio import watch, client from traitlets import Any, Bool, Dict, Int, Unicode from traitlets.config import LoggingConfigurable from urllib3.exceptions import ReadTimeoutError @@ -228,7 +228,17 @@ async def _list_and_update(self, resource_version=None): kwargs["namespace"] = self.namespace list_method = getattr(self.api, self.list_method_name) + initial_resources_raw = await list_method(**kwargs) + if not initial_resources_raw.ok: + self.log.error(f'Error when calling Kubernetes API.' + f' Status: {initial_resources_raw.status} {initial_resources_raw.reason}.' + f' Message: {(await initial_resources_raw.json())["message"]}') + raise client.ApiException( + status=initial_resources_raw.status, + reason=initial_resources_raw.reason + ) + # This is an atomic operation on the dictionary! initial_resources = json.loads(await initial_resources_raw.read()) self.resources = { From a4fc6454e938108be5b7f9cc57c1ec1d4d302d1d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 3 May 2024 12:23:03 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- kubespawner/reflector.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/kubespawner/reflector.py b/kubespawner/reflector.py index 7571ea9a..c2794015 100644 --- a/kubespawner/reflector.py +++ b/kubespawner/reflector.py @@ -5,7 +5,7 @@ import time from functools import partial -from kubernetes_asyncio import watch, client +from kubernetes_asyncio import client, watch from traitlets import Any, Bool, Dict, Int, Unicode from traitlets.config import LoggingConfigurable from urllib3.exceptions import ReadTimeoutError @@ -231,12 +231,13 @@ async def _list_and_update(self, resource_version=None): initial_resources_raw = await list_method(**kwargs) if not initial_resources_raw.ok: - self.log.error(f'Error when calling Kubernetes API.' + self.log.error( + f'Error when calling Kubernetes API.' f' Status: {initial_resources_raw.status} {initial_resources_raw.reason}.' - f' Message: {(await initial_resources_raw.json())["message"]}') + f' Message: {(await initial_resources_raw.json())["message"]}' + ) raise client.ApiException( - status=initial_resources_raw.status, - reason=initial_resources_raw.reason + status=initial_resources_raw.status, reason=initial_resources_raw.reason ) # This is an atomic operation on the dictionary! From 0f2555dd6fd05591698246c0656d9a668c932d1b Mon Sep 17 00:00:00 2001 From: Josef Handl Date: Mon, 6 May 2024 10:58:55 +0200 Subject: [PATCH 3/4] Replace error log with exception log for K8s API exception handling --- kubespawner/reflector.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/kubespawner/reflector.py b/kubespawner/reflector.py index c2794015..192000a4 100644 --- a/kubespawner/reflector.py +++ b/kubespawner/reflector.py @@ -229,16 +229,18 @@ async def _list_and_update(self, resource_version=None): list_method = getattr(self.api, self.list_method_name) - initial_resources_raw = await list_method(**kwargs) - if not initial_resources_raw.ok: - self.log.error( - f'Error when calling Kubernetes API.' + try: + initial_resources_raw = await list_method(**kwargs) + if not initial_resources_raw.ok: + raise client.ApiException( + status=initial_resources_raw.status, + reason=initial_resources_raw.reason + ) + except client.ApiException: + self.log.exception(f'An error occurred when calling Kubernetes API.' f' Status: {initial_resources_raw.status} {initial_resources_raw.reason}.' - f' Message: {(await initial_resources_raw.json())["message"]}' - ) - raise client.ApiException( - status=initial_resources_raw.status, reason=initial_resources_raw.reason - ) + f' Message: {(await initial_resources_raw.json())["message"]}') + raise # This is an atomic operation on the dictionary! initial_resources = json.loads(await initial_resources_raw.read()) From 4fcd345e1b15d211d08b32536632677fff5bbbfe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 09:01:47 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- kubespawner/reflector.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/kubespawner/reflector.py b/kubespawner/reflector.py index 192000a4..c3271916 100644 --- a/kubespawner/reflector.py +++ b/kubespawner/reflector.py @@ -234,12 +234,14 @@ async def _list_and_update(self, resource_version=None): if not initial_resources_raw.ok: raise client.ApiException( status=initial_resources_raw.status, - reason=initial_resources_raw.reason + reason=initial_resources_raw.reason, ) except client.ApiException: - self.log.exception(f'An error occurred when calling Kubernetes API.' + self.log.exception( + f'An error occurred when calling Kubernetes API.' f' Status: {initial_resources_raw.status} {initial_resources_raw.reason}.' - f' Message: {(await initial_resources_raw.json())["message"]}') + f' Message: {(await initial_resources_raw.json())["message"]}' + ) raise # This is an atomic operation on the dictionary!