Fix merge conflicts for cloudwatch.
This commit is contained in:
parent
2d65b0a020
commit
93f56322d8
@ -4,6 +4,7 @@ logging.getLogger('boto').setLevel(logging.CRITICAL)
|
|||||||
|
|
||||||
from .autoscaling import mock_autoscaling
|
from .autoscaling import mock_autoscaling
|
||||||
from .cloudformation import mock_cloudformation
|
from .cloudformation import mock_cloudformation
|
||||||
|
from .cloudwatch import mock_cloudwatch
|
||||||
from .dynamodb import mock_dynamodb
|
from .dynamodb import mock_dynamodb
|
||||||
from .dynamodb2 import mock_dynamodb2
|
from .dynamodb2 import mock_dynamodb2
|
||||||
from .ec2 import mock_ec2
|
from .ec2 import mock_ec2
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from moto.autoscaling import autoscaling_backend
|
from moto.autoscaling import autoscaling_backend
|
||||||
|
from moto.cloudwatch import cloudwatch_backend
|
||||||
from moto.dynamodb import dynamodb_backend
|
from moto.dynamodb import dynamodb_backend
|
||||||
from moto.dynamodb2 import dynamodb_backend2
|
from moto.dynamodb2 import dynamodb_backend2
|
||||||
from moto.ec2 import ec2_backend
|
from moto.ec2 import ec2_backend
|
||||||
@ -14,6 +15,7 @@ from moto.route53 import route53_backend
|
|||||||
|
|
||||||
BACKENDS = {
|
BACKENDS = {
|
||||||
'autoscaling': autoscaling_backend,
|
'autoscaling': autoscaling_backend,
|
||||||
|
'cloudwatch': cloudwatch_backend,
|
||||||
'dynamodb': dynamodb_backend,
|
'dynamodb': dynamodb_backend,
|
||||||
'dynamodb2': dynamodb_backend2,
|
'dynamodb2': dynamodb_backend2,
|
||||||
'ec2': ec2_backend,
|
'ec2': ec2_backend,
|
||||||
|
2
moto/cloudwatch/__init__.py
Normal file
2
moto/cloudwatch/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .models import cloudwatch_backend
|
||||||
|
mock_cloudwatch = cloudwatch_backend.decorator
|
50
moto/cloudwatch/models.py
Normal file
50
moto/cloudwatch/models.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from moto.core import BaseBackend
|
||||||
|
|
||||||
|
|
||||||
|
class Dimension(object):
|
||||||
|
def __init__(self, name, value):
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
|
||||||
|
class FakeAlarm(object):
|
||||||
|
def __init__(self, name, comparison_operator, evaluation_periods, period,
|
||||||
|
threshold, statistic, description, dimensions, alarm_actions,
|
||||||
|
ok_actions, insufficient_data_actions, unit):
|
||||||
|
self.name = name
|
||||||
|
self.comparison_operator = comparison_operator
|
||||||
|
self.evaluation_periods = evaluation_periods
|
||||||
|
self.period = period
|
||||||
|
self.threshold = threshold
|
||||||
|
self.statistic = statistic
|
||||||
|
self.description = description
|
||||||
|
self.dimensions = [Dimension(dimension['name'], dimension['value']) for dimension in dimensions]
|
||||||
|
self.alarm_actions = alarm_actions
|
||||||
|
self.ok_actions = ok_actions
|
||||||
|
self.insufficient_data_actions = insufficient_data_actions
|
||||||
|
self.unit = unit
|
||||||
|
|
||||||
|
|
||||||
|
class CloudWatchBackend(BaseBackend):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.alarms = {}
|
||||||
|
|
||||||
|
def put_metric_alarm(self, name, comparison_operator, evaluation_periods,
|
||||||
|
period, threshold, statistic, description, dimensions,
|
||||||
|
alarm_actions, ok_actions, insufficient_data_actions, unit):
|
||||||
|
alarm = FakeAlarm(name, comparison_operator, evaluation_periods, period,
|
||||||
|
threshold, statistic, description, dimensions, alarm_actions,
|
||||||
|
ok_actions, insufficient_data_actions, unit)
|
||||||
|
self.alarms[name] = alarm
|
||||||
|
return alarm
|
||||||
|
|
||||||
|
def get_all_alarms(self):
|
||||||
|
return self.alarms.values()
|
||||||
|
|
||||||
|
def delete_alarms(self, alarm_names):
|
||||||
|
for alarm_name in alarm_names:
|
||||||
|
self.alarms.pop(alarm_name, None)
|
||||||
|
|
||||||
|
|
||||||
|
cloudwatch_backend = CloudWatchBackend()
|
129
moto/cloudwatch/responses.py
Normal file
129
moto/cloudwatch/responses.py
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
from jinja2 import Template
|
||||||
|
|
||||||
|
from moto.core.responses import BaseResponse
|
||||||
|
from moto.core.utils import camelcase_to_underscores
|
||||||
|
from .models import cloudwatch_backend
|
||||||
|
|
||||||
|
|
||||||
|
class CloudWatchResponse(BaseResponse):
|
||||||
|
|
||||||
|
def _get_param(self, param_name):
|
||||||
|
return self.querystring.get(param_name, [None])[0]
|
||||||
|
|
||||||
|
def _get_multi_param(self, param_prefix):
|
||||||
|
return [value[0] for key, value in self.querystring.items() if key.startswith(param_prefix)]
|
||||||
|
|
||||||
|
def _get_list_prefix(self, param_prefix):
|
||||||
|
results = []
|
||||||
|
param_index = 1
|
||||||
|
while True:
|
||||||
|
index_prefix = "{}.{}.".format(param_prefix, param_index)
|
||||||
|
new_items = {
|
||||||
|
camelcase_to_underscores(key.replace(index_prefix, "")): value[0]
|
||||||
|
for key, value in self.querystring.items()
|
||||||
|
if key.startswith(index_prefix)
|
||||||
|
}
|
||||||
|
if not new_items:
|
||||||
|
break
|
||||||
|
results.append(new_items)
|
||||||
|
param_index += 1
|
||||||
|
return results
|
||||||
|
|
||||||
|
def put_metric_alarm(self):
|
||||||
|
name = self._get_param('AlarmName')
|
||||||
|
comparison_operator = self._get_param('ComparisonOperator')
|
||||||
|
evaluation_periods = self._get_param('EvaluationPeriods')
|
||||||
|
period = self._get_param('Period')
|
||||||
|
threshold = self._get_param('Threshold')
|
||||||
|
statistic = self._get_param('Statistic')
|
||||||
|
description = self._get_param('AlarmDescription')
|
||||||
|
dimensions = self._get_list_prefix('Dimensions.member')
|
||||||
|
alarm_actions = self._get_multi_param('AlarmActions')
|
||||||
|
ok_actions = self._get_multi_param('OKActions')
|
||||||
|
insufficient_data_actions = self._get_multi_param("InsufficientDataActions")
|
||||||
|
unit = self._get_param('Unit')
|
||||||
|
alarm = cloudwatch_backend.put_metric_alarm(name, comparison_operator,
|
||||||
|
evaluation_periods, period,
|
||||||
|
threshold, statistic,
|
||||||
|
description, dimensions,
|
||||||
|
alarm_actions, ok_actions,
|
||||||
|
insufficient_data_actions,
|
||||||
|
unit)
|
||||||
|
template = Template(PUT_METRIC_ALARM_TEMPLATE)
|
||||||
|
return template.render(alarm=alarm)
|
||||||
|
|
||||||
|
def describe_alarms(self):
|
||||||
|
alarms = cloudwatch_backend.get_all_alarms()
|
||||||
|
template = Template(DESCRIBE_ALARMS_TEMPLATE)
|
||||||
|
return template.render(alarms=alarms)
|
||||||
|
|
||||||
|
def delete_alarms(self):
|
||||||
|
alarm_names = self._get_multi_param('AlarmNames.member')
|
||||||
|
cloudwatch_backend.delete_alarms(alarm_names)
|
||||||
|
template = Template(DELETE_METRIC_ALARMS_TEMPLATE)
|
||||||
|
return template.render()
|
||||||
|
|
||||||
|
PUT_METRIC_ALARM_TEMPLATE = """<PutMetricAlarmResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>
|
||||||
|
2690d7eb-ed86-11dd-9877-6fad448a8419
|
||||||
|
</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</PutMetricAlarmResponse>"""
|
||||||
|
|
||||||
|
DESCRIBE_ALARMS_TEMPLATE = """<DescribeAlarmsResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
|
||||||
|
<MetricAlarms>
|
||||||
|
{% for alarm in alarms %}
|
||||||
|
<member>
|
||||||
|
<ActionsEnabled>{{ alarm.actions_enabled }}</ActionsEnabled>
|
||||||
|
<AlarmActions>
|
||||||
|
{% for action in alarm.alarm_actions %}
|
||||||
|
<member>{{ action }}</member>
|
||||||
|
{% endfor %}
|
||||||
|
</AlarmActions>
|
||||||
|
<AlarmArn>{{ alarm.arn }}</AlarmArn>
|
||||||
|
<AlarmConfigurationUpdatedTimestamp>{{ alarm.configuration_updated_timestamp }}</AlarmConfigurationUpdatedTimestamp>
|
||||||
|
<AlarmDescription>{{ alarm.description }}</AlarmDescription>
|
||||||
|
<AlarmName>{{ alarm.name }}</AlarmName>
|
||||||
|
<ComparisonOperator>{{ alarm.comparison_operator }}</ComparisonOperator>
|
||||||
|
<Dimensions>
|
||||||
|
{% for dimension in alarm.dimensions %}
|
||||||
|
<member>
|
||||||
|
<Name>{{ dimension.name }}</Name>
|
||||||
|
<Value>{{ dimension.value }}</Value>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Dimensions>
|
||||||
|
<EvaluationPeriods>{{ alarm.evaluation_periods }}</EvaluationPeriods>
|
||||||
|
<InsufficientDataActions>
|
||||||
|
{% for action in alarm.insufficient_data_actions %}
|
||||||
|
<member>{{ action }}</member>
|
||||||
|
{% endfor %}
|
||||||
|
</InsufficientDataActions>
|
||||||
|
<MetricName>{{ alarm.metric_name }}</MetricName>
|
||||||
|
<Namespace>{{ alarm.namespace }}</Namespace>
|
||||||
|
<OKActions>
|
||||||
|
{% for action in alarm.ok_actions %}
|
||||||
|
<member>{{ action }}</member>
|
||||||
|
{% endfor %}
|
||||||
|
</OKActions>
|
||||||
|
<Period>{{ alarm.period }}</Period>
|
||||||
|
<StateReason>{{ alarm.state_reason }}</StateReason>
|
||||||
|
<StateReasonData>{{ alarm.state_reason_data }}</StateReasonData>
|
||||||
|
<StateUpdatedTimestamp>{{ alarm.state_updated_timestamp }}</StateUpdatedTimestamp>
|
||||||
|
<StateValue>{{ alarm.state_value }}</StateValue>
|
||||||
|
<Statistic>{{ alarm.statistic }}</Statistic>
|
||||||
|
<Threshold>{{ alarm.threshold }}</Threshold>
|
||||||
|
<Unit>{{ alarm.unit }}</Unit>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</MetricAlarms>
|
||||||
|
</DescribeAlarmsResponse>"""
|
||||||
|
|
||||||
|
DELETE_METRIC_ALARMS_TEMPLATE = """<DeleteMetricAlarmResponse xmlns="http://monitoring.amazonaws.com/doc/2010-08-01/">
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>
|
||||||
|
2690d7eb-ed86-11dd-9877-6fad448a8419
|
||||||
|
</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</DeleteMetricAlarmResponse>"""
|
9
moto/cloudwatch/urls.py
Normal file
9
moto/cloudwatch/urls.py
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
from .responses import CloudWatchResponse
|
||||||
|
|
||||||
|
url_bases = [
|
||||||
|
"https?://monitoring.(.+).amazonaws.com",
|
||||||
|
]
|
||||||
|
|
||||||
|
url_paths = {
|
||||||
|
'{0}/$': CloudWatchResponse().dispatch,
|
||||||
|
}
|
71
tests/test_cloudwatch/test_cloudwatch.py
Normal file
71
tests/test_cloudwatch/test_cloudwatch.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
import boto
|
||||||
|
from boto.ec2.cloudwatch.alarm import MetricAlarm
|
||||||
|
import sure # noqa
|
||||||
|
|
||||||
|
from moto import mock_cloudwatch
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudwatch
|
||||||
|
def test_create_alarm():
|
||||||
|
conn = boto.connect_cloudwatch()
|
||||||
|
|
||||||
|
alarm = MetricAlarm(
|
||||||
|
name='tester',
|
||||||
|
comparison='>=',
|
||||||
|
threshold=2.0,
|
||||||
|
period=60,
|
||||||
|
evaluation_periods=5,
|
||||||
|
statistic='Average',
|
||||||
|
description='A test',
|
||||||
|
dimensions={'InstanceId': ['i-0123456,i-0123457']},
|
||||||
|
alarm_actions=['arn:alarm'],
|
||||||
|
ok_actions=['arn:ok'],
|
||||||
|
insufficient_data_actions=['arn:insufficient'],
|
||||||
|
unit='Seconds',
|
||||||
|
)
|
||||||
|
conn.create_alarm(alarm)
|
||||||
|
|
||||||
|
alarms = conn.describe_alarms()
|
||||||
|
alarms.should.have.length_of(1)
|
||||||
|
alarm = alarms[0]
|
||||||
|
alarm.name.should.equal('tester')
|
||||||
|
alarm.comparison.should.equal('>=')
|
||||||
|
alarm.threshold.should.equal(2.0)
|
||||||
|
alarm.period.should.equal(60)
|
||||||
|
alarm.evaluation_periods.should.equal(5)
|
||||||
|
alarm.statistic.should.equal('Average')
|
||||||
|
alarm.description.should.equal('A test')
|
||||||
|
dict(alarm.dimensions).should.equal({'InstanceId': ['i-0123456,i-0123457']})
|
||||||
|
list(alarm.alarm_actions).should.equal(['arn:alarm'])
|
||||||
|
list(alarm.ok_actions).should.equal(['arn:ok'])
|
||||||
|
list(alarm.insufficient_data_actions).should.equal(['arn:insufficient'])
|
||||||
|
alarm.unit.should.equal('Seconds')
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudwatch
|
||||||
|
def test_delete_alarm():
|
||||||
|
conn = boto.connect_cloudwatch()
|
||||||
|
|
||||||
|
alarm = MetricAlarm(
|
||||||
|
name='tester',
|
||||||
|
comparison='>=',
|
||||||
|
threshold=2.0,
|
||||||
|
period=60,
|
||||||
|
evaluation_periods=5,
|
||||||
|
statistic='Average',
|
||||||
|
description='A test',
|
||||||
|
dimensions={'InstanceId': ['i-0123456,i-0123457']},
|
||||||
|
alarm_actions=['arn:alarm'],
|
||||||
|
ok_actions=['arn:ok'],
|
||||||
|
insufficient_data_actions=['arn:insufficient'],
|
||||||
|
unit='Seconds',
|
||||||
|
)
|
||||||
|
conn.create_alarm(alarm)
|
||||||
|
|
||||||
|
alarms = conn.describe_alarms()
|
||||||
|
alarms.should.have.length_of(1)
|
||||||
|
|
||||||
|
alarms[0].delete()
|
||||||
|
|
||||||
|
alarms = conn.describe_alarms()
|
||||||
|
alarms.should.have.length_of(0)
|
Loading…
x
Reference in New Issue
Block a user