From 42fb92907b0beaf2e8e3264c613013c0b52193b7 Mon Sep 17 00:00:00 2001 From: huangtianhua Date: Sat, 25 Jun 2016 11:23:32 +0800 Subject: [PATCH] Migrate to aodh for gnocchi alarms This changes: 1. use aodhclient to manage gnocchi alarm resources, including create, update, delete, check, suspend, resume and show. 2. rename OS::Ceilometer::Gnocchi* to OS::Aodh::Gnochhi* 3. considering to compatible with old templates with gnocchi alarm resources, set resource_registry to map Ceilometer gnocchi alarms to Aodh gnocchi alarms. Blueprint migrate-to-use-aodh-for-alarms Change-Id: I1507e5c82dbd7437000900eb1a46fe37806833b1 --- etc/heat/environment.d/default.yaml | 3 + .../openstack/ceilometer/gnocchi/alarm.py | 46 +++- .../ceilometer/test_gnocchi_alarm.py | 243 +++++++++--------- 3 files changed, 156 insertions(+), 136 deletions(-) diff --git a/etc/heat/environment.d/default.yaml b/etc/heat/environment.d/default.yaml index fb680c43ca..2092e84232 100644 --- a/etc/heat/environment.d/default.yaml +++ b/etc/heat/environment.d/default.yaml @@ -8,3 +8,6 @@ resource_registry: "OS::Metering::Alarm": "OS::Aodh::Alarm" "AWS::RDS::DBInstance": "file:///etc/heat/templates/AWS_RDS_DBInstance.yaml" "OS::Ceilometer::Alarm": "OS::Aodh::Alarm" + "OS::Ceilometer::GnocchiResourcesAlarm": "OS::Aodh::GnocchiResourcesAlarm" + "OS::Ceilometer::GnocchiAggregationByMetricsAlarm": "OS::Aodh::GnocchiAggregationByMetricsAlarm" + "OS::Ceilometer::GnocchiAggregationByResourcesAlarm": "OS::Aodh::GnocchiAggregationByResourcesAlarm" \ No newline at end of file diff --git a/heat/engine/resources/openstack/ceilometer/gnocchi/alarm.py b/heat/engine/resources/openstack/ceilometer/gnocchi/alarm.py index 16557cb8a3..ac5d57aa74 100644 --- a/heat/engine/resources/openstack/ceilometer/gnocchi/alarm.py +++ b/heat/engine/resources/openstack/ceilometer/gnocchi/alarm.py @@ -16,7 +16,6 @@ from heat.common.i18n import _ from heat.engine import constraints from heat.engine import properties from heat.engine.resources import alarm_base -from heat.engine.resources.openstack.ceilometer import alarm from heat.engine import support @@ -67,7 +66,7 @@ common_gnocchi_properties_schema = { } -class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm): +class AodhGnocchiResourcesAlarm(alarm_base.BaseAlarm): """A resource allowing for the watch of some specified resource. An alarm that evaluates threshold based on some metric for the @@ -108,9 +107,32 @@ class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm): alarm_type = 'gnocchi_resources_threshold' + def get_alarm_props(self, props): + kwargs = self.actions_to_urls(props) + kwargs = self._reformat_properties(kwargs) -class CeilometerGnocchiAggregationByMetricsAlarm( - CeilometerGnocchiResourcesAlarm): + return kwargs + + def handle_create(self): + props = self.get_alarm_props(self.properties) + props['name'] = self.physical_resource_name() + props['type'] = self.alarm_type + alarm = self.client().alarm.create(props) + self.resource_id_set(alarm['alarm_id']) + + def handle_update(self, json_snippet, tmpl_diff, prop_diff): + if prop_diff: + kwargs = {} + kwargs.update(prop_diff) + props = self.get_alarm_props(kwargs) + self.client().alarm.update(self.resource_id, props) + + def _show_resource(self): + return self.client().alarm.get(self.resource_id) + + +class AodhGnocchiAggregationByMetricsAlarm( + AodhGnocchiResourcesAlarm): """A resource that implements alarm with specified metrics. A resource that implements alarm which allows to use specified by user @@ -136,8 +158,8 @@ class CeilometerGnocchiAggregationByMetricsAlarm( alarm_type = 'gnocchi_aggregation_by_metrics_threshold' -class CeilometerGnocchiAggregationByResourcesAlarm( - CeilometerGnocchiResourcesAlarm): +class AodhGnocchiAggregationByResourcesAlarm( + AodhGnocchiResourcesAlarm): """A resource that implements alarm as an aggregation of resources alarms. A resource that implements alarm which uses aggregation of resources alarms @@ -183,10 +205,10 @@ class CeilometerGnocchiAggregationByResourcesAlarm( def resource_mapping(): return { - 'OS::Ceilometer::GnocchiResourcesAlarm': - CeilometerGnocchiResourcesAlarm, - 'OS::Ceilometer::GnocchiAggregationByMetricsAlarm': - CeilometerGnocchiAggregationByMetricsAlarm, - 'OS::Ceilometer::GnocchiAggregationByResourcesAlarm': - CeilometerGnocchiAggregationByResourcesAlarm, + 'OS::Aodh::GnocchiResourcesAlarm': + AodhGnocchiResourcesAlarm, + 'OS::Aodh::GnocchiAggregationByMetricsAlarm': + AodhGnocchiAggregationByMetricsAlarm, + 'OS::Aodh::GnocchiAggregationByResourcesAlarm': + AodhGnocchiAggregationByResourcesAlarm, } diff --git a/heat/tests/openstack/ceilometer/test_gnocchi_alarm.py b/heat/tests/openstack/ceilometer/test_gnocchi_alarm.py index 011dbb3c86..58f2fcaa22 100644 --- a/heat/tests/openstack/ceilometer/test_gnocchi_alarm.py +++ b/heat/tests/openstack/ceilometer/test_gnocchi_alarm.py @@ -16,7 +16,7 @@ import mox from heat.common import exception from heat.common import template_format -from heat.engine.clients.os import ceilometer +from heat.engine.clients.os import aodh from heat.engine.resources.openstack.ceilometer.gnocchi import ( alarm as gnocchi) from heat.engine import scheduler @@ -28,7 +28,7 @@ heat_template_version: 2013-05-23 description: Gnocchi Resources Alarm Test resources: GnoResAlarm: - type: OS::Ceilometer::GnocchiResourcesAlarm + type: OS::Aodh::GnocchiResourcesAlarm properties: description: Do stuff with gnocchi metric: cpu_util @@ -48,7 +48,7 @@ heat_template_version: 2013-05-23 description: Gnocchi Aggregation by Metrics Alarm Test resources: GnoAggregationByMetricsAlarm: - type: OS::Ceilometer::GnocchiAggregationByMetricsAlarm + type: OS::Aodh::GnocchiAggregationByMetricsAlarm properties: description: Do stuff with gnocchi metrics metrics: ["911fce07-e0d7-4210-8c8c-4a9d811fcabc", @@ -66,7 +66,7 @@ heat_template_version: 2013-05-23 description: Gnocchi Aggregation by Resources Alarm Test resources: GnoAggregationByResourcesAlarm: - type: OS::Ceilometer::GnocchiAggregationByResourcesAlarm + type: OS::Aodh::GnocchiAggregationByResourcesAlarm properties: description: Do stuff with gnocchi aggregation by resource aggregation_method: mean @@ -80,12 +80,8 @@ resources: comparison_operator: gt ''' - -class FakeCeilometerAlarm(object): - alarm_id = 'foo' - - def __init__(self): - self.to_dict = lambda: {'attr': 'val'} +FakeAodhAlarm = {'other_attrs': 'val', + 'alarm_id': 'foo'} class GnocchiResourcesAlarmTest(common.HeatTestCase): @@ -94,44 +90,45 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): self.fc = mock.Mock() def create_alarm(self): - self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') - ceilometer.CeilometerClientPlugin._create().AndReturn( - self.fc) - self.m.StubOutWithMock(self.fc.alarms, 'create') - self.fc.alarms.create( - alarm_actions=[], - description=u'Do stuff with gnocchi', - enabled=True, - insufficient_data_actions=None, - ok_actions=None, - name=mox.IgnoreArg(), type='gnocchi_resources_threshold', - repeat_actions=True, - gnocchi_resources_threshold_rule={ - "metric": "cpu_util", - "aggregation_method": "mean", - "granularity": 60, - "evaluation_periods": 1, - "threshold": 50, - "resource_type": "instance", - "resource_id": "5a517ceb-b068-4aca-9eb9-3e4eb9b90d9a", - "comparison_operator": "gt", - }, - time_constraints=[], - severity='low', - ).AndReturn(FakeCeilometerAlarm()) + self.patchobject(aodh.AodhClientPlugin, + '_create').return_value = self.fc + self.m.StubOutWithMock(self.fc.alarm, 'create') + self.fc.alarm.create( + { + 'alarm_actions': [], + 'description': u'Do stuff with gnocchi', + 'enabled': True, + 'insufficient_data_actions': None, + 'ok_actions': None, + 'name': mox.IgnoreArg(), + 'type': 'gnocchi_resources_threshold', + 'repeat_actions': True, + 'gnocchi_resources_threshold_rule': { + "metric": "cpu_util", + "aggregation_method": "mean", + "granularity": 60, + "evaluation_periods": 1, + "threshold": 50, + "resource_type": "instance", + "resource_id": "5a517ceb-b068-4aca-9eb9-3e4eb9b90d9a", + "comparison_operator": "gt", + }, + 'time_constraints': [], + 'severity': 'low' + }).AndReturn(FakeAodhAlarm) self.tmpl = template_format.parse(gnocchi_resources_alarm_template) self.stack = utils.parse_stack(self.tmpl) resource_defns = self.stack.t.resource_definitions(self.stack) - return gnocchi.CeilometerGnocchiResourcesAlarm( + return gnocchi.AodhGnocchiResourcesAlarm( 'GnoResAlarm', resource_defns['GnoResAlarm'], self.stack) def test_update(self): rsrc = self.create_alarm() - self.m.StubOutWithMock(self.fc.alarms, 'update') - self.fc.alarms.update( - alarm_id='foo', - gnocchi_resources_threshold_rule={ - 'resource_id': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'}) + self.m.StubOutWithMock(self.fc.alarm, 'update') + self.fc.alarm.update( + 'foo', + {'gnocchi_resources_threshold_rule': { + 'resource_id': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'}}) self.m.ReplayAll() scheduler.TaskRunner(rsrc.create)() @@ -150,7 +147,7 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): res = self.stack['GnoResAlarm'] res.client = mock.Mock() mock_alarm = mock.Mock(enabled=True, state='ok') - res.client().alarms.get.return_value = mock_alarm + res.client().alarm.get.return_value = mock_alarm return res def test_create(self): @@ -164,8 +161,8 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): def test_suspend(self): rsrc = self.create_alarm() - self.m.StubOutWithMock(self.fc.alarms, 'update') - self.fc.alarms.update(alarm_id='foo', enabled=False) + self.m.StubOutWithMock(self.fc.alarm, 'update') + self.fc.alarm.update('foo', {'enabled': False}) self.m.ReplayAll() scheduler.TaskRunner(rsrc.create)() @@ -177,8 +174,8 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): def test_resume(self): rsrc = self.create_alarm() - self.m.StubOutWithMock(self.fc.alarms, 'update') - self.fc.alarms.update(alarm_id='foo', enabled=True) + self.m.StubOutWithMock(self.fc.alarm, 'update') + self.fc.alarm.update('foo', {'enabled': True}) self.m.ReplayAll() scheduler.TaskRunner(rsrc.create)() @@ -196,7 +193,7 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): def test_check_failure(self): res = self._prepare_check_resource() - res.client().alarms.get.side_effect = Exception('Boom') + res.client().alarm.get.side_effect = Exception('Boom') self.assertRaises(exception.ResourceFailure, scheduler.TaskRunner(res.check)) @@ -205,57 +202,56 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): def test_show_resource(self): res = self._prepare_check_resource() - res.client().alarms.create.return_value = mock.MagicMock( - alarm_id='2') - res.client().alarms.get.return_value = FakeCeilometerAlarm() + res.client().alarm.create.return_value = FakeAodhAlarm + res.client().alarm.get.return_value = FakeAodhAlarm scheduler.TaskRunner(res.create)() - self.assertEqual({'attr': 'val'}, res.FnGetAtt('show')) + self.assertEqual(FakeAodhAlarm, res.FnGetAtt('show')) class GnocchiAggregationByMetricsAlarmTest(GnocchiResourcesAlarmTest): def create_alarm(self): - self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') - ceilometer.CeilometerClientPlugin._create().AndReturn( - self.fc) - self.m.StubOutWithMock(self.fc.alarms, 'create') - self.fc.alarms.create( - alarm_actions=[], - description=u'Do stuff with gnocchi metrics', - enabled=True, - insufficient_data_actions=None, - ok_actions=None, - name=mox.IgnoreArg(), - type='gnocchi_aggregation_by_metrics_threshold', - repeat_actions=True, - gnocchi_aggregation_by_metrics_threshold_rule={ - "aggregation_method": "mean", - "granularity": 60, - "evaluation_periods": 1, - "threshold": 50, - "comparison_operator": "gt", - "metrics": ["911fce07-e0d7-4210-8c8c-4a9d811fcabc", - "2543d435-fe93-4443-9351-fb0156930f94"], - }, - time_constraints=[], - severity='low', - ).AndReturn(FakeCeilometerAlarm()) + self.patchobject(aodh.AodhClientPlugin, + '_create').return_value = self.fc + self.m.StubOutWithMock(self.fc.alarm, 'create') + self.fc.alarm.create( + { + 'alarm_actions': [], + 'description': u'Do stuff with gnocchi metrics', + 'enabled': True, + 'insufficient_data_actions': None, + 'ok_actions': None, + 'name': mox.IgnoreArg(), + 'type': 'gnocchi_aggregation_by_metrics_threshold', + 'repeat_actions': True, + 'gnocchi_aggregation_by_metrics_threshold_rule': { + "aggregation_method": "mean", + "granularity": 60, + "evaluation_periods": 1, + "threshold": 50, + "comparison_operator": "gt", + "metrics": ["911fce07-e0d7-4210-8c8c-4a9d811fcabc", + "2543d435-fe93-4443-9351-fb0156930f94"], + }, + 'time_constraints': [], + 'severity': 'low'} + ).AndReturn(FakeAodhAlarm) self.tmpl = template_format.parse( gnocchi_aggregation_by_metrics_alarm_template) self.stack = utils.parse_stack(self.tmpl) resource_defns = self.stack.t.resource_definitions(self.stack) - return gnocchi.CeilometerGnocchiAggregationByMetricsAlarm( + return gnocchi.AodhGnocchiAggregationByMetricsAlarm( 'GnoAggregationByMetricsAlarm', resource_defns['GnoAggregationByMetricsAlarm'], self.stack) def test_update(self): rsrc = self.create_alarm() - self.m.StubOutWithMock(self.fc.alarms, 'update') - self.fc.alarms.update( - alarm_id='foo', - gnocchi_aggregation_by_metrics_threshold_rule={ + self.m.StubOutWithMock(self.fc.alarm, 'update') + self.fc.alarm.update( + 'foo', + {'gnocchi_aggregation_by_metrics_threshold_rule': { 'metrics': ['d3d6c642-921e-4fc2-9c5f-15d9a5afb598', - 'bc60f822-18a0-4a0c-94e7-94c554b00901']}) + 'bc60f822-18a0-4a0c-94e7-94c554b00901']}}) self.m.ReplayAll() scheduler.TaskRunner(rsrc.create)() @@ -277,62 +273,62 @@ class GnocchiAggregationByMetricsAlarmTest(GnocchiResourcesAlarmTest): res = self.stack['GnoAggregationByMetricsAlarm'] res.client = mock.Mock() mock_alarm = mock.Mock(enabled=True, state='ok') - res.client().alarms.get.return_value = mock_alarm + res.client().alarm.get.return_value = mock_alarm return res def test_show_resource(self): res = self._prepare_check_resource() - res.client().alarms.create.return_value = mock.MagicMock( - alarm_id='2') - res.client().alarms.get.return_value = FakeCeilometerAlarm() + res.client().alarm.create.return_value = FakeAodhAlarm + res.client().alarm.get.return_value = FakeAodhAlarm scheduler.TaskRunner(res.create)() - self.assertEqual({'attr': 'val'}, res.FnGetAtt('show')) + self.assertEqual(FakeAodhAlarm, res.FnGetAtt('show')) class GnocchiAggregationByResourcesAlarmTest(GnocchiResourcesAlarmTest): def create_alarm(self): - self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') - ceilometer.CeilometerClientPlugin._create().AndReturn( - self.fc) - self.m.StubOutWithMock(self.fc.alarms, 'create') - self.fc.alarms.create( - alarm_actions=[], - description=u'Do stuff with gnocchi aggregation by resource', - enabled=True, - insufficient_data_actions=None, - ok_actions=None, - name=mox.IgnoreArg(), - type='gnocchi_aggregation_by_resources_threshold', - repeat_actions=True, - gnocchi_aggregation_by_resources_threshold_rule={ - "aggregation_method": "mean", - "granularity": 60, - "evaluation_periods": 1, - "threshold": 50, - "comparison_operator": "gt", - "metric": "cpu_util", - "resource_type": "instance", - "query": '{"=": {"server_group": "my_autoscaling_group"}}', - }, - time_constraints=[], - severity='low', - ).AndReturn(FakeCeilometerAlarm()) + self.patchobject(aodh.AodhClientPlugin, + '_create').return_value = self.fc + + self.m.StubOutWithMock(self.fc.alarm, 'create') + self.fc.alarm.create( + { + 'alarm_actions': [], + 'description': 'Do stuff with gnocchi aggregation by resource', + 'enabled': True, + 'insufficient_data_actions': None, + 'ok_actions': None, + 'name': mox.IgnoreArg(), + 'type': 'gnocchi_aggregation_by_resources_threshold', + 'repeat_actions': True, + 'gnocchi_aggregation_by_resources_threshold_rule': { + "aggregation_method": "mean", + "granularity": 60, + "evaluation_periods": 1, + "threshold": 50, + "comparison_operator": "gt", + "metric": "cpu_util", + "resource_type": "instance", + "query": '{"=": {"server_group": "my_autoscaling_group"}}', + }, + 'time_constraints': [], + 'severity': 'low'} + ).AndReturn(FakeAodhAlarm) self.tmpl = template_format.parse( gnocchi_aggregation_by_resources_alarm_template) self.stack = utils.parse_stack(self.tmpl) resource_defns = self.stack.t.resource_definitions(self.stack) - return gnocchi.CeilometerGnocchiAggregationByResourcesAlarm( + return gnocchi.AodhGnocchiAggregationByResourcesAlarm( 'GnoAggregationByResourcesAlarm', resource_defns['GnoAggregationByResourcesAlarm'], self.stack) def test_update(self): rsrc = self.create_alarm() - self.m.StubOutWithMock(self.fc.alarms, 'update') - self.fc.alarms.update( - alarm_id='foo', - gnocchi_aggregation_by_resources_threshold_rule={ - 'query': '{"=": {"server_group": "my_new_group"}}'}) + self.m.StubOutWithMock(self.fc.alarm, 'update') + self.fc.alarm.update( + 'foo', + {'gnocchi_aggregation_by_resources_threshold_rule': { + 'query': '{"=": {"server_group": "my_new_group"}}'}}) self.m.ReplayAll() scheduler.TaskRunner(rsrc.create)() @@ -353,13 +349,12 @@ class GnocchiAggregationByResourcesAlarmTest(GnocchiResourcesAlarmTest): res = self.stack['GnoAggregationByResourcesAlarm'] res.client = mock.Mock() mock_alarm = mock.Mock(enabled=True, state='ok') - res.client().alarms.get.return_value = mock_alarm + res.client().alarm.get.return_value = mock_alarm return res def test_show_resource(self): res = self._prepare_check_resource() - res.client().alarms.create.return_value = mock.MagicMock( - alarm_id='2') - res.client().alarms.get.return_value = FakeCeilometerAlarm() + res.client().alarm.create.return_value = FakeAodhAlarm + res.client().alarm.get.return_value = FakeAodhAlarm scheduler.TaskRunner(res.create)() - self.assertEqual({'attr': 'val'}, res.FnGetAtt('show')) + self.assertEqual(FakeAodhAlarm, res.FnGetAtt('show'))