diff --git a/glance/async_/flows/plugins/inject_image_metadata.py b/glance/async_/flows/plugins/inject_image_metadata.py index 24010a86ba..7b76b0834a 100644 --- a/glance/async_/flows/plugins/inject_image_metadata.py +++ b/glance/async_/flows/plugins/inject_image_metadata.py @@ -54,12 +54,12 @@ CONF.register_opts(inject_metadata_opts, group='inject_metadata_properties') class _InjectMetadataProperties(task.Task): - def __init__(self, context, task_id, task_type, image_repo, image_id): + def __init__(self, context, task_id, task_type, action_wrapper): self.context = context self.task_id = task_id self.task_type = task_type - self.image_repo = image_repo - self.image_id = image_id + self.action_wrapper = action_wrapper + self.image_id = action_wrapper.image_id super(_InjectMetadataProperties, self).__init__( name='%s-InjectMetadataProperties-%s' % (task_type, task_id)) @@ -75,9 +75,8 @@ class _InjectMetadataProperties(task.Task): properties = CONF.inject_metadata_properties.inject if properties: - image = self.image_repo.get(self.image_id) - image.extra_properties.update(properties) - self.image_repo.save(image) + with self.action_wrapper as action: + action.set_image_extra_properties(properties) def get_flow(**kwargs): @@ -91,11 +90,9 @@ def get_flow(**kwargs): """ task_id = kwargs.get('task_id') task_type = kwargs.get('task_type') - image_repo = kwargs.get('image_repo') - image_id = kwargs.get('image_id') context = kwargs.get('context') + action_wrapper = kwargs.get('action_wrapper') return lf.Flow(task_type).add( - _InjectMetadataProperties(context, task_id, task_type, image_repo, - image_id), + _InjectMetadataProperties(context, task_id, task_type, action_wrapper), ) diff --git a/glance/tests/unit/async_/flows/plugins/test_inject_image_metadata.py b/glance/tests/unit/async_/flows/plugins/test_inject_image_metadata.py index 9671bc99c5..f371b08600 100644 --- a/glance/tests/unit/async_/flows/plugins/test_inject_image_metadata.py +++ b/glance/tests/unit/async_/flows/plugins/test_inject_image_metadata.py @@ -19,6 +19,7 @@ from unittest import mock import glance_store from oslo_config import cfg +import glance.async_.flows.api_image_import as import_flow import glance.async_.flows.plugins.inject_image_metadata as inject_metadata from glance.common import utils from glance import domain @@ -75,42 +76,44 @@ class TestInjectImageMetadataTask(test_utils.BaseTestCase): self.task = self.task_factory.new_task(self.task_type, TENANT1, task_time_to_live=task_ttl, task_input=task_input) + self.image.extra_properties = { + 'os_glance_import_task': self.task.task_id} + self.img_repo.get.return_value = self.image + self.wrapper = import_flow.ImportActionWrapper(self.img_repo, + self.image_id, + self.task.task_id) def test_inject_image_metadata_using_non_admin_user(self): context = test_unit_utils.get_fake_context(roles='member') inject_image_metadata = inject_metadata._InjectMetadataProperties( - context, self.task.task_id, self.task_type, self.img_repo, - self.image_id) + context, self.task.task_id, self.task_type, self.wrapper) self.config(inject={"test": "abc"}, group='inject_metadata_properties') inject_image_metadata.execute() - self.img_repo.get.assert_called_once_with(self.image_id) - self.img_repo.save.assert_called_once_with(self.image) - self.assertEqual({"test": "abc"}, self.image.extra_properties) + self.img_repo.save.assert_called_once_with(self.image, 'queued') + self.assertEqual({"test": "abc", + "os_glance_import_task": self.task.task_id}, + self.image.extra_properties) def test_inject_image_metadata_using_admin_user(self): context = test_unit_utils.get_fake_context(roles='admin') inject_image_metadata = inject_metadata._InjectMetadataProperties( - context, self.task.task_id, self.task_type, self.img_repo, - self.image_id) + context, self.task.task_id, self.task_type, self.wrapper) self.config(inject={"test": "abc"}, group='inject_metadata_properties') inject_image_metadata.execute() - self.img_repo.get.assert_called_once_with(UUID1) - self.img_repo.save.assert_called_once_with(self.image) + self.img_repo.save.assert_called_once_with(self.image, 'queued') def test_inject_image_metadata_empty(self): context = test_unit_utils.get_fake_context(roles='member') inject_image_metadata = inject_metadata._InjectMetadataProperties( - context, self.task.task_id, self.task_type, self.img_repo, - self.image_id) + context, self.task.task_id, self.task_type, self.wrapper) self.config(inject={}, group='inject_metadata_properties') inject_image_metadata.execute() - self.img_repo.get.assert_not_called() self.img_repo.save.assert_not_called() diff --git a/releasenotes/notes/os-glance-injection-disallowed-5dad244dfb071938.yaml b/releasenotes/notes/os-glance-injection-disallowed-5dad244dfb071938.yaml new file mode 100644 index 0000000000..a6879d2585 --- /dev/null +++ b/releasenotes/notes/os-glance-injection-disallowed-5dad244dfb071938.yaml @@ -0,0 +1,10 @@ +--- +upgrade: + - | + The ``inject_image_metadata`` task will no longer allow setting + properties in the reserved ``os_glance_*`` namespace, in line with + the blanket prohibition on such via the API. It has always been + dangerous to do this, so no operator should have any such + configuration in production. If any keys in this namespace are + set, they will be dropped (and logged) during the injection + process.