Merge "Honor image_endpoint_override for image discovery"
This commit is contained in:
commit
50f4d553ba
|
@ -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']
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue