Support globbing in name or id checks

The ansible os_server_facts module support doing this, and a recent
change to add support for returning servers by ids there made it seem
like perhaps the functionality should get rolled up into the shade layer
and be available to everyone.

Change-Id: Ib1096d606840767ce884e6dd58a6928fee0ae6e2
This commit is contained in:
Monty Taylor 2017-02-01 11:09:40 -06:00
parent cc78a7fbad
commit 7102440687
No known key found for this signature in database
GPG Key ID: 7BAE94BC7141A594
3 changed files with 28 additions and 3 deletions

View File

@ -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'.

View File

@ -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

View File

@ -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')