Merge "Fix case-sensitivity for metadata keys" into stable/2025.1
This commit is contained in:
@@ -258,7 +258,8 @@ class AggregateController(wsgi.Controller):
|
||||
id, metadata)
|
||||
except exception.AggregateNotFound as e:
|
||||
raise exc.HTTPNotFound(explanation=e.format_message())
|
||||
except exception.InvalidAggregateAction as e:
|
||||
except (exception.InvalidAggregateAction,
|
||||
exception.AggregateMetadataKeyExists) as e:
|
||||
raise exc.HTTPBadRequest(explanation=e.format_message())
|
||||
|
||||
return self._marshall_aggregate(req, aggregate)
|
||||
|
@@ -482,6 +482,12 @@ class InvalidAggregateActionUpdateMeta(InvalidAggregateAction):
|
||||
"%(aggregate_id)s. Reason: %(reason)s.")
|
||||
|
||||
|
||||
class AggregateMetadataKeyExists(NovaException):
|
||||
msg_fmt = _("Aggregate %(aggregate_id)s already contain metadata "
|
||||
"key %(key)s.")
|
||||
code = 400
|
||||
|
||||
|
||||
class InvalidSortKey(Invalid):
|
||||
msg_fmt = _("Sort key supplied was not valid.")
|
||||
|
||||
|
@@ -113,8 +113,15 @@ def _metadata_add_to_db(context, aggregate_id, metadata, max_retries=10,
|
||||
api_models.AggregateMetadata.key.in_(all_keys))
|
||||
for meta_ref in query.all():
|
||||
key = meta_ref.key
|
||||
meta_ref.update({"value": metadata[key]})
|
||||
already_existing_keys.add(key)
|
||||
try:
|
||||
meta_ref.update({"value": metadata[key]})
|
||||
already_existing_keys.add(key)
|
||||
except KeyError:
|
||||
# NOTE(ratailor): When user tries updating
|
||||
# metadata using case-sensitive key, we get
|
||||
# KeyError.
|
||||
raise exception.AggregateMetadataKeyExists(
|
||||
aggregate_id=aggregate_id, key=key)
|
||||
|
||||
new_entries = []
|
||||
for key, value in metadata.items():
|
||||
|
@@ -675,6 +675,19 @@ class AggregateTestCaseV21(test.NoDBTestCase):
|
||||
self.assertRaises(self.bad_request, eval(self.set_metadata),
|
||||
self.req, "1", body=body)
|
||||
|
||||
def test_set_metadata_case_sensitive(self):
|
||||
body = {"set_metadata": {"metadata": {"foo": "bar"}}}
|
||||
side_effect = exception.AggregateMetadataKeyExists(
|
||||
aggregate_id="2", key="foo")
|
||||
|
||||
with mock.patch.object(self.controller.api,
|
||||
'update_aggregate_metadata',
|
||||
side_effect=side_effect) as mock_update:
|
||||
self.assertRaises(exc.HTTPBadRequest, eval(self.set_metadata),
|
||||
self.req, "2", body=body)
|
||||
mock_update.assert_called_once_with(
|
||||
self.context, "2", body["set_metadata"]["metadata"])
|
||||
|
||||
def test_delete_aggregate(self):
|
||||
with mock.patch.object(self.controller.api,
|
||||
'delete_aggregate') as mock_del:
|
||||
|
@@ -175,6 +175,30 @@ class _TestAggregateObject(object):
|
||||
123,
|
||||
{'toadd': 'myval'})
|
||||
|
||||
@mock.patch('nova.compute.utils.notify_about_aggregate_action')
|
||||
def test_update_metadata_api_case_sensitive(self, mock_notify):
|
||||
# Mock context.session.query().filter_by().filter().all()
|
||||
fake_context = mock.Mock()
|
||||
mock_query = mock.Mock()
|
||||
fake_context.session.query.return_value = mock_query
|
||||
mock_query = mock_query.filter_by.return_value.filter.return_value
|
||||
|
||||
# Return a fake meta_ref that raises a KeyError
|
||||
fake_meta_ref = mock.Mock()
|
||||
fake_meta_ref.update.side_effect = KeyError
|
||||
mock_query.all.return_value = [fake_meta_ref]
|
||||
|
||||
# Create an aggregate in the database
|
||||
agg = aggregate.Aggregate(
|
||||
context=self.context, name='agg', metadata={'Abc': 'bar'})
|
||||
agg.create()
|
||||
|
||||
# Then replace its context with mock context
|
||||
agg._context = fake_context
|
||||
self.assertRaises(exception.AggregateMetadataKeyExists,
|
||||
agg.update_metadata,
|
||||
{'abC': 'barbar'})
|
||||
|
||||
@mock.patch('nova.objects.aggregate._host_add_to_db')
|
||||
def test_add_host_api(self, mock_host_add_api):
|
||||
mock_host_add_api.return_value = {'host': 'bar'}
|
||||
|
Reference in New Issue
Block a user