Merge pull request #2859 from gmcrocetti/fix-rules-cfn
CloudFormation support for events
This commit is contained in:
commit
c87ab973c9
@ -431,7 +431,9 @@ class LogGroup(BaseModel):
|
||||
properties = cloudformation_json["Properties"]
|
||||
log_group_name = properties["LogGroupName"]
|
||||
tags = properties.get("Tags", {})
|
||||
return logs_backends[region_name].create_log_group(log_group_name, tags)
|
||||
return logs_backends[region_name].create_log_group(
|
||||
log_group_name, tags, **properties
|
||||
)
|
||||
|
||||
|
||||
cloudwatch_backends = {}
|
||||
|
@ -26,6 +26,10 @@ class Rule(BaseModel):
|
||||
self.role_arn = kwargs.get("RoleArn")
|
||||
self.targets = []
|
||||
|
||||
@property
|
||||
def physical_resource_id(self):
|
||||
return self.name
|
||||
|
||||
# This song and dance for targets is because we need order for Limits and NextTokens, but can't use OrderedDicts
|
||||
# with Python 2.6, so tracking it with an array it is.
|
||||
def _check_target_exists(self, target_id):
|
||||
@ -59,6 +63,14 @@ class Rule(BaseModel):
|
||||
if index is not None:
|
||||
self.targets.pop(index)
|
||||
|
||||
def get_cfn_attribute(self, attribute_name):
|
||||
from moto.cloudformation.exceptions import UnformattedGetAttTemplateException
|
||||
|
||||
if attribute_name == "Arn":
|
||||
return self.arn
|
||||
|
||||
raise UnformattedGetAttTemplateException()
|
||||
|
||||
@classmethod
|
||||
def create_from_cloudformation_json(
|
||||
cls, resource_name, cloudformation_json, region_name
|
||||
|
@ -134,7 +134,7 @@ class LogStream:
|
||||
return None, 0
|
||||
|
||||
events = sorted(
|
||||
filter(filter_func, self.events), key=lambda event: event.timestamp,
|
||||
filter(filter_func, self.events), key=lambda event: event.timestamp
|
||||
)
|
||||
|
||||
direction, index = get_index_and_direction_from_token(next_token)
|
||||
@ -169,11 +169,7 @@ class LogStream:
|
||||
if end_index > final_index:
|
||||
end_index = final_index
|
||||
elif end_index < 0:
|
||||
return (
|
||||
[],
|
||||
"b/{:056d}".format(0),
|
||||
"f/{:056d}".format(0),
|
||||
)
|
||||
return ([], "b/{:056d}".format(0), "f/{:056d}".format(0))
|
||||
|
||||
events_page = [
|
||||
event.to_response_dict() for event in events[start_index : end_index + 1]
|
||||
@ -219,7 +215,7 @@ class LogStream:
|
||||
|
||||
|
||||
class LogGroup:
|
||||
def __init__(self, region, name, tags):
|
||||
def __init__(self, region, name, tags, **kwargs):
|
||||
self.name = name
|
||||
self.region = region
|
||||
self.arn = "arn:aws:logs:{region}:1:log-group:{log_group}".format(
|
||||
@ -228,9 +224,9 @@ class LogGroup:
|
||||
self.creationTime = int(unix_time_millis())
|
||||
self.tags = tags
|
||||
self.streams = dict() # {name: LogStream}
|
||||
self.retentionInDays = (
|
||||
None # AWS defaults to Never Expire for log group retention
|
||||
)
|
||||
self.retention_in_days = kwargs.get(
|
||||
"RetentionInDays"
|
||||
) # AWS defaults to Never Expire for log group retention
|
||||
|
||||
def create_log_stream(self, log_stream_name):
|
||||
if log_stream_name in self.streams:
|
||||
@ -368,12 +364,12 @@ class LogGroup:
|
||||
"storedBytes": sum(s.storedBytes for s in self.streams.values()),
|
||||
}
|
||||
# AWS only returns retentionInDays if a value is set for the log group (ie. not Never Expire)
|
||||
if self.retentionInDays:
|
||||
log_group["retentionInDays"] = self.retentionInDays
|
||||
if self.retention_in_days:
|
||||
log_group["retentionInDays"] = self.retention_in_days
|
||||
return log_group
|
||||
|
||||
def set_retention_policy(self, retention_in_days):
|
||||
self.retentionInDays = retention_in_days
|
||||
self.retention_in_days = retention_in_days
|
||||
|
||||
def list_tags(self):
|
||||
return self.tags if self.tags else {}
|
||||
@ -401,10 +397,12 @@ class LogsBackend(BaseBackend):
|
||||
self.__dict__ = {}
|
||||
self.__init__(region_name)
|
||||
|
||||
def create_log_group(self, log_group_name, tags):
|
||||
def create_log_group(self, log_group_name, tags, **kwargs):
|
||||
if log_group_name in self.groups:
|
||||
raise ResourceAlreadyExistsException()
|
||||
self.groups[log_group_name] = LogGroup(self.region_name, log_group_name, tags)
|
||||
self.groups[log_group_name] = LogGroup(
|
||||
self.region_name, log_group_name, tags, **kwargs
|
||||
)
|
||||
return self.groups[log_group_name]
|
||||
|
||||
def ensure_log_group(self, log_group_name, tags):
|
||||
|
@ -2373,13 +2373,12 @@ def test_create_log_group_using_fntransform():
|
||||
}
|
||||
|
||||
cf_conn = boto3.client("cloudformation", "us-west-2")
|
||||
cf_conn.create_stack(
|
||||
StackName="test_stack", TemplateBody=json.dumps(template),
|
||||
)
|
||||
cf_conn.create_stack(StackName="test_stack", TemplateBody=json.dumps(template))
|
||||
|
||||
logs_conn = boto3.client("logs", region_name="us-west-2")
|
||||
log_group = logs_conn.describe_log_groups()["logGroups"][0]
|
||||
log_group["logGroupName"].should.equal("some-log-group")
|
||||
log_group["retentionInDays"].should.be.equal(90)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@ -2400,7 +2399,7 @@ def test_stack_events_create_rule_integration():
|
||||
}
|
||||
cf_conn = boto3.client("cloudformation", "us-west-2")
|
||||
cf_conn.create_stack(
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template),
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template)
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
@ -2428,7 +2427,7 @@ def test_stack_events_delete_rule_integration():
|
||||
}
|
||||
cf_conn = boto3.client("cloudformation", "us-west-2")
|
||||
cf_conn.create_stack(
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template),
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template)
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
@ -2457,8 +2456,45 @@ def test_stack_events_create_rule_without_name_integration():
|
||||
}
|
||||
cf_conn = boto3.client("cloudformation", "us-west-2")
|
||||
cf_conn.create_stack(
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template),
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template)
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
rules["Rules"][0]["Name"].should.contain("test_stack-Event-")
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@mock_events
|
||||
@mock_logs
|
||||
def test_stack_events_create_rule_as_target():
|
||||
events_template = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Resources": {
|
||||
"SecurityGroup": {
|
||||
"Type": "AWS::Logs::LogGroup",
|
||||
"Properties": {
|
||||
"LogGroupName": {"Fn::GetAtt": ["Event", "Arn"]},
|
||||
"RetentionInDays": 3,
|
||||
},
|
||||
},
|
||||
"Event": {
|
||||
"Type": "AWS::Events::Rule",
|
||||
"Properties": {
|
||||
"State": "ENABLED",
|
||||
"ScheduleExpression": "rate(5 minutes)",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
cf_conn = boto3.client("cloudformation", "us-west-2")
|
||||
cf_conn.create_stack(
|
||||
StackName="test_stack", TemplateBody=json.dumps(events_template)
|
||||
)
|
||||
|
||||
rules = boto3.client("events", "us-west-2").list_rules()
|
||||
log_groups = boto3.client("logs", "us-west-2").describe_log_groups()
|
||||
|
||||
rules["Rules"][0]["Name"].should.contain("test_stack-Event-")
|
||||
|
||||
log_groups["logGroups"][0]["logGroupName"].should.equal(rules["Rules"][0]["Arn"])
|
||||
log_groups["logGroups"][0]["retentionInDays"].should.equal(3)
|
||||
|
@ -79,13 +79,23 @@ def generate_environment():
|
||||
@mock_events
|
||||
def test_put_rule():
|
||||
client = boto3.client("events", "us-west-2")
|
||||
|
||||
client.list_rules()["Rules"].should.have.length_of(0)
|
||||
|
||||
rule_data = get_random_rule()
|
||||
rule_data = {
|
||||
"Name": "my-event",
|
||||
"ScheduleExpression": "rate(5 minutes)",
|
||||
"EventPattern": '{"source": ["test-source"]}',
|
||||
}
|
||||
|
||||
client.put_rule(**rule_data)
|
||||
|
||||
client.list_rules()["Rules"].should.have.length_of(1)
|
||||
rules = client.list_rules()["Rules"]
|
||||
|
||||
rules.should.have.length_of(1)
|
||||
rules[0]["Name"].should.equal(rule_data["Name"])
|
||||
rules[0]["ScheduleExpression"].should.equal(rule_data["ScheduleExpression"])
|
||||
rules[0]["EventPattern"].should.equal(rule_data["EventPattern"])
|
||||
rules[0]["State"].should.equal("ENABLED")
|
||||
|
||||
|
||||
@mock_events
|
||||
|
@ -12,17 +12,14 @@ _logs_region = "us-east-1" if settings.TEST_SERVER_MODE else "us-west-2"
|
||||
|
||||
|
||||
@mock_logs
|
||||
def test_log_group_create():
|
||||
def test_create_log_group():
|
||||
conn = boto3.client("logs", "us-west-2")
|
||||
log_group_name = "dummy"
|
||||
response = conn.create_log_group(logGroupName=log_group_name)
|
||||
|
||||
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
|
||||
assert len(response["logGroups"]) == 1
|
||||
# AWS defaults to Never Expire for log group retention
|
||||
assert response["logGroups"][0].get("retentionInDays") == None
|
||||
response = conn.create_log_group(logGroupName="dummy")
|
||||
response = conn.describe_log_groups()
|
||||
|
||||
response = conn.delete_log_group(logGroupName=log_group_name)
|
||||
response["logGroups"].should.have.length_of(1)
|
||||
response["logGroups"][0].should_not.have.key("retentionInDays")
|
||||
|
||||
|
||||
@mock_logs
|
||||
|
Loading…
Reference in New Issue
Block a user