Skip to content

Commit 8e544d8

Browse files
If looking up a resource type fails bypass the cache (#669)
1 parent 02fe61a commit 8e544d8

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

kr8s/_api.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,16 @@ async def lookup_kind(self, kind) -> tuple[str, str, bool]:
341341
"""
342342
return await self.async_lookup_kind(kind)
343343

344-
async def async_lookup_kind(self, kind) -> tuple[str, str, bool]:
344+
async def async_lookup_kind(
345+
self, kind, skip_cache: bool = False
346+
) -> tuple[str, str, bool]:
345347
"""Lookup a Kubernetes resource kind."""
346348
from ._objects import parse_kind
347349

348-
resources = await self.async_api_resources()
350+
if skip_cache:
351+
resources = await self.async_api_resources_uncached()
352+
else:
353+
resources = await self.async_api_resources()
349354
kind, group, version = parse_kind(kind)
350355
if group:
351356
version = f"{group}/{version}"
@@ -367,6 +372,10 @@ async def async_lookup_kind(self, kind) -> tuple[str, str, bool]:
367372
resource["name"],
368373
resource["namespaced"],
369374
)
375+
376+
if not skip_cache:
377+
return await self.async_lookup_kind(kind, skip_cache=True)
378+
370379
raise ValueError(f"Kind {kind} not found.")
371380

372381
@contextlib.asynccontextmanager
@@ -635,6 +644,9 @@ async def api_resources(self) -> list[dict]:
635644
# https://github.com/kubernetes/cli-runtime/blob/980bedf450ab21617b33d68331786942227fe93a/pkg/genericclioptions/config_flags.go#L297
636645
@cached(TTLCache(1, 60 * 60 * 6))
637646
async def async_api_resources(self) -> list[dict]:
647+
return await self.async_api_resources_uncached()
648+
649+
async def async_api_resources_uncached(self) -> list[dict]:
638650
"""Get the Kubernetes API resources."""
639651
resources = []
640652
async with self.call_api(method="GET", version="", base="/api") as response:

kr8s/tests/test_api.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# SPDX-License-Identifier: BSD 3-Clause License
33
import queue
44
import threading
5+
from contextlib import asynccontextmanager
56
from unittest.mock import AsyncMock
67

78
import anyio
@@ -18,14 +19,36 @@
1819

1920
@pytest.fixture
2021
async def example_crd(example_crd_spec):
21-
example = await kr8s.asyncio.objects.CustomResourceDefinition(example_crd_spec)
22+
async with create_delete_crd(example_crd_spec) as example:
23+
yield example
24+
25+
26+
@asynccontextmanager
27+
async def create_delete_crd(spec):
28+
example = await kr8s.asyncio.objects.CustomResourceDefinition(spec)
29+
30+
# Clean up any existing CRD if it exists from a previous failed test run
31+
if await example.exists():
32+
await example.delete()
33+
while await example.exists():
34+
await anyio.sleep(0.1)
35+
36+
# Create the CRD
2237
if not await example.exists():
2338
await example.create()
39+
while not await example.exists():
40+
await anyio.sleep(0.1)
41+
42+
# Check that the CRD gets returned
2443
assert example in [
2544
crd async for crd in kr8s.asyncio.get("customresourcedefinitions")
2645
]
2746
yield example
47+
48+
# Clean up the CRD
2849
await example.delete()
50+
while await example.exists():
51+
await anyio.sleep(0.1)
2952

3053

3154
async def test_factory_bypass() -> None:
@@ -497,3 +520,15 @@ async def test_bad_kubernetes_version():
497520
with pytest.warns(UserWarning):
498521
await api._check_version()
499522
api.async_version = keep
523+
524+
525+
async def test_crd_caching(example_crd_spec):
526+
api = await kr8s.asyncio.api()
527+
528+
# Populate the cache
529+
[r async for r in api.get("pods")]
530+
531+
# Register a new CRD
532+
async with create_delete_crd(example_crd_spec) as example_crd:
533+
# Try to get the new CRD (which isn't in the cache, so the cache should be bypassed)
534+
[r async for r in api.get(example_crd.name)]

0 commit comments

Comments
 (0)