diff --git a/moto/cloudwatch/responses.py b/moto/cloudwatch/responses.py index 56ba68bb9..f6e003ee2 100644 --- a/moto/cloudwatch/responses.py +++ b/moto/cloudwatch/responses.py @@ -161,9 +161,23 @@ class CloudWatchResponse(BaseResponse): def describe_alarm_history(self): raise NotImplementedError() + @staticmethod + def filter_alarms(alarms, metric_name, namespace): + metric_filtered_alarms = [] + + for alarm in alarms: + if alarm.metric_name == metric_name and alarm.namespace == namespace: + metric_filtered_alarms.append(alarm) + return metric_filtered_alarms + @amzn_request_id def describe_alarms_for_metric(self): - raise NotImplementedError() + alarms = self.cloudwatch_backend.get_all_alarms() + namespace = self._get_param("Namespace") + metric_name = self._get_param("MetricName") + filtered_alarms = self.filter_alarms(alarms, metric_name, namespace) + template = self.response_template(DESCRIBE_METRIC_ALARMS_TEMPLATE) + return template.render(alarms=filtered_alarms) @amzn_request_id def disable_alarm_actions(self): @@ -282,6 +296,57 @@ DESCRIBE_ALARMS_TEMPLATE = """ + + + {% for alarm in alarms %} + + {{ alarm.actions_enabled }} + + {% for action in alarm.alarm_actions %} + {{ action }} + {% endfor %} + + {{ alarm.arn }} + {{ alarm.configuration_updated_timestamp }} + {{ alarm.description }} + {{ alarm.name }} + {{ alarm.comparison_operator }} + + {% for dimension in alarm.dimensions %} + + {{ dimension.name }} + {{ dimension.value }} + + {% endfor %} + + {{ alarm.evaluation_periods }} + + {% for action in alarm.insufficient_data_actions %} + {{ action }} + {% endfor %} + + {{ alarm.metric_name }} + {{ alarm.namespace }} + + {% for action in alarm.ok_actions %} + {{ action }} + {% endfor %} + + {{ alarm.period }} + {{ alarm.state_reason }} + {{ alarm.state_reason_data }} + {{ alarm.state_updated_timestamp }} + {{ alarm.state_value }} + {{ alarm.statistic }} + {{ alarm.threshold }} + {{ alarm.unit }} + + {% endfor %} + + +""" + DELETE_METRIC_ALARMS_TEMPLATE = """ diff --git a/tests/test_cloudwatch/test_cloudwatch.py b/tests/test_cloudwatch/test_cloudwatch.py index 60b6898bd..b1f84ff4b 100644 --- a/tests/test_cloudwatch/test_cloudwatch.py +++ b/tests/test_cloudwatch/test_cloudwatch.py @@ -127,6 +127,22 @@ def test_describe_alarms(): alarms.should.have.length_of(0) +@mock_cloudwatch_deprecated +def test_describe_alarms_for_metric(): + conn = boto.connect_cloudwatch() + + conn.create_alarm(alarm_fixture(name="nfoobar", action="afoobar")) + conn.create_alarm(alarm_fixture(name="nfoobaz", action="afoobaz")) + conn.create_alarm(alarm_fixture(name="nbarfoo", action="abarfoo")) + conn.create_alarm(alarm_fixture(name="nbazfoo", action="abazfoo")) + + alarms = conn.describe_alarms_for_metric("nbarfoo_metric", "nbarfoo_namespace") + alarms.should.have.length_of(1) + + alarms = conn.describe_alarms_for_metric("nbazfoo_metric", "nbazfoo_namespace") + alarms.should.have.length_of(1) + + @mock_cloudwatch_deprecated def test_get_metric_statistics(): conn = boto.connect_cloudwatch() diff --git a/tests/test_cloudwatch/test_cloudwatch_boto3.py b/tests/test_cloudwatch/test_cloudwatch_boto3.py index 926c321ba..c38e2c77e 100644 --- a/tests/test_cloudwatch/test_cloudwatch_boto3.py +++ b/tests/test_cloudwatch/test_cloudwatch_boto3.py @@ -123,6 +123,24 @@ def test_delete_invalid_alarm(): e.exception.response["Error"]["Code"].should.equal("ResourceNotFound") +@mock_cloudwatch +def test_describe_alarms_for_metric(): + conn = boto3.client("cloudwatch", region_name="eu-central-1") + conn.put_metric_alarm( + AlarmName="testalarm1", + MetricName="cpu", + Namespace="blah", + Period=10, + EvaluationPeriods=5, + Statistic="Average", + Threshold=2, + ComparisonOperator="GreaterThanThreshold", + ActionsEnabled=True, + ) + alarms = conn.describe_alarms_for_metric(MetricName="cpu", Namespace="blah") + alarms.get("MetricAlarms").should.have.length_of(1) + + @mock_cloudwatch def test_alarm_state(): client = boto3.client("cloudwatch", region_name="eu-central-1")