diff --git a/ceilometer/compute/notifications.py b/ceilometer/compute/notifications.py index 0b7e8cc26..af39c4e21 100644 --- a/ceilometer/compute/notifications.py +++ b/ceilometer/compute/notifications.py @@ -1,8 +1,10 @@ # -*- encoding: utf-8 -*- # # Copyright © 2012 New Dream Network, LLC (DreamHost) +# Copyright © 2013 eNovance # # Author: Doug Hellmann +# Julien Danjou # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -23,6 +25,7 @@ from oslo.config import cfg from ceilometer.compute import instance from ceilometer import counter from ceilometer import plugin +from ceilometer import utils OPTS = [ @@ -35,23 +38,7 @@ OPTS = [ cfg.CONF.register_opts(OPTS) -class _Base(plugin.NotificationBase): - """Convert compute.instance.* notifications into Counters - """ - metadata_keys = instance.INSTANCE_PROPERTIES - - def notification_to_metadata(self, event): - metadata = super(_Base, self).notification_to_metadata(event) - metadata['instance_type'] = event['payload']['instance_type_id'] - return metadata - - @staticmethod - def get_event_types(): - return ['compute.instance.create.end', - 'compute.instance.exists', - 'compute.instance.delete.start', - 'compute.instance.finish_resize.end', - 'compute.instance.resize.revert.end'] +class ComputeNotificationBase(plugin.NotificationBase): @staticmethod def get_exchange_topics(conf): @@ -65,7 +52,61 @@ class _Base(plugin.NotificationBase): ] -class Instance(_Base): +class InstanceScheduled(ComputeNotificationBase): + + metadata_keys = ['request_spec'] + + @staticmethod + def get_event_types(): + return ['scheduler.run_instance.scheduled'] + + def notification_to_metadata(self, event): + metadata = super(InstanceScheduled, + self).notification_to_metadata(event) + metadata['weighted_host'] = event['payload']['weighted_host']['host'] + metadata['weight'] = event['payload']['weighted_host']['weight'] + return metadata + + def process_notification(self, message): + return [ + counter.Counter( + name='instance.scheduled', + type=counter.TYPE_DELTA, + volume=1, + unit='instance', + user_id=None, + project_id= + message['payload']['request_spec'] + ['instance_properties']['project_id'], + resource_id=message['payload']['instance_id'], + timestamp=message['timestamp'], + resource_metadata=dict( + utils.recursive_keypairs(message['payload'])), + ) + ] + + +class ComputeInstanceNotificationBase(ComputeNotificationBase): + """Convert compute.instance.* notifications into Counters + """ + metadata_keys = instance.INSTANCE_PROPERTIES + + def notification_to_metadata(self, event): + metadata = super(ComputeInstanceNotificationBase, + self).notification_to_metadata(event) + metadata['instance_type'] = event['payload']['instance_type_id'] + return metadata + + @staticmethod + def get_event_types(): + return ['compute.instance.create.end', + 'compute.instance.exists', + 'compute.instance.delete.start', + 'compute.instance.finish_resize.end', + 'compute.instance.resize.revert.end'] + + +class Instance(ComputeInstanceNotificationBase): def process_notification(self, message): return [ @@ -83,7 +124,7 @@ class Instance(_Base): ] -class Memory(_Base): +class Memory(ComputeInstanceNotificationBase): def process_notification(self, message): return [ @@ -100,7 +141,7 @@ class Memory(_Base): ] -class VCpus(_Base): +class VCpus(ComputeInstanceNotificationBase): def process_notification(self, message): return [ @@ -117,7 +158,7 @@ class VCpus(_Base): ] -class RootDiskSize(_Base): +class RootDiskSize(ComputeInstanceNotificationBase): def process_notification(self, message): return [ @@ -134,7 +175,7 @@ class RootDiskSize(_Base): ] -class EphemeralDiskSize(_Base): +class EphemeralDiskSize(ComputeInstanceNotificationBase): def process_notification(self, message): return [ @@ -151,7 +192,7 @@ class EphemeralDiskSize(_Base): ] -class InstanceFlavor(_Base): +class InstanceFlavor(ComputeInstanceNotificationBase): def process_notification(self, message): counters = [] @@ -174,7 +215,7 @@ class InstanceFlavor(_Base): return counters -class InstanceDelete(_Base): +class InstanceDelete(ComputeInstanceNotificationBase): """Handle the messages sent by the nova notifier plugin when an instance is being deleted. """ diff --git a/tests/compute/test_notifications.py b/tests/compute/test_notifications.py index ba5d59d3e..4d1202c2d 100644 --- a/tests/compute/test_notifications.py +++ b/tests/compute/test_notifications.py @@ -1,8 +1,10 @@ # -*- encoding: utf-8 -*- # # Copyright © 2012 New Dream Network, LLC (DreamHost) +# Copyright © 2013 eNovance # # Author: Doug Hellmann +# Julien Danjou # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain @@ -351,6 +353,51 @@ INSTANCE_DELETE_SAMPLES = { } +INSTANCE_SCHEDULED = { + u'_context_roles': [u'admin'], + u'_context_request_id': u'req-9da1d714-dabe-42fd-8baa-583e57cd4f1a', + u'_context_quota_class': None, + u'event_type': u'scheduler.run_instance.scheduled', + u'_context_user_name': u'admin', + u'_context_project_name': u'admin', + u'timestamp': u'2013-01-04 15:20:32.009532', + u'_context_is_admin': True, + u'message_id': u'c48deeba-d0c3-4154-b3db-47480b52267a', + u'_context_auth_token': None, + u'_context_instance_lock_checked': False, + u'_context_project_id': u'cea4b25edb484e5392727181b7721d29', + u'_context_timestamp': u'2013-01-04T15:19:51.018218', + u'_context_read_deleted': u'no', + u'_context_user_id': u'01b83a5e23f24a6fb6cd073c0aee6eed', + u'_context_remote_address': u'10.147.132.184', + u'publisher_id': u'compute.ip-10-147-132-184.ec2.internal', + u'payload': { + 'instance_id': 'fake-uuid1-1', + 'weighted_host': { + 'host': 'host3', + 'weight': 3.0, + }, + 'request_spec': { + 'instance_properties': { + 'root_gb': 512, + 'ephemeral_gb': 0, + 'launch_index': 0, + 'memory_mb': 512, + 'vcpus': 1, + 'os_type': 'Linux', + 'project_id': 1, + 'system_metadata': {'system': 'metadata'}}, + 'instance_type': {'memory_mb': 512, + 'vcpus': 1, + 'root_gb': 512, + 'ephemeral_gb': 0}, + 'instance_uuids': ['fake-uuid1-1'], + }, + }, + u'priority': u'INFO' +} + + class TestNotifications(base.TestCase): def test_process_notification(self): @@ -507,3 +554,16 @@ class TestNotifications(base.TestCase): self.assertEqual(len(counters), 2) names = [c.name for c in counters] self.assertEqual(names, ['sample-name1', 'sample-name2']) + + def test_instance_scheduled(self): + ic = notifications.InstanceScheduled() + + self.assertIn(INSTANCE_SCHEDULED['event_type'], + ic.get_event_types()) + + counters = ic.process_notification(INSTANCE_SCHEDULED) + self.assertEqual(len(counters), 1) + names = [c.name for c in counters] + self.assertEqual(names, ['instance.scheduled']) + rid = [c.resource_id for c in counters] + self.assertEqual(rid, ['fake-uuid1-1'])