Tweak find_image method to search in hidden images

With Image v2.7 a possibility of hiding and image is being added (an 
attribute 'os_hidden'). After an image is being hidden the only 
possibility to find image by name is to do a list with `os_hidden=True` 
to list hidden images. So what we do here is search as usual, and if 
nothing found try also to search in hidden images (list of hidden images 
and grep by name)

Change-Id: I237da3e7e6b5d23010d8b26a3fcbfabaddeb5f31
This commit is contained in:
Artem Goncharov 2019-02-28 12:12:04 +01:00
parent a185a7fd2d
commit 5e09afc80e
2 changed files with 55 additions and 1 deletions

View File

@ -301,3 +301,25 @@ class Image(resource.Resource, resource.TagMixin):
request.headers.update(headers)
return request
@classmethod
def find(cls, session, name_or_id, ignore_missing=True, **params):
# Do a regular search first (ignoring missing)
result = super(Image, cls).find(session, name_or_id, True,
**params)
if result:
return result
else:
# Search also in hidden images
params['is_hidden'] = True
data = cls.list(session, **params)
result = cls._get_one_match(name_or_id, data)
if result is not None:
return result
if ignore_missing:
return None
raise exceptions.ResourceNotFound(
"No %s found for %s" % (cls.__name__, name_or_id))

View File

@ -86,12 +86,16 @@ EXAMPLE = {
class FakeResponse(object):
def __init__(self, response, status_code=200, headers=None):
def __init__(self, response, status_code=200, headers=None, reason=None):
self.body = response
self.content = response
self.status_code = status_code
headers = headers if headers else {'content-type': 'application/json'}
self.headers = requests.structures.CaseInsensitiveDict(headers)
if reason:
self.reason = reason
# for the sake of "list" response faking
self.links = []
def json(self):
return self.body
@ -108,6 +112,7 @@ class TestImage(base.TestCase):
self.sess.post = mock.Mock(return_value=self.resp)
self.sess.put = mock.Mock(return_value=FakeResponse({}))
self.sess.delete = mock.Mock(return_value=FakeResponse({}))
self.sess.fetch = mock.Mock(return_value=FakeResponse({}))
self.sess.default_microversion = None
self.sess.retriable_status_codes = None
@ -366,3 +371,30 @@ class TestImage(base.TestCase):
self.assertEqual(
sorted(value, key=operator.itemgetter('value')),
sorted(call_kwargs['json'], key=operator.itemgetter('value')))
def test_image_find(self):
sot = image.Image()
self.sess._get_connection = mock.Mock(return_value=self.cloud)
self.sess.get.side_effect = [
# First fetch by name
FakeResponse(None, 404, headers={}, reason='dummy'),
# Then list with no results
FakeResponse({'images': []}),
# And finally new list of hidden images with one searched
FakeResponse({'images': [EXAMPLE]})
]
result = sot.find(self.sess, EXAMPLE['name'])
self.sess.get.assert_has_calls([
mock.call('images/' + EXAMPLE['name'], microversion=None),
mock.call('/images', headers={'Accept': 'application/json'},
microversion=None, params={}),
mock.call('/images', headers={'Accept': 'application/json'},
microversion=None, params={'os_hidden': True})
])
self.assertIsInstance(result, image.Image)
self.assertEqual(IDENTIFIER, result.id)