diff --git a/releasenotes/notes/fnmatch-name-or-id-f658fe26f84086c8.yaml b/releasenotes/notes/fnmatch-name-or-id-f658fe26f84086c8.yaml new file mode 100644 index 000000000..dcdccd249 --- /dev/null +++ b/releasenotes/notes/fnmatch-name-or-id-f658fe26f84086c8.yaml @@ -0,0 +1,5 @@ +--- +features: + - name_or_id parameters to search/get methods now support + filename-like globbing. This means search_servers('nb0*') + will return all servers whose names start with 'nb0'. diff --git a/shade/_utils.py b/shade/_utils.py index bfcfbd416..b3da5b5c9 100644 --- a/shade/_utils.py +++ b/shade/_utils.py @@ -13,6 +13,7 @@ # limitations under the License. import contextlib +import fnmatch import inspect import jmespath import munch @@ -83,7 +84,8 @@ def _filter_list(data, name_or_id, filters): each dictionary contains an 'id' and 'name' key if a value for name_or_id is given. :param string name_or_id: - The name or ID of the entity being filtered. + The name or ID of the entity being filtered. Can be a glob pattern, + such as 'nb01*'. :param filters: A dictionary of meta data to use for further filtering. Elements of this dictionary may, themselves, be dictionaries. Example:: @@ -100,9 +102,11 @@ def _filter_list(data, name_or_id, filters): if name_or_id: identifier_matches = [] for e in data: - e_id = str(e.get('id', None)) + e_id = e.get('id', None) e_name = e.get('name', None) - if str(name_or_id) in (e_id, e_name): + if ((e_id and fnmatch.fnmatch(str(e_id), str(name_or_id))) or + (e_name and fnmatch.fnmatch( + str(e_name), str(name_or_id)))): identifier_matches.append(e) data = identifier_matches diff --git a/shade/tests/unit/test__utils.py b/shade/tests/unit/test__utils.py index bfe566bd4..28235e8dd 100644 --- a/shade/tests/unit/test__utils.py +++ b/shade/tests/unit/test__utils.py @@ -40,6 +40,22 @@ class TestUtils(base.TestCase): ret = _utils._filter_list(data, 'donald', None) self.assertEqual([el1], ret) + def test__filter_list_name_or_id_glob(self): + el1 = dict(id=100, name='donald') + el2 = dict(id=200, name='pluto') + el3 = dict(id=200, name='pluto-2') + data = [el1, el2, el3] + ret = _utils._filter_list(data, 'pluto*', None) + self.assertEqual([el2, el3], ret) + + def test__filter_list_name_or_id_glob_not_found(self): + el1 = dict(id=100, name='donald') + el2 = dict(id=200, name='pluto') + el3 = dict(id=200, name='pluto-2') + data = [el1, el2, el3] + ret = _utils._filter_list(data, 'q*', None) + self.assertEqual([], ret) + def test__filter_list_filter(self): el1 = dict(id=100, name='donald', other='duck') el2 = dict(id=200, name='donald', other='trump')