diff --git a/nova/api/metadata/handler.py b/nova/api/metadata/handler.py index 27f4d4e1b210..7ac902304d6f 100644 --- a/nova/api/metadata/handler.py +++ b/nova/api/metadata/handler.py @@ -147,6 +147,7 @@ class MetadataRequestHandler(wsgi.Application): def _handle_instance_id_request(self, req): instance_id = req.headers.get('X-Instance-ID') + tenant_id = req.headers.get('X-Tenant-ID') signature = req.headers.get('X-Instance-ID-Signature') remote_address = req.headers.get('X-Forwarded-For') @@ -154,8 +155,12 @@ class MetadataRequestHandler(wsgi.Application): if instance_id is None: msg = _('X-Instance-ID header is missing from request.') + elif tenant_id is None: + msg = _('X-Tenant-ID header is missing from request.') elif not isinstance(instance_id, basestring): msg = _('Multiple X-Instance-ID headers found within request.') + elif not isinstance(tenant_id, basestring): + msg = _('Multiple X-Tenant-ID headers found within request.') else: msg = None @@ -195,4 +200,12 @@ class MetadataRequestHandler(wsgi.Application): LOG.error(_('Failed to get metadata for instance id: %s'), instance_id) + if meta_data.instance['project_id'] != tenant_id: + LOG.warning(_("Tenant_id %(tenant_id)s does not match tenant_id " + "of instance %(instance_id)s."), + {'tenant_id': tenant_id, + 'instance_id': instance_id}) + # causes a 404 to be raised + meta_data = None + return meta_data diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index 50f0d07f7a9b..e75b51f86737 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -601,6 +601,7 @@ class MetadataHandlerTestCase(test.TestCase): relpath="/2009-04-04/user-data", address="192.192.192.2", headers={'X-Instance-ID': 'a-b-c-d', + 'X-Tenant-ID': 'test', 'X-Instance-ID-Signature': signed}) self.assertEqual(response.status_int, 200) @@ -613,6 +614,7 @@ class MetadataHandlerTestCase(test.TestCase): fake_get_metadata_by_instance_id=fake_get_metadata, headers={'X-Forwarded-For': '192.192.192.2', 'X-Instance-ID': 'a-b-c-d', + 'X-Tenant-ID': 'test', 'X-Instance-ID-Signature': signed}) self.assertEqual(response.status_int, 200) @@ -627,10 +629,36 @@ class MetadataHandlerTestCase(test.TestCase): fake_get_metadata_by_instance_id=fake_get_metadata, headers={'X-Forwarded-For': '192.192.192.2', 'X-Instance-ID': 'a-b-c-d', + 'X-Tenant-ID': 'test', 'X-Instance-ID-Signature': ''}) self.assertEqual(response.status_int, 403) + # missing X-Tenant-ID from request + response = fake_request( + self.stubs, self.mdinst, + relpath="/2009-04-04/user-data", + address="192.192.192.2", + fake_get_metadata_by_instance_id=fake_get_metadata, + headers={'X-Forwarded-For': '192.192.192.2', + 'X-Instance-ID': 'a-b-c-d', + 'X-Instance-ID-Signature': signed}) + + self.assertEqual(response.status_int, 400) + + # mismatched X-Tenant-ID + response = fake_request( + self.stubs, self.mdinst, + relpath="/2009-04-04/user-data", + address="192.192.192.2", + fake_get_metadata_by_instance_id=fake_get_metadata, + headers={'X-Forwarded-For': '192.192.192.2', + 'X-Instance-ID': 'a-b-c-d', + 'X-Tenant-ID': 'FAKE', + 'X-Instance-ID-Signature': signed}) + + self.assertEqual(response.status_int, 404) + # without X-Forwarded-For response = fake_request( self.stubs, self.mdinst, @@ -638,6 +666,7 @@ class MetadataHandlerTestCase(test.TestCase): address="192.192.192.2", fake_get_metadata_by_instance_id=fake_get_metadata, headers={'X-Instance-ID': 'a-b-c-d', + 'X-Tenant-ID': 'test', 'X-Instance-ID-Signature': signed}) self.assertEqual(response.status_int, 500) @@ -655,6 +684,7 @@ class MetadataHandlerTestCase(test.TestCase): fake_get_metadata_by_instance_id=fake_get_metadata, headers={'X-Forwarded-For': '192.192.192.2', 'X-Instance-ID': 'z-z-z-z', + 'X-Tenant-ID': 'test', 'X-Instance-ID-Signature': signed}) self.assertEqual(response.status_int, 500)