Merge "Update notification for flavor"

This commit is contained in:
Jenkins 2017-01-11 21:58:06 +00:00 committed by Gerrit Code Review
commit 0308c00d0d
46 changed files with 207 additions and 45 deletions

View File

@ -2,7 +2,7 @@
"priority": "INFO",
"payload": {
"nova_object.namespace": "nova",
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.name": "FlavorPayload",
"nova_object.data": {
"name": "test_flavor",

View File

@ -2,7 +2,7 @@
"priority": "INFO",
"payload": {
"nova_object.namespace": "nova",
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.name": "FlavorPayload",
"nova_object.data": {
"name": "test_flavor",

View File

@ -0,0 +1,28 @@
{
"priority": "INFO",
"payload": {
"nova_object.namespace": "nova",
"nova_object.version": "1.2",
"nova_object.name": "FlavorPayload",
"nova_object.data": {
"name": "test_flavor",
"memory_mb": 1024,
"ephemeral_gb": 0,
"disabled": false,
"vcpus": 2,
"extra_specs": {
"key1": "value1",
"key2": "value2"
},
"projects": ["fake_tenant"],
"swap": 0,
"rxtx_factor": 2.0,
"is_public": false,
"root_gb": 10,
"vcpu_weight": 0,
"flavorid": "a22d5517-147c-4147-a0d1-e698df5cd4e3"
}
},
"event_type": "flavor.update",
"publisher_id": "nova-api:fake-mini"
}

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -48,11 +48,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -38,11 +38,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -38,11 +38,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 256,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 256,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -51,11 +51,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id":"fake",

View File

@ -56,11 +56,12 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.version": "1.1",
"nova_object.version": "1.2",
"nova_object.namespace": "nova"
},
"user_id": "fake",

View File

@ -19,13 +19,14 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.name": "FlavorPayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.1"
"nova_object.version": "1.2"
},
"host": "compute",
"host_name": "some-server",

View File

@ -29,13 +29,14 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.name": "FlavorPayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.1"
"nova_object.version": "1.2"
},
"host": "compute",
"host_name": "some-server",

View File

@ -19,13 +19,14 @@
"memory_mb": 512,
"disabled": false,
"rxtx_factor": 1.0,
"extra_specs": {},
"swap": 0,
"is_public": true,
"vcpu_weight": 0
},
"nova_object.name": "FlavorPayload",
"nova_object.namespace": "nova",
"nova_object.version": "1.1"
"nova_object.version": "1.2"
},
"host": "compute",
"host_name": "some-server",

View File

@ -18,6 +18,7 @@ from nova.objects import fields
@base.notification_sample('flavor-create.json')
@base.notification_sample('flavor-update.json')
@base.notification_sample('flavor-delete.json')
@nova_base.NovaObjectRegistry.register_notification
class FlavorNotification(base.NotificationBase):
@ -33,7 +34,8 @@ class FlavorNotification(base.NotificationBase):
class FlavorPayload(base.NotificationPayloadBase):
# Version 1.0: Initial version
# Version 1.1: Add other fields for Flavor
VERSION = '1.1'
# Version 1.2: Add extra_specs and projects fields
VERSION = '1.2'
# NOTE: if we'd want to rename some fields(memory_mb->ram, root_gb->disk,
# ephemeral_gb: ephemeral), bumping to payload version 2.0 will be needed.
@ -49,6 +51,8 @@ class FlavorPayload(base.NotificationPayloadBase):
'vcpu_weight': ('flavor', 'vcpu_weight'),
'disabled': ('flavor', 'disabled'),
'is_public': ('flavor', 'is_public'),
'extra_specs': ('flavor', 'extra_specs'),
'projects': ('flavor', 'projects'),
}
fields = {
@ -63,6 +67,8 @@ class FlavorPayload(base.NotificationPayloadBase):
'vcpu_weight': fields.IntegerField(nullable=True),
'disabled': fields.BooleanField(),
'is_public': fields.BooleanField(),
'extra_specs': fields.DictOfStringsField(),
'projects': fields.ListOfStringsField(),
}
def __init__(self, flavor, **kwargs):
@ -80,3 +86,6 @@ class FlavorPayload(base.NotificationPayloadBase):
primitive.pop('vcpu_weight', None)
primitive.pop('disabled', None)
primitive.pop('is_public', None)
if target_version < (1, 2):
primitive.pop('extra_specs', None)
primitive.pop('projects', None)

View File

@ -448,6 +448,7 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
reason='projects modified')
self._add_access(project_id)
self._load_projects()
self._send_notification(fields.NotificationAction.UPDATE)
def _remove_access(self, project_id):
if self.in_api:
@ -462,6 +463,7 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
reason='projects modified')
self._remove_access(project_id)
self._load_projects()
self._send_notification(fields.NotificationAction.UPDATE)
@staticmethod
def _flavor_create(context, updates):
@ -579,6 +581,9 @@ class Flavor(base.NovaPersistentObject, base.NovaObject,
if added_projects or deleted_projects:
self.save_projects(added_projects, deleted_projects)
if added_keys or deleted_keys or added_projects or deleted_projects:
self._send_notification(fields.NotificationAction.UPDATE)
@staticmethod
def _flavor_destroy(context, flavor_id=None, flavorid=None):
return _flavor_destroy(context, flavor_id=flavor_id, flavorid=flavorid)

View File

@ -49,3 +49,40 @@ class TestFlavorNotificationSample(
'flavors/a22d5517-147c-4147-a0d1-e698df5cd4e3')
self._verify_notification(
'flavor-delete', actual=fake_notifier.VERSIONED_NOTIFICATIONS[1])
def test_flavor_update(self):
body = {
"flavor": {
"name": "test_flavor",
"ram": 1024,
"vcpus": 2,
"disk": 10,
"id": "a22d5517-147c-4147-a0d1-e698df5cd4e3",
"os-flavor-access:is_public": False,
"rxtx_factor": 2.0
}
}
# Create a flavor.
self.admin_api.api_post('flavors', body)
body = {
"extra_specs": {
"key1": "value1",
"key2": "value2"
}
}
self.admin_api.api_post(
'flavors/a22d5517-147c-4147-a0d1-e698df5cd4e3/os-extra_specs',
body)
body = {
"addTenantAccess": {
"tenant": "fake_tenant"
}
}
self.admin_api.api_post(
'flavors/a22d5517-147c-4147-a0d1-e698df5cd4e3/action',
body)
self._verify_notification(
'flavor-update', actual=fake_notifier.VERSIONED_NOTIFICATIONS[2])

View File

@ -28,14 +28,20 @@ class TestFlavorNotification(test.TestCase):
@mock.patch('nova.notifications.objects.flavor.FlavorNotification')
def _verify_notification(self, flavor_obj, flavor, action,
mock_notification):
mock_notification, project_id=None):
notification = mock_notification
if action == "CREATE":
flavor_obj.create()
elif action == "DELETE":
flavor_obj.destroy()
elif action == "ADD_ACCESS":
action = "UPDATE"
flavor_obj.add_access(project_id)
elif action == "REMOVE_ACCESS":
action = "UPDATE"
flavor_obj.remove_access(project_id)
else:
raise Exception('Unsupported action: %s' % action)
flavor_obj.save()
self.assertTrue(notification.called)
@ -68,6 +74,39 @@ class TestFlavorNotification(test.TestCase):
mock_create.return_value = flavor
self._verify_notification(flavor_obj, flavor, 'CREATE')
@mock.patch('nova.objects.Flavor._flavor_extra_specs_del')
def test_flavor_update_with_notification(self, mock_delete):
flavor = copy.deepcopy(fake_flavor)
flavorid = '1'
flavor['flavorid'] = flavorid
flavor['id'] = flavorid
flavor_obj = objects.Flavor(context=self.ctxt, **flavor)
flavor_obj.obj_reset_changes()
del flavor_obj.extra_specs['foo']
del flavor['extra_specs']['foo']
self._verify_notification(flavor_obj, flavor, "UPDATE")
projects = ['project-1', 'project-2']
flavor_obj.projects = projects
flavor['projects'] = projects
self._verify_notification(flavor_obj, flavor, "UPDATE")
@mock.patch('nova.objects.Flavor._add_access')
@mock.patch('nova.objects.Flavor._remove_access')
def test_flavor_access_with_notification(self, mock_remove_access,
mock_add_access):
flavor = copy.deepcopy(fake_flavor)
flavorid = '1'
flavor['flavorid'] = flavorid
flavor['id'] = flavorid
flavor_obj = objects.Flavor(context=self.ctxt, **flavor)
flavor_obj.obj_reset_changes()
self._verify_notification(flavor_obj, flavor, "ADD_ACCESS",
project_id="project1")
self._verify_notification(flavor_obj, flavor, "REMOVE_ACCESS",
project_id="project1")
@mock.patch('nova.objects.Flavor._flavor_destroy')
def test_flavor_destroy_with_notification(self, mock_destroy):
flavor = copy.deepcopy(fake_flavor)

View File

@ -265,7 +265,7 @@ notification_object_data = {
'ExceptionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'ExceptionPayload': '1.0-27db46ee34cd97e39f2643ed92ad0cc5',
'FlavorNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'FlavorPayload': '1.1-e3892169e2c946f6784fe130deaeae4f',
'FlavorPayload': '1.2-6f73fa3dc2d5f7abff1a27aac70b8759',
'InstanceActionNotification': '1.0-a73147b93b520ff0061865849d3dfa56',
'InstanceActionPayload': '1.1-8d12efc3251c606b61b3d479a9da51be',
'InstanceActionVolumeSwapNotification':

View File

@ -1,4 +1,11 @@
---
features:
- Support versioned notifications for flavor operations like create and
delete.
- Support versioned notifications for flavor operations like create, delete,
update access and update extra_specs.
issues:
- |
Flavor.projects (access) will not be present in the instance versioned
notifications since notifications currently do not lazy-load fields. This
limitation is being tracked with `bug 1653221`_.
.. _bug 1653221: https://bugs.launchpad.net/nova/+bug/1653221