diff --git a/contrib/heat_gnocchi/heat_gnocchi/resources/gnocchi_alarm.py b/contrib/heat_gnocchi/heat_gnocchi/resources/gnocchi_alarm.py index 7ce810a7a9..cf6f28025b 100644 --- a/contrib/heat_gnocchi/heat_gnocchi/resources/gnocchi_alarm.py +++ b/contrib/heat_gnocchi/heat_gnocchi/resources/gnocchi_alarm.py @@ -71,9 +71,9 @@ class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm): support_status = support.SupportStatus(version='2015.1') PROPERTIES = ( - METRIC, RESOURCE_CONSTRAINT, RESOURCE_TYPE + METRIC, RESOURCE_ID, RESOURCE_TYPE ) = ( - 'metric', 'resource_constraint', 'resource_type' + 'metric', 'resource_id', 'resource_type' ) PROPERTIES += COMMON_GNOCCHI_PROPERTIES @@ -84,9 +84,9 @@ class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm): required=True, update_allowed=True ), - RESOURCE_CONSTRAINT: properties.Schema( + RESOURCE_ID: properties.Schema( properties.Schema.STRING, - _('Id of a resource or expression to select multiple resources'), + _('Id of a resource'), required=True, update_allowed=True ), @@ -103,7 +103,8 @@ class CeilometerGnocchiResourcesAlarm(alarm.BaseCeilometerAlarm): ceilometer_alarm_type = 'gnocchi_resources_threshold' -class CeilometerGnocchiMetricsAlarm(CeilometerGnocchiResourcesAlarm): +class CeilometerGnocchiAggregationByMetricsAlarm( + CeilometerGnocchiResourcesAlarm): support_status = support.SupportStatus(version='2015.1') @@ -121,12 +122,54 @@ class CeilometerGnocchiMetricsAlarm(CeilometerGnocchiResourcesAlarm): properties_schema.update(common_gnocchi_properties_schema) properties_schema.update(alarm.common_properties_schema) - ceilometer_alarm_type = 'gnocchi_metrics_threshold' + ceilometer_alarm_type = 'gnocchi_aggregation_by_metrics_threshold' + + +class CeilometerGnocchiAggregationByResourcesAlarm( + CeilometerGnocchiResourcesAlarm): + + support_status = support.SupportStatus(version='2015.1') + + PROPERTIES = ( + METRIC, QUERY, RESOURCE_TYPE + ) = ( + 'metric', 'query', 'resource_type' + ) + PROPERTIES += COMMON_GNOCCHI_PROPERTIES + + properties_schema = { + METRIC: properties.Schema( + properties.Schema.STRING, + _('Metric name watched by the alarm.'), + required=True, + update_allowed=True + ), + QUERY: properties.Schema( + properties.Schema.STRING, + _('The query to filter the metrics'), + required=True, + update_allowed=True + ), + RESOURCE_TYPE: properties.Schema( + properties.Schema.STRING, + _('Resource type'), + required=True, + update_allowed=True + ), + } + + properties_schema.update(common_gnocchi_properties_schema) + properties_schema.update(alarm.common_properties_schema) + + ceilometer_alarm_type = 'gnocchi_aggregation_by_resources_threshold' def resource_mapping(): return { 'OS::Ceilometer::GnocchiResourcesAlarm': CeilometerGnocchiResourcesAlarm, - 'OS::Ceilometer::GnocchiMetricsAlarm': CeilometerGnocchiMetricsAlarm, + 'OS::Ceilometer::GnocchiAggregationByMetricsAlarm': + CeilometerGnocchiAggregationByMetricsAlarm, + 'OS::Ceilometer::GnocchiAggregationByResourcesAlarm': + CeilometerGnocchiAggregationByResourcesAlarm, } diff --git a/contrib/heat_gnocchi/heat_gnocchi/tests/test_gnocchi_alarm.py b/contrib/heat_gnocchi/heat_gnocchi/tests/test_gnocchi_alarm.py index 9863564d41..4ea6438de8 100644 --- a/contrib/heat_gnocchi/heat_gnocchi/tests/test_gnocchi_alarm.py +++ b/contrib/heat_gnocchi/heat_gnocchi/tests/test_gnocchi_alarm.py @@ -43,17 +43,17 @@ resources: threshold: 50 alarm_actions: [] resource_type: instance - resource_constraint: server_group=mystack + resource_id: 5a517ceb-b068-4aca-9eb9-3e4eb9b90d9a comparison_operator: gt ''' -gnocchi_metrics_alarm_template = ''' +gnocchi_aggregation_by_metrics_alarm_template = ''' heat_template_version: 2013-05-23 -description: Gnocchi Metrics Alarm Test +description: Gnocchi Aggregation by Metrics Alarm Test resources: - GnoMetricsAlarm: - type: OS::Ceilometer::GnocchiMetricsAlarm + GnoAggregationByMetricsAlarm: + type: OS::Ceilometer::GnocchiAggregationByMetricsAlarm properties: description: Do stuff with gnocchi metrics metrics: ["911fce07-e0d7-4210-8c8c-4a9d811fcabc", @@ -66,6 +66,25 @@ resources: comparison_operator: gt ''' +gnocchi_aggregation_by_resources_alarm_template = ''' +heat_template_version: 2013-05-23 +description: Gnocchi Aggregation by Resources Alarm Test +resources: + GnoAggregationByResourcesAlarm: + type: OS::Ceilometer::GnocchiAggregationByResourcesAlarm + properties: + description: Do stuff with gnocchi aggregation by resource + aggregation_method: mean + granularity: 60 + evaluation_periods: 1 + threshold: 50 + metric: cpu_util + alarm_actions: [] + resource_type: instance + query: '{"=": {"server_group": "my_autoscaling_group"}}' + comparison_operator: gt +''' + class FakeCeilometerAlarm(object): alarm_id = 'foo' @@ -101,7 +120,7 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): "evaluation_periods": 1, "threshold": 50, "resource_type": "instance", - "resource_constraint": "server_group=mystack", + "resource_id": "5a517ceb-b068-4aca-9eb9-3e4eb9b90d9a", "comparison_operator": "gt", } ).AndReturn(FakeCeilometerAlarm()) @@ -117,13 +136,13 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): self.fc.alarms.update( alarm_id='foo', gnocchi_resources_threshold_rule={ - 'resource_constraint': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'}) + 'resource_id': 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598'}) self.m.ReplayAll() scheduler.TaskRunner(rsrc.create)() update_template = copy.deepcopy(rsrc.t) - update_template['Properties']['resource_constraint'] = ( + update_template['Properties']['resource_id'] = ( 'd3d6c642-921e-4fc2-9c5f-15d9a5afb598') scheduler.TaskRunner(rsrc.update, update_template)() self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state) @@ -213,7 +232,7 @@ class GnocchiResourcesAlarmTest(common.HeatTestCase): self.assertIn('Boom', res.status_reason) -class GnocchiMetricsAlarmTest(GnocchiResourcesAlarmTest): +class GnocchiAggregationByMetricsAlarmTest(GnocchiResourcesAlarmTest): def create_alarm(self): self.m.StubOutWithMock(ceilometer.CeilometerClientPlugin, '_create') @@ -226,9 +245,10 @@ class GnocchiMetricsAlarmTest(GnocchiResourcesAlarmTest): enabled=True, insufficient_data_actions=None, ok_actions=None, - name=mox.IgnoreArg(), type='gnocchi_metrics_threshold', + name=mox.IgnoreArg(), + type='gnocchi_aggregation_by_metrics_threshold', repeat_actions=True, - gnocchi_metrics_threshold_rule={ + gnocchi_aggregation_by_metrics_threshold_rule={ "aggregation_method": "mean", "granularity": 60, "evaluation_periods": 1, @@ -238,18 +258,20 @@ class GnocchiMetricsAlarmTest(GnocchiResourcesAlarmTest): "2543d435-fe93-4443-9351-fb0156930f94"], } ).AndReturn(FakeCeilometerAlarm()) - snippet = template_format.parse(gnocchi_metrics_alarm_template) + snippet = template_format.parse( + gnocchi_aggregation_by_metrics_alarm_template) stack = utils.parse_stack(snippet) resource_defns = stack.t.resource_definitions(stack) - return gnocchi.CeilometerGnocchiMetricsAlarm( - 'GnoMetricsAlarm', resource_defns['GnoMetricsAlarm'], stack) + return gnocchi.CeilometerGnocchiAggregationByMetricsAlarm( + 'GnoAggregationByMetricsAlarm', + resource_defns['GnoAggregationByMetricsAlarm'], stack) def test_update(self): rsrc = self.create_alarm() self.m.StubOutWithMock(self.fc.alarms, 'update') self.fc.alarms.update( alarm_id='foo', - gnocchi_metrics_threshold_rule={ + gnocchi_aggregation_by_metrics_threshold_rule={ 'metrics': ['d3d6c642-921e-4fc2-9c5f-15d9a5afb598', 'bc60f822-18a0-4a0c-94e7-94c554b00901']}) @@ -266,9 +288,75 @@ class GnocchiMetricsAlarmTest(GnocchiResourcesAlarmTest): self.m.VerifyAll() def _prepare_check_resource(self): - snippet = template_format.parse(gnocchi_metrics_alarm_template) + snippet = template_format.parse( + gnocchi_aggregation_by_metrics_alarm_template) stack = utils.parse_stack(snippet) - res = stack['GnoMetricsAlarm'] + res = stack['GnoAggregationByMetricsAlarm'] + res.ceilometer = mock.Mock() + mock_alarm = mock.Mock(enabled=True, state='ok') + res.ceilometer().alarms.get.return_value = mock_alarm + return res + + +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"}}', + } + ).AndReturn(FakeCeilometerAlarm()) + snippet = template_format.parse( + gnocchi_aggregation_by_resources_alarm_template) + stack = utils.parse_stack(snippet) + resource_defns = stack.t.resource_definitions(stack) + return gnocchi.CeilometerGnocchiAggregationByResourcesAlarm( + 'GnoAggregationByResourcesAlarm', + resource_defns['GnoAggregationByResourcesAlarm'], 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.ReplayAll() + scheduler.TaskRunner(rsrc.create)() + + update_template = copy.deepcopy(rsrc.t) + update_template['Properties']['query'] = ( + '{"=": {"server_group": "my_new_group"}}') + scheduler.TaskRunner(rsrc.update, update_template)() + self.assertEqual((rsrc.UPDATE, rsrc.COMPLETE), rsrc.state) + + self.m.VerifyAll() + + def _prepare_check_resource(self): + snippet = template_format.parse( + gnocchi_aggregation_by_resources_alarm_template) + stack = utils.parse_stack(snippet) + res = stack['GnoAggregationByResourcesAlarm'] res.ceilometer = mock.Mock() mock_alarm = mock.Mock(enabled=True, state='ok') res.ceilometer().alarms.get.return_value = mock_alarm