Skip to content

Commit 2ea5ad3

Browse files
[release-0.8] When searching for resources, prefer non-List matches (#232)
* Fixes #229: When searching for resources, prefer non-List matches Signed-off-by: Fabian von Feilitzsch <[email protected]> * add unit test for resource searching behavior Signed-off-by: Fabian von Feilitzsch <[email protected]>
1 parent 828de7d commit 2ea5ad3

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

openshift/dynamic/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,10 +517,14 @@ def get(self, **kwargs):
517517
on api_version, that resource will be returned.
518518
"""
519519
results = self.search(**kwargs)
520+
# If there are multiple matches, prefer exact matches on api_version
520521
if len(results) > 1 and kwargs.get('api_version'):
521522
results = [
522523
result for result in results if result.group_version == kwargs['api_version']
523524
]
525+
# If there are multiple matches, prefer non-List kinds
526+
if len(results) > 1 and not all([isinstance(x, ResourceList) for x in results]):
527+
results = [result for result in results if not isinstance(result, ResourceList)]
524528
if len(results) == 1:
525529
return results[0]
526530
elif not results:
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import pytest
2+
3+
from kubernetes.client import ApiClient
4+
5+
from openshift.dynamic import DynamicClient, Resource, ResourceList
6+
7+
8+
@pytest.fixture(scope='module')
9+
def mock_namespace():
10+
return Resource(
11+
api_version='v1',
12+
kind='Namespace',
13+
name='namespaces',
14+
namespaced=False,
15+
preferred=True,
16+
prefix='api',
17+
shorter_names=['ns'],
18+
shortNames=['ns'],
19+
singularName='namespace',
20+
verbs=['create', 'delete', 'get', 'list', 'patch', 'update', 'watch']
21+
)
22+
23+
24+
@pytest.fixture(scope='module')
25+
def mock_namespace_list(mock_namespace):
26+
return ResourceList(mock_namespace)
27+
28+
@pytest.fixture(scope='function', autouse=True)
29+
def setup_client_monkeypatch(monkeypatch, mock_namespace, mock_namespace_list):
30+
31+
def mock_load_server_info(self):
32+
self.__version = {'kubernetes': 'mock-k8s-version'}
33+
34+
def mock_parse_api_groups(self):
35+
return {
36+
'api': {
37+
'': {
38+
'v1': {
39+
'Namespace': mock_namespace,
40+
'NamespaceList': mock_namespace_list
41+
}
42+
}
43+
}
44+
}
45+
46+
monkeypatch.setattr(DynamicClient, '_load_server_info', mock_load_server_info)
47+
monkeypatch.setattr(DynamicClient, 'parse_api_groups', mock_parse_api_groups)
48+
49+
50+
@pytest.fixture()
51+
def client():
52+
return DynamicClient(ApiClient())
53+
54+
55+
@pytest.mark.parametrize(("attribute", "value"), [
56+
('name', 'namespaces'),
57+
('singular_name', 'namespace'),
58+
('short_names', ['ns'])
59+
])
60+
def test_search_returns_single_and_list(client, mock_namespace, mock_namespace_list, attribute, value):
61+
resources = client.resources.search(**{'api_version':'v1', attribute: value})
62+
63+
assert len(resources) == 2
64+
assert mock_namespace in resources
65+
assert mock_namespace_list in resources
66+
67+
@pytest.mark.parametrize(("attribute", "value"), [
68+
('kind', 'Namespace'),
69+
('name', 'namespaces'),
70+
('singular_name', 'namespace'),
71+
('short_names', ['ns'])
72+
])
73+
def test_get_returns_only_single(client, mock_namespace, attribute, value):
74+
resource = client.resources.get(**{'api_version':'v1', attribute: value})
75+
76+
assert resource == mock_namespace
77+
78+
79+
def test_get_namespace_list_kind(client, mock_namespace_list):
80+
resource = client.resources.get(api_version='v1', kind='NamespaceList')
81+
82+
assert resource == mock_namespace_list

0 commit comments

Comments
 (0)