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
This commit is contained in:
huangtianhua 2016-06-25 11:23:32 +08:00
parent 4a79f7ca53
commit 42fb92907b
3 changed files with 156 additions and 136 deletions

View File

@ -8,3 +8,6 @@ resource_registry:
"OS::Metering::Alarm": "OS::Aodh::Alarm" "OS::Metering::Alarm": "OS::Aodh::Alarm"
"AWS::RDS::DBInstance": "file:///etc/heat/templates/AWS_RDS_DBInstance.yaml" "AWS::RDS::DBInstance": "file:///etc/heat/templates/AWS_RDS_DBInstance.yaml"
"OS::Ceilometer::Alarm": "OS::Aodh::Alarm" "OS::Ceilometer::Alarm": "OS::Aodh::Alarm"
"OS::Ceilometer::GnocchiResourcesAlarm": "OS::Aodh::GnocchiResourcesAlarm"
"OS::Ceilometer::GnocchiAggregationByMetricsAlarm": "OS::Aodh::GnocchiAggregationByMetricsAlarm"
"OS::Ceilometer::GnocchiAggregationByResourcesAlarm": "OS::Aodh::GnocchiAggregationByResourcesAlarm"

View File

@ -16,7 +16,6 @@ from heat.common.i18n import _
from heat.engine import constraints from heat.engine import constraints
from heat.engine import properties from heat.engine import properties
from heat.engine.resources import alarm_base from heat.engine.resources import alarm_base
from heat.engine.resources.openstack.ceilometer import alarm
from heat.engine import support 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. """A resource allowing for the watch of some specified resource.
An alarm that evaluates threshold based on some metric for the An alarm that evaluates threshold based on some metric for the
@ -108,9 +107,32 @@ class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm):
alarm_type = 'gnocchi_resources_threshold' alarm_type = 'gnocchi_resources_threshold'
def get_alarm_props(self, props):
kwargs = self.actions_to_urls(props)
kwargs = self._reformat_properties(kwargs)
class CeilometerGnocchiAggregationByMetricsAlarm( return kwargs
CeilometerGnocchiResourcesAlarm):
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 with specified metrics.
A resource that implements alarm which allows to use specified by user 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' alarm_type = 'gnocchi_aggregation_by_metrics_threshold'
class CeilometerGnocchiAggregationByResourcesAlarm( class AodhGnocchiAggregationByResourcesAlarm(
CeilometerGnocchiResourcesAlarm): AodhGnocchiResourcesAlarm):
"""A resource that implements alarm as an aggregation of resources alarms. """A resource that implements alarm as an aggregation of resources alarms.
A resource that implements alarm which uses aggregation of resources alarms A resource that implements alarm which uses aggregation of resources alarms
@ -183,10 +205,10 @@ class CeilometerGnocchiAggregationByResourcesAlarm(
def resource_mapping(): def resource_mapping():
return { return {
'OS::Ceilometer::GnocchiResourcesAlarm': 'OS::Aodh::GnocchiResourcesAlarm':
CeilometerGnocchiResourcesAlarm, AodhGnocchiResourcesAlarm,
'OS::Ceilometer::GnocchiAggregationByMetricsAlarm': 'OS::Aodh::GnocchiAggregationByMetricsAlarm':
CeilometerGnocchiAggregationByMetricsAlarm, AodhGnocchiAggregationByMetricsAlarm,
'OS::Ceilometer::GnocchiAggregationByResourcesAlarm': 'OS::Aodh::GnocchiAggregationByResourcesAlarm':
CeilometerGnocchiAggregationByResourcesAlarm, AodhGnocchiAggregationByResourcesAlarm,
} }

View File

@ -16,7 +16,7 @@ import mox
from heat.common import exception from heat.common import exception
from heat.common import template_format 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 ( from heat.engine.resources.openstack.ceilometer.gnocchi import (
alarm as gnocchi) alarm as gnocchi)
from heat.engine import scheduler from heat.engine import scheduler
@ -28,7 +28,7 @@ heat_template_version: 2013-05-23
description: Gnocchi Resources Alarm Test description: Gnocchi Resources Alarm Test
resources: resources:
GnoResAlarm: GnoResAlarm:
type: OS::Ceilometer::GnocchiResourcesAlarm type: OS::Aodh::GnocchiResourcesAlarm
properties: properties:
description: Do stuff with gnocchi description: Do stuff with gnocchi
metric: cpu_util metric: cpu_util
@ -48,7 +48,7 @@ heat_template_version: 2013-05-23
description: Gnocchi Aggregation by Metrics Alarm Test description: Gnocchi Aggregation by Metrics Alarm Test
resources: resources:
GnoAggregationByMetricsAlarm: GnoAggregationByMetricsAlarm:
type: OS::Ceilometer::GnocchiAggregationByMetricsAlarm type: OS::Aodh::GnocchiAggregationByMetricsAlarm
properties: properties:
description: Do stuff with gnocchi metrics description: Do stuff with gnocchi metrics
metrics: ["911fce07-e0d7-4210-8c8c-4a9d811fcabc", metrics: ["911fce07-e0d7-4210-8c8c-4a9d811fcabc",
@ -66,7 +66,7 @@ heat_template_version: 2013-05-23
description: Gnocchi Aggregation by Resources Alarm Test description: Gnocchi Aggregation by Resources Alarm Test
resources: resources:
GnoAggregationByResourcesAlarm: GnoAggregationByResourcesAlarm:
type: OS::Ceilometer::GnocchiAggregationByResourcesAlarm type: OS::Aodh::GnocchiAggregationByResourcesAlarm
properties: properties:
description: Do stuff with gnocchi aggregation by resource description: Do stuff with gnocchi aggregation by resource
aggregation_method: mean aggregation_method: mean
@ -80,12 +80,8 @@ resources:
comparison_operator: gt comparison_operator: gt
''' '''
FakeAodhAlarm = {'other_attrs': 'val',
class FakeCeilometerAlarm(object): 'alarm_id': 'foo'}
alarm_id = 'foo'
def __init__(self):
self.to_dict = lambda: {'attr': 'val'}
class GnocchiResourcesAlarmTest(common.HeatTestCase): class GnocchiResourcesAlarmTest(common.HeatTestCase):
@ -94,44 +90,45 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase):
self.fc = mock.Mock() self.fc = mock.Mock()
def create_alarm(self): def create_alarm(self):
self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') self.patchobject(aodh.AodhClientPlugin,
ceilometer.CeilometerClientPlugin._create().AndReturn( '_create').return_value = self.fc
self.fc) self.m.StubOutWithMock(self.fc.alarm, 'create')
self.m.StubOutWithMock(self.fc.alarms, 'create') self.fc.alarm.create(
self.fc.alarms.create( {
alarm_actions=[], 'alarm_actions': [],
description=u'Do stuff with gnocchi', 'description': u'Do stuff with gnocchi',
enabled=True, 'enabled': True,
insufficient_data_actions=None, 'insufficient_data_actions': None,
ok_actions=None, 'ok_actions': None,
name=mox.IgnoreArg(), type='gnocchi_resources_threshold', 'name': mox.IgnoreArg(),
repeat_actions=True, 'type': 'gnocchi_resources_threshold',
gnocchi_resources_threshold_rule={ 'repeat_actions': True,
"metric": "cpu_util", 'gnocchi_resources_threshold_rule': {
"aggregation_method": "mean", "metric": "cpu_util",
"granularity": 60, "aggregation_method": "mean",
"evaluation_periods": 1, "granularity": 60,
"threshold": 50, "evaluation_periods": 1,
"resource_type": "instance", "threshold": 50,
"resource_id": "5a517ceb-b068-4aca-9eb9-3e4eb9b90d9a", "resource_type": "instance",
"comparison_operator": "gt", "resource_id": "5a517ceb-b068-4aca-9eb9-3e4eb9b90d9a",
}, "comparison_operator": "gt",
time_constraints=[], },
severity='low', 'time_constraints': [],
).AndReturn(FakeCeilometerAlarm()) 'severity': 'low'
}).AndReturn(FakeAodhAlarm)
self.tmpl = template_format.parse(gnocchi_resources_alarm_template) self.tmpl = template_format.parse(gnocchi_resources_alarm_template)
self.stack = utils.parse_stack(self.tmpl) self.stack = utils.parse_stack(self.tmpl)
resource_defns = self.stack.t.resource_definitions(self.stack) resource_defns = self.stack.t.resource_definitions(self.stack)
return gnocchi.CeilometerGnocchiResourcesAlarm( return gnocchi.AodhGnocchiResourcesAlarm(
'GnoResAlarm', resource_defns['GnoResAlarm'], self.stack) 'GnoResAlarm', resource_defns['GnoResAlarm'], self.stack)
def test_update(self): def test_update(self):
rsrc = self.create_alarm() rsrc = self.create_alarm()
self.m.StubOutWithMock(self.fc.alarms, 'update') self.m.StubOutWithMock(self.fc.alarm, 'update')
self.fc.alarms.update( self.fc.alarm.update(
alarm_id='foo', 'foo',
gnocchi_resources_threshold_rule={ {'gnocchi_resources_threshold_rule': {
'resource_id': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'}) 'resource_id': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'}})
self.m.ReplayAll() self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -150,7 +147,7 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase):
res = self.stack['GnoResAlarm'] res = self.stack['GnoResAlarm']
res.client = mock.Mock() res.client = mock.Mock()
mock_alarm = mock.Mock(enabled=True, state='ok') 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 return res
def test_create(self): def test_create(self):
@ -164,8 +161,8 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase):
def test_suspend(self): def test_suspend(self):
rsrc = self.create_alarm() rsrc = self.create_alarm()
self.m.StubOutWithMock(self.fc.alarms, 'update') self.m.StubOutWithMock(self.fc.alarm, 'update')
self.fc.alarms.update(alarm_id='foo', enabled=False) self.fc.alarm.update('foo', {'enabled': False})
self.m.ReplayAll() self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -177,8 +174,8 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase):
def test_resume(self): def test_resume(self):
rsrc = self.create_alarm() rsrc = self.create_alarm()
self.m.StubOutWithMock(self.fc.alarms, 'update') self.m.StubOutWithMock(self.fc.alarm, 'update')
self.fc.alarms.update(alarm_id='foo', enabled=True) self.fc.alarm.update('foo', {'enabled': True})
self.m.ReplayAll() self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -196,7 +193,7 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase):
def test_check_failure(self): def test_check_failure(self):
res = self._prepare_check_resource() 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, self.assertRaises(exception.ResourceFailure,
scheduler.TaskRunner(res.check)) scheduler.TaskRunner(res.check))
@ -205,57 +202,56 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase):
def test_show_resource(self): def test_show_resource(self):
res = self._prepare_check_resource() res = self._prepare_check_resource()
res.client().alarms.create.return_value = mock.MagicMock( res.client().alarm.create.return_value = FakeAodhAlarm
alarm_id='2') res.client().alarm.get.return_value = FakeAodhAlarm
res.client().alarms.get.return_value = FakeCeilometerAlarm()
scheduler.TaskRunner(res.create)() scheduler.TaskRunner(res.create)()
self.assertEqual({'attr': 'val'}, res.FnGetAtt('show')) self.assertEqual(FakeAodhAlarm, res.FnGetAtt('show'))
class GnocchiAggregationByMetricsAlarmTest(GnocchiResourcesAlarmTest): class GnocchiAggregationByMetricsAlarmTest(GnocchiResourcesAlarmTest):
def create_alarm(self): def create_alarm(self):
self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') self.patchobject(aodh.AodhClientPlugin,
ceilometer.CeilometerClientPlugin._create().AndReturn( '_create').return_value = self.fc
self.fc) self.m.StubOutWithMock(self.fc.alarm, 'create')
self.m.StubOutWithMock(self.fc.alarms, 'create') self.fc.alarm.create(
self.fc.alarms.create( {
alarm_actions=[], 'alarm_actions': [],
description=u'Do stuff with gnocchi metrics', 'description': u'Do stuff with gnocchi metrics',
enabled=True, 'enabled': True,
insufficient_data_actions=None, 'insufficient_data_actions': None,
ok_actions=None, 'ok_actions': None,
name=mox.IgnoreArg(), 'name': mox.IgnoreArg(),
type='gnocchi_aggregation_by_metrics_threshold', 'type': 'gnocchi_aggregation_by_metrics_threshold',
repeat_actions=True, 'repeat_actions': True,
gnocchi_aggregation_by_metrics_threshold_rule={ 'gnocchi_aggregation_by_metrics_threshold_rule': {
"aggregation_method": "mean", "aggregation_method": "mean",
"granularity": 60, "granularity": 60,
"evaluation_periods": 1, "evaluation_periods": 1,
"threshold": 50, "threshold": 50,
"comparison_operator": "gt", "comparison_operator": "gt",
"metrics": ["911fce07-e0d7-4210-8c8c-4a9d811fcabc", "metrics": ["911fce07-e0d7-4210-8c8c-4a9d811fcabc",
"2543d435-fe93-4443-9351-fb0156930f94"], "2543d435-fe93-4443-9351-fb0156930f94"],
}, },
time_constraints=[], 'time_constraints': [],
severity='low', 'severity': 'low'}
).AndReturn(FakeCeilometerAlarm()) ).AndReturn(FakeAodhAlarm)
self.tmpl = template_format.parse( self.tmpl = template_format.parse(
gnocchi_aggregation_by_metrics_alarm_template) gnocchi_aggregation_by_metrics_alarm_template)
self.stack = utils.parse_stack(self.tmpl) self.stack = utils.parse_stack(self.tmpl)
resource_defns = self.stack.t.resource_definitions(self.stack) resource_defns = self.stack.t.resource_definitions(self.stack)
return gnocchi.CeilometerGnocchiAggregationByMetricsAlarm( return gnocchi.AodhGnocchiAggregationByMetricsAlarm(
'GnoAggregationByMetricsAlarm', 'GnoAggregationByMetricsAlarm',
resource_defns['GnoAggregationByMetricsAlarm'], self.stack) resource_defns['GnoAggregationByMetricsAlarm'], self.stack)
def test_update(self): def test_update(self):
rsrc = self.create_alarm() rsrc = self.create_alarm()
self.m.StubOutWithMock(self.fc.alarms, 'update') self.m.StubOutWithMock(self.fc.alarm, 'update')
self.fc.alarms.update( self.fc.alarm.update(
alarm_id='foo', 'foo',
gnocchi_aggregation_by_metrics_threshold_rule={ {'gnocchi_aggregation_by_metrics_threshold_rule': {
'metrics': ['d3d6c642-921e-4fc2-9c5f-15d9a5afb598', 'metrics': ['d3d6c642-921e-4fc2-9c5f-15d9a5afb598',
'bc60f822-18a0-4a0c-94e7-94c554b00901']}) 'bc60f822-18a0-4a0c-94e7-94c554b00901']}})
self.m.ReplayAll() self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -277,62 +273,62 @@ class GnocchiAggregationByMetricsAlarmTest(GnocchiResourcesAlarmTest):
res = self.stack['GnoAggregationByMetricsAlarm'] res = self.stack['GnoAggregationByMetricsAlarm']
res.client = mock.Mock() res.client = mock.Mock()
mock_alarm = mock.Mock(enabled=True, state='ok') 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 return res
def test_show_resource(self): def test_show_resource(self):
res = self._prepare_check_resource() res = self._prepare_check_resource()
res.client().alarms.create.return_value = mock.MagicMock( res.client().alarm.create.return_value = FakeAodhAlarm
alarm_id='2') res.client().alarm.get.return_value = FakeAodhAlarm
res.client().alarms.get.return_value = FakeCeilometerAlarm()
scheduler.TaskRunner(res.create)() scheduler.TaskRunner(res.create)()
self.assertEqual({'attr': 'val'}, res.FnGetAtt('show')) self.assertEqual(FakeAodhAlarm, res.FnGetAtt('show'))
class GnocchiAggregationByResourcesAlarmTest(GnocchiResourcesAlarmTest): class GnocchiAggregationByResourcesAlarmTest(GnocchiResourcesAlarmTest):
def create_alarm(self): def create_alarm(self):
self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') self.patchobject(aodh.AodhClientPlugin,
ceilometer.CeilometerClientPlugin._create().AndReturn( '_create').return_value = self.fc
self.fc)
self.m.StubOutWithMock(self.fc.alarms, 'create') self.m.StubOutWithMock(self.fc.alarm, 'create')
self.fc.alarms.create( self.fc.alarm.create(
alarm_actions=[], {
description=u'Do stuff with gnocchi aggregation by resource', 'alarm_actions': [],
enabled=True, 'description': 'Do stuff with gnocchi aggregation by resource',
insufficient_data_actions=None, 'enabled': True,
ok_actions=None, 'insufficient_data_actions': None,
name=mox.IgnoreArg(), 'ok_actions': None,
type='gnocchi_aggregation_by_resources_threshold', 'name': mox.IgnoreArg(),
repeat_actions=True, 'type': 'gnocchi_aggregation_by_resources_threshold',
gnocchi_aggregation_by_resources_threshold_rule={ 'repeat_actions': True,
"aggregation_method": "mean", 'gnocchi_aggregation_by_resources_threshold_rule': {
"granularity": 60, "aggregation_method": "mean",
"evaluation_periods": 1, "granularity": 60,
"threshold": 50, "evaluation_periods": 1,
"comparison_operator": "gt", "threshold": 50,
"metric": "cpu_util", "comparison_operator": "gt",
"resource_type": "instance", "metric": "cpu_util",
"query": '{"=": {"server_group": "my_autoscaling_group"}}', "resource_type": "instance",
}, "query": '{"=": {"server_group": "my_autoscaling_group"}}',
time_constraints=[], },
severity='low', 'time_constraints': [],
).AndReturn(FakeCeilometerAlarm()) 'severity': 'low'}
).AndReturn(FakeAodhAlarm)
self.tmpl = template_format.parse( self.tmpl = template_format.parse(
gnocchi_aggregation_by_resources_alarm_template) gnocchi_aggregation_by_resources_alarm_template)
self.stack = utils.parse_stack(self.tmpl) self.stack = utils.parse_stack(self.tmpl)
resource_defns = self.stack.t.resource_definitions(self.stack) resource_defns = self.stack.t.resource_definitions(self.stack)
return gnocchi.CeilometerGnocchiAggregationByResourcesAlarm( return gnocchi.AodhGnocchiAggregationByResourcesAlarm(
'GnoAggregationByResourcesAlarm', 'GnoAggregationByResourcesAlarm',
resource_defns['GnoAggregationByResourcesAlarm'], self.stack) resource_defns['GnoAggregationByResourcesAlarm'], self.stack)
def test_update(self): def test_update(self):
rsrc = self.create_alarm() rsrc = self.create_alarm()
self.m.StubOutWithMock(self.fc.alarms, 'update') self.m.StubOutWithMock(self.fc.alarm, 'update')
self.fc.alarms.update( self.fc.alarm.update(
alarm_id='foo', 'foo',
gnocchi_aggregation_by_resources_threshold_rule={ {'gnocchi_aggregation_by_resources_threshold_rule': {
'query': '{"=": {"server_group": "my_new_group"}}'}) 'query': '{"=": {"server_group": "my_new_group"}}'}})
self.m.ReplayAll() self.m.ReplayAll()
scheduler.TaskRunner(rsrc.create)() scheduler.TaskRunner(rsrc.create)()
@ -353,13 +349,12 @@ class GnocchiAggregationByResourcesAlarmTest(GnocchiResourcesAlarmTest):
res = self.stack['GnoAggregationByResourcesAlarm'] res = self.stack['GnoAggregationByResourcesAlarm']
res.client = mock.Mock() res.client = mock.Mock()
mock_alarm = mock.Mock(enabled=True, state='ok') 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 return res
def test_show_resource(self): def test_show_resource(self):
res = self._prepare_check_resource() res = self._prepare_check_resource()
res.client().alarms.create.return_value = mock.MagicMock( res.client().alarm.create.return_value = FakeAodhAlarm
alarm_id='2') res.client().alarm.get.return_value = FakeAodhAlarm
res.client().alarms.get.return_value = FakeCeilometerAlarm()
scheduler.TaskRunner(res.create)() scheduler.TaskRunner(res.create)()
self.assertEqual({'attr': 'val'}, res.FnGetAtt('show')) self.assertEqual(FakeAodhAlarm, res.FnGetAtt('show'))