Merge "Honor image_endpoint_override for image discovery"

This commit is contained in:
Jenkins 2017-01-10 18:48:15 +00:00 committed by Gerrit Code Review
commit 50f4d553ba
2 changed files with 90 additions and 56 deletions

View File

@ -394,66 +394,73 @@ class OpenStackCloud(_normalize.Normalizer):
self._raw_clients['raw-image'] = image_client
return self._raw_clients['raw-image']
def _discover_image_endpoint(self, config_version, image_client):
try:
# Version discovery
versions = image_client.get('/')
api_version = None
if config_version.startswith('1'):
api_version = [
version for version in versions
if version['id'] in ('v1.0', 'v1.1')]
if api_version:
api_version = api_version[0]
if not api_version:
api_version = [
version for version in versions
if version['status'] == 'CURRENT'][0]
image_url = api_version['links'][0]['href']
# If we detect a different version that was configured,
# set the version in occ because we have logic elsewhere
# that is different depending on which version we're using
warning_msg = None
if (config_version.startswith('2')
and api_version['id'].startswith('v1')):
self.cloud_config.config['image_api_version'] = '1'
warning_msg = (
'image_api_version is 2 but only 1 is available.')
elif (config_version.startswith('1')
and api_version['id'].startswith('v2')):
self.cloud_config.config['image_api_version'] = '2'
warning_msg = (
'image_api_version is 1 but only 2 is available.')
if warning_msg:
self.log.debug(warning_msg)
warnings.warn(warning_msg)
except (keystoneauth1.exceptions.connection.ConnectFailure,
OpenStackCloudURINotFound) as e:
# A 404 or a connection error is a likely thing to get
# either with a misconfgured glance. or we've already
# gotten a versioned endpoint from the catalog
self.log.debug(
"Glance version discovery failed, assuming endpoint in"
" the catalog is already versioned. {e}".format(e=str(e)))
image_url = image_client.get_endpoint()
service_url = image_client.get_endpoint()
parsed_image_url = urllib.parse.urlparse(image_url)
parsed_service_url = urllib.parse.urlparse(service_url)
image_url = urllib.parse.ParseResult(
parsed_service_url.scheme,
parsed_image_url.netloc,
parsed_image_url.path,
parsed_image_url.params,
parsed_image_url.query,
parsed_image_url.fragment).geturl()
return image_url
@property
def _image_client(self):
if 'image' not in self._raw_clients:
# Get configured api version for downgrades
config_version = self.cloud_config.get_api_version('image')
image_client = self._get_raw_client('image')
try:
# Version discovery
versions = image_client.get('/')
api_version = None
if config_version.startswith('1'):
api_version = [
version for version in versions
if version['id'] in ('v1.0', 'v1.1')]
if api_version:
api_version = api_version[0]
if not api_version:
api_version = [
version for version in versions
if version['status'] == 'CURRENT'][0]
image_url = api_version['links'][0]['href']
# If we detect a different version that was configured,
# set the version in occ because we have logic elsewhere
# that is different depending on which version we're using
warning_msg = None
if (config_version.startswith('2')
and api_version['id'].startswith('v1')):
self.cloud_config.config['image_api_version'] = '1'
warning_msg = (
'image_api_version is 2 but only 1 is available.')
elif (config_version.startswith('1')
and api_version['id'].startswith('v2')):
self.cloud_config.config['image_api_version'] = '2'
warning_msg = (
'image_api_version is 1 but only 2 is available.')
if warning_msg:
self.log.debug(warning_msg)
warnings.warn(warning_msg)
except (keystoneauth1.exceptions.connection.ConnectFailure,
OpenStackCloudURINotFound) as e:
# A 404 or a connection error is a likely thing to get
# either with a misconfgured glance. or we've already
# gotten a versioned endpoint from the catalog
self.log.debug(
"Glance version discovery failed, assuming endpoint in"
" the catalog is already versioned. {e}".format(e=str(e)))
image_url = image_client.get_endpoint()
service_url = image_client.get_endpoint()
parsed_image_url = urllib.parse.urlparse(image_url)
parsed_service_url = urllib.parse.urlparse(service_url)
image_url = urllib.parse.ParseResult(
parsed_service_url.scheme,
parsed_image_url.netloc,
parsed_image_url.path,
parsed_image_url.params,
parsed_image_url.query,
parsed_image_url.fragment).geturl()
image_url = self.cloud_config.config.get('image_endpoint_override')
if not image_url:
image_url = self._discover_image_endpoint(
config_version, image_client)
image_client.endpoint_override = image_url
self._raw_clients['image'] = image_client
return self._raw_clients['image']

View File

@ -31,10 +31,10 @@ NO_MD5 = '93b885adfe0da089cdf634904fd59f71'
NO_SHA256 = '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d'
class TestImage(base.RequestsMockTestCase):
class BaseTestImage(base.RequestsMockTestCase):
def setUp(self):
super(TestImage, self).setUp()
super(BaseTestImage, self).setUp()
self.image_id = str(uuid.uuid4())
self.imagefile = tempfile.NamedTemporaryFile(delete=False)
self.imagefile.write(b'\0')
@ -68,6 +68,12 @@ class TestImage(base.RequestsMockTestCase):
u'protected': False}
self.fake_search_return = {'images': [self.fake_image_dict]}
self.output = uuid.uuid4().bytes
class TestImage(BaseTestImage):
def setUp(self):
super(TestImage, self).setUp()
self.use_glance()
def test_config_v1(self):
@ -733,3 +739,24 @@ class TestImageV2Only(base.RequestsMockTestCase):
self.cloud._image_client.get_endpoint())
self.assertEqual(
'2', self.cloud_config.get_api_version('image'))
class TestImageVersionDiscovery(BaseTestImage):
def test_version_discovery_skip(self):
self.cloud.cloud_config.config['image_endpoint_override'] = \
'https://image.example.com/v2/override'
self.adapter.register_uri(
'GET', 'https://image.example.com/v2/override/images',
json={'images': []})
self.assertEqual([], self.cloud.list_images())
self.assertEqual(
self.cloud._image_client.endpoint_override,
'https://image.example.com/v2/override')
self.calls += [
dict(
method='GET',
url='https://image.example.com/v2/override/images'),
]
self.assert_calls()