summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--glance/api/v1/images.py26
-rw-r--r--glance/tests/functional/v1/test_copy_to_file.py28
-rw-r--r--glance/tests/unit/v1/test_api.py6
3 files changed, 41 insertions, 19 deletions
diff --git a/glance/api/v1/images.py b/glance/api/v1/images.py
index 15ec91201..3b460272f 100644
--- a/glance/api/v1/images.py
+++ b/glance/api/v1/images.py
@@ -417,17 +417,20 @@ class Controller(controller.BaseController):
"""
External sources (as specified via the location or copy-from headers)
are supported only over non-local store types, i.e. S3, Swift, HTTP.
- Note the absence of file:// for security reasons, see LP bug #942118.
+ Note the absence of 'file://' for security reasons, see LP bug #942118.
+ 'swift+config://' is also absent for security reasons, see LP bug
+ #1334196.
If the above constraint is violated, we reject with 400 "Bad Request".
"""
if source:
pieces = urlparse.urlparse(source)
schemes = [scheme for scheme in store.get_known_schemes()
- if scheme != 'file']
+ if scheme != 'file' and scheme != 'swift+config']
for scheme in schemes:
if pieces.scheme == scheme:
return source
- msg = "External sourcing not supported for store %s" % source
+ msg = ("External sourcing not supported for "
+ "store '%s'" % pieces.scheme)
LOG.debug(msg)
raise HTTPBadRequest(explanation=msg,
request=req,
@@ -743,18 +746,17 @@ class Controller(controller.BaseController):
self.pool.spawn_n(self._upload_and_activate, req, image_meta)
else:
if location:
- try:
- store.validate_location(location, context=req.context)
- except store.BadStoreUri as bse:
- raise HTTPBadRequest(explanation=bse.msg,
- request=req)
-
self._validate_image_for_activation(req, image_id, image_meta)
image_size_meta = image_meta.get('size')
if image_size_meta:
- image_size_store = store.get_size_from_backend(
- location,
- context=req.context)
+ try:
+ image_size_store = store.get_size_from_backend(
+ location, req.context)
+ except (store.BadStoreUri, store.UnknownScheme) as e:
+ LOG.debug(utils.exception_to_str(e))
+ raise HTTPBadRequest(explanation=e.msg,
+ request=req,
+ content_type="text/plain")
# NOTE(zhiyan): A returned size of zero usually means
# the driver encountered an error. In this case the
# size provided by the client will be used as-is.
diff --git a/glance/tests/functional/v1/test_copy_to_file.py b/glance/tests/functional/v1/test_copy_to_file.py
index ae2c32051..15bb7081c 100644
--- a/glance/tests/functional/v1/test_copy_to_file.py
+++ b/glance/tests/functional/v1/test_copy_to_file.py
@@ -250,7 +250,33 @@ class TestCopyToFile(functional.FunctionalTest):
response, content = http.request(path, 'POST', headers=headers)
self.assertEqual(response.status, 400, content)
- expected = 'External sourcing not supported for store ' + copy_from
+ expected = 'External sourcing not supported for store \'file\''
+ msg = 'expected "%s" in "%s"' % (expected, content)
+ self.assertTrue(expected in content, msg)
+
+ self.stop_servers()
+
+ @skip_if_disabled
+ def test_copy_from_swift_config(self):
+ """
+ Ensure we can't copy from swift+config
+ """
+ self.cleanup()
+
+ self.start_servers(**self.__dict__.copy())
+
+ # POST /images with public image copied from file (to file)
+ headers = {'X-Image-Meta-Name': 'copied',
+ 'X-Image-Meta-disk_format': 'raw',
+ 'X-Image-Meta-container_format': 'ovf',
+ 'X-Image-Meta-Is-Public': 'True',
+ 'X-Glance-API-Copy-From': 'swift+config://xxx'}
+ path = "http://%s:%d/v1/images" % ("127.0.0.1", self.api_port)
+ http = httplib2.Http()
+ response, content = http.request(path, 'POST', headers=headers)
+ self.assertEqual(response.status, 400, content)
+
+ expected = 'External sourcing not supported for store \'swift+config\''
msg = 'expected "%s" in "%s"' % (expected, content)
self.assertTrue(expected in content, msg)
diff --git a/glance/tests/unit/v1/test_api.py b/glance/tests/unit/v1/test_api.py
index 8d2d68951..fa7f220e6 100644
--- a/glance/tests/unit/v1/test_api.py
+++ b/glance/tests/unit/v1/test_api.py
@@ -91,7 +91,6 @@ class TestGlanceAPI(base.IsolatedUnitTest):
'metadata': {}, 'status': 'active'}],
'properties': {}}]
self.context = glance.context.RequestContext(is_admin=True)
- store.validate_location = mock.Mock()
db_api.get_engine()
self.destroy_fixtures()
self.create_fixtures()
@@ -1009,11 +1008,6 @@ class TestGlanceAPI(base.IsolatedUnitTest):
def test_add_location_with_invalid_location(self):
"""Tests creates an image from location and conflict image size"""
-
- mock_validate_location = mock.Mock()
- store.validate_location = mock_validate_location
- mock_validate_location.side_effect = store.BadStoreUri()
-
fixture_headers = {'x-image-meta-store': 'file',
'x-image-meta-disk-format': 'vhd',
'x-image-meta-location': 'http://a/b/c.tar.gz',