xenapi: send identity headers from glance plugin
Send identity headers while uploading/downloading images from glance. Related to: 1) Add identity headers while calling glanceclient from nova Ife02059abbdce7920f1f408b71e9745d777fa770 2) Pass identity headers received in glanceclient to nova Ifbef582aa4e64a2e7a46db43a9cc6cf8c3531dbd 3) Pass identity headers received by glance api to glance registry Ie5f07ed6dfeaa8428de4f79c4d40d182328e6ab4 NOTE: since this is a change to a Dom0 plugin API, it requires the lock-step upgrade of both the compute-manager and the dom0 plugin. DocImpact Change-Id: I6d5e3448d2c0acc392d18e0b88cec25cf313da5b
This commit is contained in:
parent
27ff32ad09
commit
47a20a9f44
@ -104,6 +104,17 @@ def _parse_image_ref(image_href):
|
|||||||
return (image_id, host, port, use_ssl)
|
return (image_id, host, port, use_ssl)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_identity_headers(context, status='Confirmed'):
|
||||||
|
return {
|
||||||
|
'X-Auth-Token': getattr(context, 'auth_token', None),
|
||||||
|
'X-User-Id': getattr(context, 'user', None),
|
||||||
|
'X-Tenant-Id': getattr(context, 'tenant', None),
|
||||||
|
'X-Roles': ','.join(context.roles),
|
||||||
|
'X-Identity-Status': status,
|
||||||
|
'X-Service-Catalog': json.dumps(context.service_catalog),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _create_glance_client(context, host, port, use_ssl, version=1):
|
def _create_glance_client(context, host, port, use_ssl, version=1):
|
||||||
"""Instantiate a new glanceclient.Client object."""
|
"""Instantiate a new glanceclient.Client object."""
|
||||||
params = {}
|
params = {}
|
||||||
@ -120,15 +131,7 @@ def _create_glance_client(context, host, port, use_ssl, version=1):
|
|||||||
# keyword 'token', but later versions accept both the
|
# keyword 'token', but later versions accept both the
|
||||||
# header 'X-Auth-Token' and 'token'
|
# header 'X-Auth-Token' and 'token'
|
||||||
params['token'] = context.auth_token
|
params['token'] = context.auth_token
|
||||||
identity_headers = {
|
params['identity_headers'] = generate_identity_headers(context)
|
||||||
'X-Auth-Token': context.auth_token,
|
|
||||||
'X-User-Id': context.user,
|
|
||||||
'X-Tenant-Id': context.tenant,
|
|
||||||
'X-Roles': ','.join(context.roles),
|
|
||||||
'X-Identity-Status': 'Confirmed',
|
|
||||||
'X-Service-Catalog': json.dumps(context.service_catalog),
|
|
||||||
}
|
|
||||||
params['identity_headers'] = identity_headers
|
|
||||||
endpoint = '%s://%s:%s' % (scheme, host, port)
|
endpoint = '%s://%s:%s' % (scheme, host, port)
|
||||||
return glanceclient.Client(str(version), endpoint, **params)
|
return glanceclient.Client(str(version), endpoint, **params)
|
||||||
|
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
|
||||||
import mox
|
|
||||||
|
|
||||||
from nova import context
|
from nova import context
|
||||||
from nova import exception
|
from nova import exception
|
||||||
from nova.tests.virt.xenapi import stubs
|
from nova.tests.virt.xenapi import stubs
|
||||||
@ -31,7 +29,6 @@ class TestGlanceStore(stubs.XenAPITestBase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestGlanceStore, self).setUp()
|
super(TestGlanceStore, self).setUp()
|
||||||
self.store = glance.GlanceStore()
|
self.store = glance.GlanceStore()
|
||||||
self.mox = mox.Mox()
|
|
||||||
|
|
||||||
self.flags(glance_host='1.1.1.1',
|
self.flags(glance_host='1.1.1.1',
|
||||||
glance_port=123,
|
glance_port=123,
|
||||||
@ -56,14 +53,26 @@ class TestGlanceStore(stubs.XenAPITestBase):
|
|||||||
'os_type': 'default',
|
'os_type': 'default',
|
||||||
'xenapi_use_agent': 'true'}
|
'xenapi_use_agent': 'true'}
|
||||||
|
|
||||||
|
def _get_params(self):
|
||||||
|
return {'image_id': 'fake_image_uuid',
|
||||||
|
'glance_host': '1.1.1.1',
|
||||||
|
'glance_port': 123,
|
||||||
|
'glance_use_ssl': False,
|
||||||
|
'sr_path': '/fake/sr/path',
|
||||||
|
'extra_headers': {'X-Service-Catalog': '[]',
|
||||||
|
'X-Auth-Token': 'foobar',
|
||||||
|
'X-Roles': '',
|
||||||
|
'X-Tenant-Id': 'project',
|
||||||
|
'X-User-Id': 'user',
|
||||||
|
'X-Identity-Status': 'Confirmed'}}
|
||||||
|
|
||||||
|
def _get_download_params(self):
|
||||||
|
params = self._get_params()
|
||||||
|
params['uuid_stack'] = ['uuid1']
|
||||||
|
return params
|
||||||
|
|
||||||
def test_download_image(self):
|
def test_download_image(self):
|
||||||
params = {'image_id': 'fake_image_uuid',
|
params = self._get_download_params()
|
||||||
'glance_host': '1.1.1.1',
|
|
||||||
'glance_port': 123,
|
|
||||||
'glance_use_ssl': False,
|
|
||||||
'sr_path': '/fake/sr/path',
|
|
||||||
'auth_token': 'foobar',
|
|
||||||
'uuid_stack': ['uuid1']}
|
|
||||||
|
|
||||||
self.stubs.Set(vm_utils, '_make_uuid_stack',
|
self.stubs.Set(vm_utils, '_make_uuid_stack',
|
||||||
lambda *a, **kw: ['uuid1'])
|
lambda *a, **kw: ['uuid1'])
|
||||||
@ -78,15 +87,10 @@ class TestGlanceStore(stubs.XenAPITestBase):
|
|||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
|
||||||
def _get_upload_params(self):
|
def _get_upload_params(self):
|
||||||
params = {'vdi_uuids': ['fake_vdi_uuid'],
|
params = self._get_params()
|
||||||
'image_id': 'fake_image_uuid',
|
params['vdi_uuids'] = ['fake_vdi_uuid']
|
||||||
'glance_host': '1.1.1.1',
|
params['properties'] = {'auto_disk_config': True,
|
||||||
'glance_port': 123,
|
'os_type': 'default'}
|
||||||
'glance_use_ssl': False,
|
|
||||||
'sr_path': '/fake/sr/path',
|
|
||||||
'auth_token': 'foobar',
|
|
||||||
'properties': {'auto_disk_config': True,
|
|
||||||
'os_type': 'default'}}
|
|
||||||
return params
|
return params
|
||||||
|
|
||||||
def test_upload_image(self):
|
def test_upload_image(self):
|
||||||
@ -105,10 +109,10 @@ class TestGlanceStore(stubs.XenAPITestBase):
|
|||||||
|
|
||||||
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
self.mox.StubOutWithMock(self.session, 'call_plugin_serialized')
|
||||||
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
self.session.call_plugin_serialized('glance', 'upload_vhd',
|
||||||
**params).AndRaise(Exception)
|
**params).AndRaise(RuntimeError)
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
self.assertRaises(Exception, self.store.upload_image,
|
self.assertRaises(RuntimeError, self.store.upload_image,
|
||||||
self.context, self.session, self.instance,
|
self.context, self.session, self.instance,
|
||||||
['fake_vdi_uuid'], 'fake_image_uuid')
|
['fake_vdi_uuid'], 'fake_image_uuid')
|
||||||
self.mox.VerifyAll()
|
self.mox.VerifyAll()
|
||||||
|
@ -243,7 +243,12 @@ class FetchVhdImageTestCase(test.TestCase):
|
|||||||
self.session, 'call_plugin_serialized_with_retry')
|
self.session, 'call_plugin_serialized_with_retry')
|
||||||
self.session.call_plugin_serialized_with_retry(
|
self.session.call_plugin_serialized_with_retry(
|
||||||
'glance', 'download_vhd', 0, mox.IgnoreArg(),
|
'glance', 'download_vhd', 0, mox.IgnoreArg(),
|
||||||
auth_token='auth_token',
|
extra_headers={'X-Service-Catalog': '[]',
|
||||||
|
'X-Auth-Token': 'auth_token',
|
||||||
|
'X-Roles': '',
|
||||||
|
'X-Tenant-Id': None,
|
||||||
|
'X-User-Id': None,
|
||||||
|
'X-Identity-Status': 'Confirmed'},
|
||||||
image_id='image_id',
|
image_id='image_id',
|
||||||
uuid_stack=["uuid_stack"],
|
uuid_stack=["uuid_stack"],
|
||||||
sr_path='sr_path').AndReturn({'root': {'uuid': 'vdi'}})
|
sr_path='sr_path').AndReturn({'root': {'uuid': 'vdi'}})
|
||||||
@ -316,7 +321,12 @@ class FetchVhdImageTestCase(test.TestCase):
|
|||||||
self.session, 'call_plugin_serialized_with_retry')
|
self.session, 'call_plugin_serialized_with_retry')
|
||||||
self.session.call_plugin_serialized_with_retry(
|
self.session.call_plugin_serialized_with_retry(
|
||||||
'glance', 'download_vhd', 0, mox.IgnoreArg(),
|
'glance', 'download_vhd', 0, mox.IgnoreArg(),
|
||||||
auth_token='auth_token',
|
extra_headers={'X-Service-Catalog': '[]',
|
||||||
|
'X-Auth-Token': 'auth_token',
|
||||||
|
'X-Roles': '',
|
||||||
|
'X-Tenant-Id': None,
|
||||||
|
'X-User-Id': None,
|
||||||
|
'X-Identity-Status': 'Confirmed'},
|
||||||
image_id='image_id',
|
image_id='image_id',
|
||||||
uuid_stack=["uuid_stack"],
|
uuid_stack=["uuid_stack"],
|
||||||
sr_path='sr_path').AndReturn({'root': {'uuid': 'vdi'}})
|
sr_path='sr_path').AndReturn({'root': {'uuid': 'vdi'}})
|
||||||
|
@ -39,7 +39,7 @@ class GlanceStore(object):
|
|||||||
def _make_params(self, context, session, image_id):
|
def _make_params(self, context, session, image_id):
|
||||||
return {'image_id': image_id,
|
return {'image_id': image_id,
|
||||||
'sr_path': vm_utils.get_sr_path(session),
|
'sr_path': vm_utils.get_sr_path(session),
|
||||||
'auth_token': getattr(context, 'auth_token', None)}
|
'extra_headers': glance.generate_identity_headers(context)}
|
||||||
|
|
||||||
def download_image(self, context, session, instance, image_id):
|
def download_image(self, context, session, instance, image_id):
|
||||||
params = self._make_params(context, session, image_id)
|
params = self._make_params(context, session, image_id)
|
||||||
|
@ -89,15 +89,10 @@ def _download_tarball_and_verify(request, staging_path):
|
|||||||
|
|
||||||
|
|
||||||
def _download_tarball(sr_path, staging_path, image_id, glance_host,
|
def _download_tarball(sr_path, staging_path, image_id, glance_host,
|
||||||
glance_port, glance_use_ssl, auth_token):
|
glance_port, glance_use_ssl, extra_headers):
|
||||||
"""Download the tarball image from Glance and extract it into the staging
|
"""Download the tarball image from Glance and extract it into the staging
|
||||||
area. Retry if there is any failure.
|
area. Retry if there is any failure.
|
||||||
"""
|
"""
|
||||||
# Build request headers
|
|
||||||
headers = {}
|
|
||||||
if auth_token:
|
|
||||||
headers['x-auth-token'] = auth_token
|
|
||||||
|
|
||||||
if glance_use_ssl:
|
if glance_use_ssl:
|
||||||
scheme = 'https'
|
scheme = 'https'
|
||||||
else:
|
else:
|
||||||
@ -107,7 +102,7 @@ def _download_tarball(sr_path, staging_path, image_id, glance_host,
|
|||||||
"%(image_id)s" % locals())
|
"%(image_id)s" % locals())
|
||||||
logging.info("Downloading %s" % url)
|
logging.info("Downloading %s" % url)
|
||||||
|
|
||||||
request = urllib2.Request(url, headers=headers)
|
request = urllib2.Request(url, headers=extra_headers)
|
||||||
try:
|
try:
|
||||||
_download_tarball_and_verify(request, staging_path)
|
_download_tarball_and_verify(request, staging_path)
|
||||||
except Exception:
|
except Exception:
|
||||||
@ -116,7 +111,7 @@ def _download_tarball(sr_path, staging_path, image_id, glance_host,
|
|||||||
|
|
||||||
|
|
||||||
def _upload_tarball(staging_path, image_id, glance_host, glance_port,
|
def _upload_tarball(staging_path, image_id, glance_host, glance_port,
|
||||||
glance_use_ssl, auth_token, properties):
|
glance_use_ssl, extra_headers, properties):
|
||||||
"""
|
"""
|
||||||
Create a tarball of the image and then stream that into Glance
|
Create a tarball of the image and then stream that into Glance
|
||||||
using chunked-transfer-encoded HTTP.
|
using chunked-transfer-encoded HTTP.
|
||||||
@ -166,9 +161,7 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
|
|||||||
'x-image-meta-container-format': 'ovf',
|
'x-image-meta-container-format': 'ovf',
|
||||||
'x-glance-registry-purge-props': 'False'}
|
'x-glance-registry-purge-props': 'False'}
|
||||||
|
|
||||||
# If we have an auth_token, set an x-auth-token header
|
headers.update(**extra_headers)
|
||||||
if auth_token:
|
|
||||||
headers['x-auth-token'] = auth_token
|
|
||||||
|
|
||||||
for key, value in properties.iteritems():
|
for key, value in properties.iteritems():
|
||||||
header_key = "x-image-meta-property-%s" % key.replace('_', '-')
|
header_key = "x-image-meta-property-%s" % key.replace('_', '-')
|
||||||
@ -229,7 +222,7 @@ def _upload_tarball(staging_path, image_id, glance_host, glance_port,
|
|||||||
|
|
||||||
|
|
||||||
def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
||||||
uuid_stack, sr_path, auth_token):
|
uuid_stack, sr_path, extra_headers):
|
||||||
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
"""Download an image from Glance, unbundle it, and then deposit the VHDs
|
||||||
into the storage repository
|
into the storage repository
|
||||||
"""
|
"""
|
||||||
@ -238,7 +231,7 @@ def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
|||||||
# Download tarball into staging area and extract it
|
# Download tarball into staging area and extract it
|
||||||
_download_tarball(
|
_download_tarball(
|
||||||
sr_path, staging_path, image_id, glance_host, glance_port,
|
sr_path, staging_path, image_id, glance_host, glance_port,
|
||||||
glance_use_ssl, auth_token)
|
glance_use_ssl, extra_headers)
|
||||||
|
|
||||||
# Move the VHDs from the staging area into the storage repository
|
# Move the VHDs from the staging area into the storage repository
|
||||||
return utils.import_vhds(sr_path, staging_path, uuid_stack)
|
return utils.import_vhds(sr_path, staging_path, uuid_stack)
|
||||||
@ -247,14 +240,14 @@ def download_vhd(session, image_id, glance_host, glance_port, glance_use_ssl,
|
|||||||
|
|
||||||
|
|
||||||
def upload_vhd(session, vdi_uuids, image_id, glance_host, glance_port,
|
def upload_vhd(session, vdi_uuids, image_id, glance_host, glance_port,
|
||||||
glance_use_ssl, sr_path, auth_token, properties):
|
glance_use_ssl, sr_path, extra_headers, properties):
|
||||||
"""Bundle the VHDs comprising an image and then stream them into Glance.
|
"""Bundle the VHDs comprising an image and then stream them into Glance.
|
||||||
"""
|
"""
|
||||||
staging_path = utils.make_staging_area(sr_path)
|
staging_path = utils.make_staging_area(sr_path)
|
||||||
try:
|
try:
|
||||||
utils.prepare_staging_area(sr_path, staging_path, vdi_uuids)
|
utils.prepare_staging_area(sr_path, staging_path, vdi_uuids)
|
||||||
_upload_tarball(staging_path, image_id, glance_host, glance_port,
|
_upload_tarball(staging_path, image_id, glance_host, glance_port,
|
||||||
glance_use_ssl, auth_token, properties)
|
glance_use_ssl, extra_headers, properties)
|
||||||
finally:
|
finally:
|
||||||
utils.cleanup_staging_area(staging_path)
|
utils.cleanup_staging_area(staging_path)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user