Merge "Get auth from context for glance endpoint"

This commit is contained in:
Zuul 2017-11-21 20:04:25 +00:00 committed by Gerrit Code Review
commit 24152a8f8f
18 changed files with 188 additions and 64 deletions

View File

@ -1023,7 +1023,7 @@ class ServersController(wsgi.Controller):
# build location of newly-created image entity
image_id = str(image['id'])
image_ref = glance.generate_image_url(image_id)
image_ref = glance.generate_image_url(image_id, context)
resp = webob.Response(status_int=202)
resp.headers['Location'] = image_ref

View File

@ -132,7 +132,8 @@ class ViewBuilder(common.ViewBuilder):
def _get_alternate_link(self, request, identifier):
"""Create an alternate link for a specific image id."""
glance_url = glance.generate_glance_url()
glance_url = glance.generate_glance_url(
request.environ['nova.context'])
glance_url = self._update_glance_link_prefix(glance_url)
return '/'.join([glance_url,
self._collection_name,

View File

@ -2946,7 +2946,7 @@ class ComputeManager(manager.Manager):
# image_ref, not the new one. Since the DB has been updated
# to point to the new one... we have to override it.
# TODO(jaypipes): Move generate_image_url() into the nova.image.api
orig_image_ref_url = glance.generate_image_url(orig_image_ref)
orig_image_ref_url = glance.generate_image_url(orig_image_ref, context)
extra_usage_info = {'image_ref_url': orig_image_ref_url}
compute_utils.notify_usage_exists(
self.notifier, context, instance,

View File

@ -149,17 +149,15 @@ def register_opts(conf):
conf.register_group(glance_group)
conf.register_opts(glance_opts, group=glance_group)
confutils.register_ksa_opts(conf, glance_group, DEFAULT_SERVICE_TYPE,
deprecated_opts=deprecated_ksa_opts)
confutils.register_ksa_opts(
conf, glance_group, DEFAULT_SERVICE_TYPE, include_auth=False,
deprecated_opts=deprecated_ksa_opts)
def list_opts():
return {glance_group: (
glance_opts +
ks_loading.get_session_conf_options() +
ks_loading.get_auth_plugin_conf_options('password') +
ks_loading.get_auth_plugin_conf_options('v2password') +
ks_loading.get_auth_plugin_conf_options('v3password') +
confutils.get_ksa_adapter_opts(DEFAULT_SERVICE_TYPE,
deprecated_opts=deprecated_ksa_opts))
}

View File

@ -55,7 +55,8 @@ def _dummy_opt(name):
return cfg.Opt(name, type=lambda x: None)
def register_ksa_opts(conf, group, default_service_type, deprecated_opts=None):
def register_ksa_opts(conf, group, default_service_type, include_auth=True,
deprecated_opts=None):
"""Register keystoneauth auth, Session, and Adapter opts.
:param conf: oslo_config.cfg.CONF in which to register the options
@ -63,6 +64,10 @@ def register_ksa_opts(conf, group, default_service_type, deprecated_opts=None):
options.
:param default_service_type: Default for the service_type conf option on
the Adapter.
:param include_auth: For service types where Nova is acting on behalf of
the user, auth should come from the user context.
In those cases, set this arg to False to avoid
registering ksa auth options.
:param deprecated_opts: dict of deprecated opts to register with the ksa
Session or Adapter opts. See docstring for
the deprecated_opts param of:
@ -72,7 +77,8 @@ def register_ksa_opts(conf, group, default_service_type, deprecated_opts=None):
group = getattr(group, 'name', group)
ks_loading.register_session_conf_options(
conf, group, deprecated_opts=deprecated_opts)
ks_loading.register_auth_conf_options(conf, group)
if include_auth:
ks_loading.register_auth_conf_options(conf, group)
conf.register_opts(get_ksa_adapter_opts(
default_service_type, deprecated_opts=deprecated_opts), group=group)
# Have to register dummies for the version-related opts we removed

View File

@ -118,7 +118,7 @@ class RequestContext(context.RequestContext):
if service_catalog:
# Only include required parts of service_catalog
self.service_catalog = [s for s in service_catalog
if s.get('type') in ('block-storage', 'volumev3',
if s.get('type') in ('image', 'block-storage', 'volumev3',
'key-manager', 'placement')]
else:
# if list is empty or none

View File

@ -56,7 +56,8 @@ CONF = nova.conf.CONF
_SESSION = None
def _glanceclient_from_endpoint(context, endpoint, version):
def _session_and_auth(context):
# Session is cached, but auth needs to be pulled from context each time.
global _SESSION
if not _SESSION:
@ -65,21 +66,25 @@ def _glanceclient_from_endpoint(context, endpoint, version):
auth = service_auth.get_auth_plugin(context)
# TODO(johngarbutt) eventually we should default to getting the
# endpoint URL from the service catalog.
return glanceclient.Client(version, session=_SESSION, auth=auth,
return _SESSION, auth
def _glanceclient_from_endpoint(context, endpoint, version):
sess, auth = _session_and_auth(context)
return glanceclient.Client(version, session=sess, auth=auth,
endpoint_override=endpoint,
global_request_id=context.global_id)
def generate_glance_url():
def generate_glance_url(context):
"""Return a random glance url from the api servers we know about."""
return next(get_api_servers())
return next(get_api_servers(context))
def generate_image_url(image_ref):
def generate_image_url(image_ref, context):
"""Generate an image URL from an image_ref."""
return "%s/images/%s" % (generate_glance_url(), image_ref)
return "%s/images/%s" % (generate_glance_url(context), image_ref)
def _endpoint_from_image_ref(image_href):
@ -106,7 +111,7 @@ def generate_identity_headers(context, status='Confirmed'):
}
def get_api_servers():
def get_api_servers(context):
"""Shuffle a list of service endpoints and return an iterator that will
cycle through the list, looping around to the beginning if necessary.
"""
@ -117,13 +122,12 @@ def get_api_servers():
api_servers = CONF.glance.api_servers
random.shuffle(api_servers)
else:
# TODO(efried): Plumb in a reasonable auth from callers' contexts
sess, auth = _session_and_auth(context)
ksa_adap = utils.get_ksa_adapter(
nova.conf.glance.DEFAULT_SERVICE_TYPE,
ksa_auth=auth, ksa_session=sess,
min_version='2.0', max_version='2.latest')
# TODO(efried): Use ksa_adap.get_endpoint() when bug #1707995 is fixed.
api_servers = [ksa_adap.endpoint_override or
ksa_adap.get_endpoint_data().catalog_url]
api_servers = [utils.get_endpoint(ksa_adap)]
return itertools.cycle(api_servers)
@ -149,7 +153,7 @@ class GlanceClientWrapper(object):
def _create_onetime_client(self, context, version):
"""Create a client that will be used for one call."""
if self.api_servers is None:
self.api_servers = get_api_servers()
self.api_servers = get_api_servers(context)
self.api_server = next(self.api_servers)
return _glanceclient_from_endpoint(context, self.api_server, version)

View File

@ -394,7 +394,7 @@ def info_from_instance(context, instance, network_info,
modifications.
"""
image_ref_url = glance.generate_image_url(instance.image_ref)
image_ref_url = glance.generate_image_url(instance.image_ref, context)
instance_type = instance.get_flavor()
instance_type_name = instance_type.get('name', '')

View File

@ -92,7 +92,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
"rel": "alternate",
"type": "application/vnd.openstack.image",
"href": self.alternate %
(glance.generate_glance_url(),
(glance.generate_glance_url('ctx'),
123),
}],
},
@ -136,7 +136,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
"type":
"application/vnd.openstack.image",
"href": self.alternate %
(glance.generate_glance_url(),
(glance.generate_glance_url('ctx'),
124),
}],
},
@ -196,7 +196,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_125["links"][0]["href"] = "%s/125" % self.url_prefix
image_125["links"][1]["href"] = "%s/125" % self.bookmark_prefix
image_125["links"][2]["href"] = (
"%s/images/125" % glance.generate_glance_url())
"%s/images/125" % glance.generate_glance_url('ctx'))
image_126 = copy.deepcopy(self.expected_image_124["image"])
image_126['id'] = '126'
@ -206,7 +206,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_126["links"][0]["href"] = "%s/126" % self.url_prefix
image_126["links"][1]["href"] = "%s/126" % self.bookmark_prefix
image_126["links"][2]["href"] = (
"%s/images/126" % glance.generate_glance_url())
"%s/images/126" % glance.generate_glance_url('ctx'))
image_127 = copy.deepcopy(self.expected_image_124["image"])
image_127['id'] = '127'
@ -216,7 +216,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_127["links"][0]["href"] = "%s/127" % self.url_prefix
image_127["links"][1]["href"] = "%s/127" % self.bookmark_prefix
image_127["links"][2]["href"] = (
"%s/images/127" % glance.generate_glance_url())
"%s/images/127" % glance.generate_glance_url('ctx'))
image_128 = copy.deepcopy(self.expected_image_124["image"])
image_128['id'] = '128'
@ -226,7 +226,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_128["links"][0]["href"] = "%s/128" % self.url_prefix
image_128["links"][1]["href"] = "%s/128" % self.bookmark_prefix
image_128["links"][2]["href"] = (
"%s/images/128" % glance.generate_glance_url())
"%s/images/128" % glance.generate_glance_url('ctx'))
image_129 = copy.deepcopy(self.expected_image_124["image"])
image_129['id'] = '129'
@ -236,7 +236,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_129["links"][0]["href"] = "%s/129" % self.url_prefix
image_129["links"][1]["href"] = "%s/129" % self.bookmark_prefix
image_129["links"][2]["href"] = (
"%s/images/129" % glance.generate_glance_url())
"%s/images/129" % glance.generate_glance_url('ctx'))
image_130 = copy.deepcopy(self.expected_image_123["image"])
image_130['id'] = '130'
@ -247,7 +247,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_130["links"][0]["href"] = "%s/130" % self.url_prefix
image_130["links"][1]["href"] = "%s/130" % self.bookmark_prefix
image_130["links"][2]["href"] = (
"%s/images/130" % glance.generate_glance_url())
"%s/images/130" % glance.generate_glance_url('ctx'))
image_131 = copy.deepcopy(self.expected_image_123["image"])
image_131['id'] = '131'
@ -258,7 +258,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
image_131["links"][0]["href"] = "%s/131" % self.url_prefix
image_131["links"][1]["href"] = "%s/131" % self.bookmark_prefix
image_131["links"][2]["href"] = (
"%s/images/131" % glance.generate_glance_url())
"%s/images/131" % glance.generate_glance_url('ctx'))
expected = [self.expected_image_123["image"],
self.expected_image_124["image"],
@ -352,7 +352,7 @@ class ImagesControllerTestV21(test.NoDBTestCase):
view = images_view.ViewBuilder()
request = self.http_request.blank(self.url_base + 'images/1')
generated_url = view._get_alternate_link(request, 1)
actual_url = "%s/images/1" % glance.generate_glance_url()
actual_url = "%s/images/1" % glance.generate_glance_url('ctx')
self.assertEqual(generated_url, actual_url)
def _check_response(self, controller_method, response, expected_code):

View File

@ -896,7 +896,7 @@ class ServerActionsControllerTestV21(test.TestCase):
location = response.headers['Location']
self.assertEqual(self.image_url + '123' if self.image_url else
glance.generate_image_url('123'),
glance.generate_image_url('123', self.context),
location)
def test_create_image_v2_45(self):
@ -997,8 +997,9 @@ class ServerActionsControllerTestV21(test.TestCase):
FAKE_UUID, body=body)
location = response.headers['Location']
image_id = location.replace(self.image_url or
glance.generate_image_url(''), '')
image_id = location.replace(
self.image_url or glance.generate_image_url('', self.context),
'')
image = image_service.show(None, image_id)
self.assertEqual(image['name'], 'snapshot_of_volume_backed')
@ -1145,7 +1146,8 @@ class ServerActionsControllerTestV21(test.TestCase):
location = response.headers['Location']
self.assertEqual(self.image_url + '123' if self.image_url else
glance.generate_image_url('123'), location)
glance.generate_image_url('123', self.context),
location)
def test_create_image_with_too_much_metadata(self):
body = {

View File

@ -2362,7 +2362,8 @@ class ComputeTestCase(BaseTestCase,
self.assertIn('display_name', payload)
self.assertIn('created_at', payload)
self.assertIn('launched_at', payload)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF,
self.context)
self.assertEqual(payload['image_ref_url'], image_ref_url)
msg = fake_notifier.NOTIFICATIONS[0]
self.assertIn('rescue_image_name', msg.payload)
@ -2402,7 +2403,8 @@ class ComputeTestCase(BaseTestCase,
self.assertIn('display_name', payload)
self.assertIn('created_at', payload)
self.assertIn('launched_at', payload)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF,
self.context)
self.assertEqual(payload['image_ref_url'], image_ref_url)
self.compute.terminate_instance(self.context, instance, [], [])
@ -4149,7 +4151,7 @@ class ComputeTestCase(BaseTestCase,
self.assertIn('launched_at', payload)
self.assertIn('fixed_ips', payload)
self.assertTrue(payload['launched_at'])
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF, self.context)
self.assertEqual(payload['image_ref_url'], image_ref_url)
self.assertEqual('Success', payload['message'])
self.compute.terminate_instance(self.context, instance, [], [])
@ -4279,7 +4281,7 @@ class ComputeTestCase(BaseTestCase,
self.assertIn('deleted_at', payload)
self.assertEqual(payload['terminated_at'], utils.strtime(cur_time))
self.assertEqual(payload['deleted_at'], utils.strtime(cur_time))
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF, self.context)
self.assertEqual(payload['image_ref_url'], image_ref_url)
@mock.patch.object(fake.FakeDriver, "macs_for_instance")
@ -4968,8 +4970,9 @@ class ComputeTestCase(BaseTestCase,
inst_ref.refresh()
image_ref_url = glance.generate_image_url(image_ref)
new_image_ref_url = glance.generate_image_url(new_image_ref)
image_ref_url = glance.generate_image_url(image_ref, self.context)
new_image_ref_url = glance.generate_image_url(new_image_ref,
self.context)
self.assertEqual(len(fake_notifier.NOTIFICATIONS), 3)
msg = fake_notifier.NOTIFICATIONS[0]
@ -5057,7 +5060,8 @@ class ComputeTestCase(BaseTestCase,
self.assertIn('created_at', payload)
self.assertIn('launched_at', payload)
self.assertEqual(payload['launched_at'], utils.strtime(cur_time))
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF,
self.context)
self.assertEqual(payload['image_ref_url'], image_ref_url)
self.compute.terminate_instance(self.context, instance, [], [])
@ -5109,7 +5113,7 @@ class ComputeTestCase(BaseTestCase,
self.assertIn('display_name', payload)
self.assertIn('created_at', payload)
self.assertIn('launched_at', payload)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF)
image_ref_url = glance.generate_image_url(FAKE_IMAGE_REF, self.context)
self.assertEqual(payload['image_ref_url'], image_ref_url)
self.compute.terminate_instance(self.context, instance, [], [])

View File

@ -449,8 +449,8 @@ class UsageInfoTestCase(test.TestCase):
"Key %s not in payload" % attr)
self.assertEqual(payload['image_meta'],
{'md_key1': 'val1', 'md_key2': 'val2'})
image_ref_url = "%s/images/%s" % (glance.generate_glance_url(),
uuids.fake_image_ref)
image_ref_url = "%s/images/%s" % (
glance.generate_glance_url(self.context), uuids.fake_image_ref)
self.assertEqual(payload['image_ref_url'], image_ref_url)
self.compute.terminate_instance(self.context, instance, [], [])
@ -485,8 +485,8 @@ class UsageInfoTestCase(test.TestCase):
self.assertIn(attr, payload, "Key %s not in payload" % attr)
self.assertEqual(payload['image_meta'],
{'md_key1': 'val1', 'md_key2': 'val2'})
image_ref_url = "%s/images/%s" % (glance.generate_glance_url(),
uuids.fake_image_ref)
image_ref_url = "%s/images/%s" % (
glance.generate_glance_url(self.context), uuids.fake_image_ref)
self.assertEqual(payload['image_ref_url'], image_ref_url)
def test_notify_about_instance_action(self):
@ -778,8 +778,8 @@ class UsageInfoTestCase(test.TestCase):
'audit_period_ending', 'image_meta'):
self.assertIn(attr, payload, "Key %s not in payload" % attr)
self.assertEqual(payload['image_meta'], {})
image_ref_url = "%s/images/%s" % (glance.generate_glance_url(),
uuids.fake_image_ref)
image_ref_url = "%s/images/%s" % (
glance.generate_glance_url(self.context), uuids.fake_image_ref)
self.assertEqual(payload['image_ref_url'], image_ref_url)
def test_notify_about_instance_usage(self):
@ -814,8 +814,8 @@ class UsageInfoTestCase(test.TestCase):
self.assertEqual(payload['image_meta'],
{'md_key1': 'val1', 'md_key2': 'val2'})
self.assertEqual(payload['image_name'], 'fake_name')
image_ref_url = "%s/images/%s" % (glance.generate_glance_url(),
uuids.fake_image_ref)
image_ref_url = "%s/images/%s" % (
glance.generate_glance_url(self.context), uuids.fake_image_ref)
self.assertEqual(payload['image_ref_url'], image_ref_url)
self.compute.terminate_instance(self.context, instance, [], [])

View File

@ -1580,7 +1580,7 @@ class TestGlanceApiServers(test.NoDBTestCase):
'http://10.0.2.2:9294']
expected_servers = set(glance_servers)
self.flags(api_servers=glance_servers, group='glance')
api_servers = glance.get_api_servers()
api_servers = glance.get_api_servers('context')
# In len(expected_servers) cycles, we should get all the endpoints
self.assertEqual(expected_servers,
{next(api_servers) for _ in expected_servers})
@ -1589,7 +1589,7 @@ class TestGlanceApiServers(test.NoDBTestCase):
def test_get_api_servers_get_ksa_adapter(self, mock_epd):
"""Test get_api_servers via nova.utils.get_ksa_adapter()."""
self.flags(api_servers=None, group='glance')
api_servers = glance.get_api_servers()
api_servers = glance.get_api_servers(mock.Mock())
self.assertEqual(mock_epd.return_value.catalog_url, next(api_servers))
# Still get itertools.cycle behavior
self.assertEqual(mock_epd.return_value.catalog_url, next(api_servers))
@ -1598,7 +1598,7 @@ class TestGlanceApiServers(test.NoDBTestCase):
# Now test with endpoint_override - get_endpoint_data is not called.
mock_epd.reset_mock()
self.flags(endpoint_override='foo', group='glance')
api_servers = glance.get_api_servers()
api_servers = glance.get_api_servers(mock.Mock())
self.assertEqual('foo', next(api_servers))
self.assertEqual('foo', next(api_servers))
mock_epd.assert_not_called()

View File

@ -97,7 +97,7 @@ class ContextTestCase(test.NoDBTestCase):
service_catalog=None)
self.assertEqual([], ctxt.service_catalog)
def test_service_catalog_cinder_only(self):
def test_service_catalog_filter(self):
service_catalog = [
{u'type': u'compute', u'name': u'nova'},
{u'type': u's3', u'name': u's3'},
@ -110,7 +110,8 @@ class ContextTestCase(test.NoDBTestCase):
{u'type': None, u'name': u'S_withouttype'},
{u'type': u'vo', u'name': u'S_partofvolume'}]
volume_catalog = [{u'type': u'volumev3', u'name': u'cinderv3'},
volume_catalog = [{u'type': u'image', u'name': u'glance'},
{u'type': u'volumev3', u'name': u'cinderv3'},
{u'type': u'block-storage', u'name': u'cinder'}]
ctxt = context.RequestContext('111', '222',
service_catalog=service_catalog)

View File

@ -20,6 +20,8 @@ import os.path
import tempfile
import eventlet
from keystoneauth1 import adapter as ks_adapter
from keystoneauth1 import exceptions as ks_exc
from keystoneauth1.identity import base as ks_identity
from keystoneauth1 import session as ks_session
import mock
@ -1385,3 +1387,54 @@ class GetKSAAdapterTestCase(test.NoDBTestCase):
self.load_adap.assert_called_once_with(
utils.CONF, 'cinder', session=self.sess, auth=self.auth,
min_version=None, max_version=None)
class GetEndpointTestCase(test.NoDBTestCase):
def setUp(self):
super(GetEndpointTestCase, self).setUp()
self.adap = mock.create_autospec(ks_adapter.Adapter, instance=True)
self.adap.endpoint_override = None
self.adap.service_type = 'stype'
self.adap.interface = ['admin', 'public']
def test_endpoint_override(self):
self.adap.endpoint_override = 'foo'
self.assertEqual('foo', utils.get_endpoint(self.adap))
self.adap.get_endpoint_data.assert_not_called()
self.adap.get_endpoint.assert_not_called()
def test_image_good(self):
self.adap.service_type = 'image'
self.adap.get_endpoint_data.return_value.catalog_url = 'url'
self.assertEqual('url', utils.get_endpoint(self.adap))
self.adap.get_endpoint_data.assert_called_once_with()
self.adap.get_endpoint.assert_not_called()
def test_image_bad(self):
self.adap.service_type = 'image'
self.adap.get_endpoint_data.side_effect = AttributeError
self.adap.get_endpoint.return_value = 'url'
self.assertEqual('url', utils.get_endpoint(self.adap))
self.adap.get_endpoint_data.assert_called_once_with()
self.adap.get_endpoint.assert_called_once_with()
def test_nonimage_good(self):
self.adap.get_endpoint.return_value = 'url'
self.assertEqual('url', utils.get_endpoint(self.adap))
self.adap.get_endpoint_data.assert_not_called()
self.adap.get_endpoint.assert_called_once_with()
def test_nonimage_try_interfaces(self):
self.adap.get_endpoint.side_effect = (ks_exc.EndpointNotFound, 'url')
self.assertEqual('url', utils.get_endpoint(self.adap))
self.adap.get_endpoint_data.assert_not_called()
self.assertEqual(2, self.adap.get_endpoint.call_count)
self.assertEqual('admin', self.adap.interface)
def test_nonimage_try_interfaces_fail(self):
self.adap.get_endpoint.side_effect = ks_exc.EndpointNotFound
self.assertRaises(ks_exc.EndpointNotFound,
utils.get_endpoint, self.adap)
self.adap.get_endpoint_data.assert_not_called()
self.assertEqual(3, self.adap.get_endpoint.call_count)
self.assertEqual('public', self.adap.interface)

View File

@ -33,6 +33,7 @@ import tempfile
import time
import eventlet
from keystoneauth1 import exceptions as ks_exc
from keystoneauth1 import loading as ks_loading
import netaddr
from os_service_types import service_types
@ -1325,3 +1326,56 @@ def get_ksa_adapter(service_type, ksa_auth=None, ksa_session=None,
return ks_loading.load_adapter_from_conf_options(
CONF, confgrp, session=ksa_session, auth=ksa_auth,
min_version=min_version, max_version=max_version)
def get_endpoint(ksa_adapter):
"""Get the endpoint URL represented by a keystoneauth1 Adapter.
This method is equivalent to what
ksa_adapter.get_endpoint()
should do, if it weren't for a panoply of bugs.
:param ksa_adapter: keystoneauth1.adapter.Adapter, appropriately set up
with an endpoint_override; or service_type, interface
(list) and auth/service_catalog.
:return: String endpoint URL.
:raise EndpointNotFound: If endpoint discovery fails.
"""
# TODO(efried): This will be unnecessary once bug #1707993 is fixed.
# (At least for the non-image case, until 1707995 is fixed.)
if ksa_adapter.endpoint_override:
return ksa_adapter.endpoint_override
# TODO(efried): Remove this once bug #1707995 is fixed.
if ksa_adapter.service_type == 'image':
try:
return ksa_adapter.get_endpoint_data().catalog_url
except AttributeError:
# ksa_adapter.auth is a _ContextAuthPlugin, which doesn't have
# get_endpoint_data. Fall through to using get_endpoint().
pass
# TODO(efried): The remainder of this method reduces to
# TODO(efried): return ksa_adapter.get_endpoint()
# TODO(efried): once bug #1709118 is fixed.
# NOTE(efried): Id9bd19cca68206fc64d23b0eaa95aa3e5b01b676 may also do the
# trick, once it's in a ksa release.
# The EndpointNotFound exception happens when _ContextAuthPlugin is in play
# because its get_endpoint() method isn't yet set up to handle interface as
# a list. (It could also happen with a real auth if the endpoint isn't
# there; but that's covered below.)
try:
return ksa_adapter.get_endpoint()
except ks_exc.EndpointNotFound:
pass
interfaces = list(ksa_adapter.interface)
for interface in interfaces:
ksa_adapter.interface = interface
try:
return ksa_adapter.get_endpoint()
except ks_exc.EndpointNotFound:
pass
raise ks_exc.EndpointNotFound(
"Could not find requested endpoint for any of the following "
"interfaces: %s" % interfaces)

View File

@ -35,7 +35,7 @@ LOG = logging.getLogger(__name__)
class GlanceStore(object):
def _call_glance_plugin(self, context, instance, session, fn, image_id,
params):
glance_api_servers = glance.get_api_servers()
glance_api_servers = glance.get_api_servers(context)
sr_path = vm_utils.get_sr_path(session)
extra_headers = glance.generate_identity_headers(context)

View File

@ -2,9 +2,10 @@
upgrade:
- |
Nova now uses keystoneauth1 configuration to set up communication with the
image service. Use keystoneauth1 loading parameters for auth, Session, and
image service. Use keystoneauth1 loading parameters for Session and
Adapter setup in the ``[glance]`` conf section. This includes using
``endpoint_override`` in favor of ``api_servers``. The
``[glance]api_servers`` conf option is still supported, but should only be
used if you need multiple endpoints and are unable to use a load balancer
for some reason.
for some reason. However, note that no configuration is necessary with an
appropriate service catalog entry for the image service.