From bda44d592e02d95254d14819dbf5ffaeefa9f552 Mon Sep 17 00:00:00 2001 From: liu-sheng Date: Thu, 15 May 2014 19:17:34 +0800 Subject: [PATCH] Fix network notifications of neutron bulk creation When bulk creating ports, networks, subnets in neutron, ceilometer-notification-agent will be broken and raise an KeyError. Change-Id: Id5737f8ec8aa46561fe66bd56251d2a8d55f2548 Closes-Bug: #1317900 --- ceilometer/network/notifications.py | 36 ++-- .../tests/network/test_notifications.py | 176 ++++++++++++++++++ 2 files changed, 196 insertions(+), 16 deletions(-) diff --git a/ceilometer/network/notifications.py b/ceilometer/network/notifications.py index d70c58e91..87753f416 100644 --- a/ceilometer/network/notifications.py +++ b/ceilometer/network/notifications.py @@ -19,6 +19,7 @@ events. """ +import copy from oslo.config import cfg import oslo.messaging @@ -74,32 +75,35 @@ class NetworkNotificationBase(plugin.NotificationBase): def process_notification(self, message): LOG.info(_('network notification %r') % message) - message['payload'] = message['payload'][self.resource_name] counter_name = getattr(self, 'counter_name', self.resource_name) unit_value = getattr(self, 'unit', self.resource_name) - yield sample.Sample.from_notification( - name=counter_name, - type=sample.TYPE_GAUGE, - unit=unit_value, - volume=1, - user_id=message['_context_user_id'], - project_id=message['_context_tenant_id'], - resource_id=message['payload']['id'], - message=message) - - event_type_split = message['event_type'].split('.') - if len(event_type_split) > 2: + payload = message['payload'].get(self.resource_name) + payloads = message['payload'].get(self.resource_name + 's') + payload_list = copy.copy([payload] if payload else payloads) + for p in payload_list: + message['payload'] = p yield sample.Sample.from_notification( - name=counter_name - + "." + event_type_split[1], - type=sample.TYPE_DELTA, + name=counter_name, + type=sample.TYPE_GAUGE, unit=unit_value, volume=1, user_id=message['_context_user_id'], project_id=message['_context_tenant_id'], resource_id=message['payload']['id'], message=message) + event_type_split = message['event_type'].split('.') + if len(event_type_split) > 2: + yield sample.Sample.from_notification( + name=counter_name + + "." + event_type_split[1], + type=sample.TYPE_DELTA, + unit=unit_value, + volume=1, + user_id=message['_context_user_id'], + project_id=message['_context_tenant_id'], + resource_id=message['payload']['id'], + message=message) class Network(NetworkNotificationBase): diff --git a/ceilometer/tests/network/test_notifications.py b/ceilometer/tests/network/test_notifications.py index 64653ac32..5cab884fe 100644 --- a/ceilometer/tests/network/test_notifications.py +++ b/ceilometer/tests/network/test_notifications.py @@ -46,6 +46,50 @@ NOTIFICATION_NETWORK_CREATE = { u'publisher_id': u'network.ubuntu-VirtualBox', u'message_id': u'9e839576-cc47-4c60-a7d8-5743681213b1'} +NOTIFICATION_BULK_NETWORK_CREATE = { + '_context_roles': [u'_member_', + u'heat_stack_owner', + u'admin'], + u'_context_request_id': u'req-a2dfdefd-b773-4400-9d52-5e146e119950', + u'_context_read_deleted': u'no', + u'event_type': u'network.create.end', + u'_context_user_name': u'admin', + u'_context_project_name': u'admin', + u'timestamp': u'2014-05-1510: 24: 56.335612', + u'_context_tenant_id': u'980ec4870033453ead65c0470a78b8a8', + u'_context_tenant_name': u'admin', + u'_context_tenant': u'980ec4870033453ead65c0470a78b8a8', + u'message_id': u'914eb601-9390-4a72-8629-f013a4c84467', + u'priority': 'info', + u'_context_is_admin': True, + u'_context_project_id': u'980ec4870033453ead65c0470a78b8a8', + u'_context_timestamp': u'2014-05-1510: 24: 56.285975', + u'_context_user': u'7520940056d54cceb25cbce888300bea', + u'_context_user_id': u'7520940056d54cceb25cbce888300bea', + u'publisher_id': u'network.devstack', + u'payload': { + u'networks': [{u'status': u'ACTIVE', + u'subnets': [], + u'name': u'test2', + u'provider: physical_network': None, + u'admin_state_up': True, + u'tenant_id': u'980ec4870033453ead65c0470a78b8a8', + u'provider: network_type': u'local', + u'shared': False, + u'id': u'7cbc7a66-bbd0-41fc-a186-81c3da5c9843', + u'provider: segmentation_id': None}, + {u'status': u'ACTIVE', + u'subnets': [], + u'name': u'test3', + u'provider: physical_network': None, + u'admin_state_up': True, + u'tenant_id': u'980ec4870033453ead65c0470a78b8a8', + u'provider: network_type': u'local', + u'shared': False, + u'id': u'5a7cb86f-1638-4cc1-8dcc-8bbbc8c7510d', + u'provider: segmentation_id': None}] + } +} NOTIFICATION_SUBNET_CREATE = { u'_context_roles': [u'anotherrole', @@ -75,6 +119,58 @@ NOTIFICATION_SUBNET_CREATE = { u'publisher_id': u'network.ubuntu-VirtualBox', u'message_id': u'd86dfc66-d3c3-4aea-b06d-bf37253e6116'} +NOTIFICATION_BULK_SUBNET_CREATE = { + '_context_roles': [u'_member_', + u'heat_stack_owner', + u'admin'], + u'_context_request_id': u'req-b77e278a-0cce-4987-9f82-15957b234768', + u'_context_read_deleted': u'no', + u'event_type': u'subnet.create.end', + u'_context_user_name': u'admin', + u'_context_project_name': u'admin', + u'timestamp': u'2014-05-1510: 47: 08.133888', + u'_context_tenant_id': u'980ec4870033453ead65c0470a78b8a8', + u'_context_tenant_name': u'admin', + u'_context_tenant': u'980ec4870033453ead65c0470a78b8a8', + u'message_id': u'c7e6f9fd-ead2-415f-8493-b95bedf72e43', + u'priority': u'info', + u'_context_is_admin': True, + u'_context_project_id': u'980ec4870033453ead65c0470a78b8a8', + u'_context_timestamp': u'2014-05-1510: 47: 07.970043', + u'_context_user': u'7520940056d54cceb25cbce888300bea', + u'_context_user_id': u'7520940056d54cceb25cbce888300bea', + u'publisher_id': u'network.devstack', + u'payload': { + u'subnets': [{u'name': u'', + u'enable_dhcp': True, + u'network_id': u'3ddfe60b-34b4-4e9d-9440-43c904b1c58e', + u'tenant_id': u'980ec4870033453ead65c0470a78b8a8', + u'dns_nameservers': [], + u'ipv6_ra_mode': None, + u'allocation_pools': [{u'start': u'10.0.4.2', + u'end': u'10.0.4.254'}], + u'host_routes': [], + u'ipv6_address_mode': None, + u'ip_version': 4, + u'gateway_ip': u'10.0.4.1', + u'cidr': u'10.0.4.0/24', + u'id': u'14020d7b-6dd7-4349-bb8e-8f954c919022'}, + {u'name': u'', + u'enable_dhcp': True, + u'network_id': u'3ddfe60b-34b4-4e9d-9440-43c904b1c58e', + u'tenant_id': u'980ec4870033453ead65c0470a78b8a8', + u'dns_nameservers': [], + u'ipv6_ra_mode': None, + u'allocation_pools': [{u'start': u'10.0.5.2', + u'end': u'10.0.5.254'}], + u'host_routes': [], + u'ipv6_address_mode': None, + u'ip_version': 4, + u'gateway_ip': u'10.0.5.1', + u'cidr': u'10.0.5.0/24', + u'id': u'a080991b-a32a-4bf7-a558-96c4b77d075c'}] + } +} NOTIFICATION_PORT_CREATE = { u'_context_roles': [u'anotherrole', @@ -104,6 +200,58 @@ NOTIFICATION_PORT_CREATE = { u'publisher_id': u'network.ubuntu-VirtualBox', u'message_id': u'7135b8ab-e13c-4ac8-bc31-75e7f756622a'} +NOTIFICATION_BULK_PORT_CREATE = { + u'_context_roles': [u'_member_', + u'SwiftOperator'], + u'_context_request_id': u'req-678be9ad-c399-475a-b3e8-8da0c06375aa', + u'_context_read_deleted': u'no', + u'event_type': u'port.create.end', + u'_context_project_name': u'demo', + u'timestamp': u'2014-05-0909: 19: 58.317548', + u'_context_tenant_id': u'133087d90fc149528b501dd8b75ea965', + u'_context_timestamp': u'2014-05-0909: 19: 58.160011', + u'_context_tenant': u'133087d90fc149528b501dd8b75ea965', + u'payload': { + u'ports': [{u'status': u'DOWN', + u'name': u'port--1501135095', + u'allowed_address_pairs': [], + u'admin_state_up': True, + u'network_id': u'acf63fdc-b43b-475d-8cca-9429b843d5e8', + u'tenant_id': u'133087d90fc149528b501dd8b75ea965', + u'binding: vnic_type': u'normal', + u'device_owner': u'', + u'mac_address': u'fa: 16: 3e: 37: 10: 39', + u'fixed_ips': [], + u'id': u'296c2c9f-14e9-48da-979d-78b213454c59', + u'security_groups': [ + u'a06f7c9d-9e5a-46b0-9f6c-ce812aa2e5ff'], + u'device_id': u''}, + {u'status': u'DOWN', + u'name': u'', + u'allowed_address_pairs': [], + u'admin_state_up': False, + u'network_id': u'0a8eea59-0146-425c-b470-e9ddfa99ec61', + u'tenant_id': u'133087d90fc149528b501dd8b75ea965', + u'binding: vnic_type': u'normal', + u'device_owner': u'', + u'mac_address': u'fa: 16: 3e: 8e: 6e: 53', + u'fixed_ips': [], + u'id': u'd8bb667f-5cd3-4eca-a984-268e25b1b7a5', + u'security_groups': [ + u'a06f7c9d-9e5a-46b0-9f6c-ce812aa2e5ff'], + u'device_id': u''}] + }, + u'_unique_id': u'60b1650f17fc4fa59492f447321fb26c', + u'_context_is_admin': False, + u'_context_project_id': u'133087d90fc149528b501dd8b75ea965', + u'_context_tenant_name': u'demo', + u'_context_user': u'b1eb48f9c54741f4adc1b4ea512d400c', + u'_context_user_name': u'demo', + u'publisher_id': u'network.os-ci-test12', + u'message_id': u'04aa45e1-3c30-4c69-8638-e7ff8621e9bc', + u'_context_user_id': u'b1eb48f9c54741f4adc1b4ea512d400c', + u'priority': u'INFO' +} NOTIFICATION_PORT_UPDATE = { u'_context_roles': [u'anotherrole', @@ -257,18 +405,46 @@ class TestNotifications(test.BaseTestCase): self.assertEqual(2, len(samples)) self.assertEqual("network.create", samples[1].name) + def test_bulk_network_create(self): + v = notifications.Network(mock.Mock()) + samples = list(v.process_notification( + NOTIFICATION_BULK_NETWORK_CREATE)) + self.assertEqual(4, len(samples)) + self.assertEqual("network", samples[0].name) + self.assertEqual("network.create", samples[1].name) + self.assertEqual("network", samples[2].name) + self.assertEqual("network.create", samples[3].name) + def test_subnet_create(self): v = notifications.Subnet(mock.Mock()) samples = list(v.process_notification(NOTIFICATION_SUBNET_CREATE)) self.assertEqual(2, len(samples)) self.assertEqual("subnet.create", samples[1].name) + def test_bulk_subnet_create(self): + v = notifications.Subnet(mock.Mock()) + samples = list(v.process_notification(NOTIFICATION_BULK_SUBNET_CREATE)) + self.assertEqual(4, len(samples)) + self.assertEqual("subnet", samples[0].name) + self.assertEqual("subnet.create", samples[1].name) + self.assertEqual("subnet", samples[2].name) + self.assertEqual("subnet.create", samples[3].name) + def test_port_create(self): v = notifications.Port(mock.Mock()) samples = list(v.process_notification(NOTIFICATION_PORT_CREATE)) self.assertEqual(2, len(samples)) self.assertEqual("port.create", samples[1].name) + def test_bulk_port_create(self): + v = notifications.Port(mock.Mock()) + samples = list(v.process_notification(NOTIFICATION_BULK_PORT_CREATE)) + self.assertEqual(4, len(samples)) + self.assertEqual("port", samples[0].name) + self.assertEqual("port.create", samples[1].name) + self.assertEqual("port", samples[2].name) + self.assertEqual("port.create", samples[3].name) + def test_port_update(self): v = notifications.Port(mock.Mock()) samples = list(v.process_notification(NOTIFICATION_PORT_UPDATE))