Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
}
)

failureFeedbackRoleValue = "LambdaFailureFeedbackRoleArn"
successFeedbackRoleValue = "LambdaSuccessFeedbackRoleArn"
successRateRoleValue = "LambdaSuccessFeedbackSampleRate"
endpointTypes = ['HTTP', 'Firehose', 'Lambda', 'Application', 'SQS']

def connect_to_sns():
return boto3.client('sns', config=boto_config)
Expand All @@ -39,9 +37,21 @@ def lambda_handler(event, _):
topic_attributes = get_topic_attributes(topic_arn)

return {
"FailureFeedbackRole": topic_attributes["Attributes"][failureFeedbackRoleValue],
"SuccessFeedbackRole": topic_attributes["Attributes"][successFeedbackRoleValue],
"SuccessSampleRate": topic_attributes["Attributes"][successRateRoleValue]
"HTTPFailureFeedbackRoleArn": topic_attributes["Attributes"]["HTTPFailureFeedbackRoleArn"],
"HTTPSuccessFeedbackRoleArn": topic_attributes["Attributes"]["HTTPSuccessFeedbackRoleArn"],
"HTTPSuccessFeedbackSampleRate": topic_attributes["Attributes"]["HTTPSuccessFeedbackSampleRate"],
"FirehoseFailureFeedbackRoleArn": topic_attributes["Attributes"]["FirehoseFailureFeedbackRoleArn"],
"FirehoseSuccessFeedbackRoleArn": topic_attributes["Attributes"]["FirehoseSuccessFeedbackRoleArn"],
"FirehoseSuccessFeedbackSampleRate": topic_attributes["Attributes"]["FirehoseSuccessFeedbackSampleRate"],
"LambdaFailureFeedbackRoleArn": topic_attributes["Attributes"]["LambdaFailureFeedbackRoleArn"],
"LambdaSuccessFeedbackRoleArn": topic_attributes["Attributes"]["LambdaSuccessFeedbackRoleArn"],
"LambdaSuccessFeedbackSampleRate": topic_attributes["Attributes"]["LambdaSuccessFeedbackSampleRate"],
"ApplicationFailureFeedbackRoleArn": topic_attributes["Attributes"]["ApplicationFailureFeedbackRoleArn"],
"ApplicationSuccessFeedbackRoleArn": topic_attributes["Attributes"]["ApplicationSuccessFeedbackRoleArn"],
"ApplicationSuccessFeedbackSampleRate": topic_attributes["Attributes"]["ApplicationSuccessFeedbackSampleRate"],
"SQSFailureFeedbackRoleArn": topic_attributes["Attributes"]["SQSFailureFeedbackRoleArn"],
"SQSSuccessFeedbackRoleArn": topic_attributes["Attributes"]["SQSSuccessFeedbackRoleArn"],
"SQSSuccessFeedbackSampleRate": topic_attributes["Attributes"]["SQSSuccessFeedbackSampleRate"]
}

def add_roles_to_topic(logging_role, topic_arn):
Expand All @@ -50,24 +60,26 @@ def add_roles_to_topic(logging_role, topic_arn):
"""
sns = connect_to_sns()
try:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=successFeedbackRoleValue, AttributeValue=logging_role)
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=failureFeedbackRoleValue, AttributeValue=logging_role)
for endpoint in endpointTypes:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}SuccessFeedbackRoleArn', AttributeValue=logging_role)
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}FailureFeedbackRoleArn', AttributeValue=logging_role)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with your choice of error handling here - the change is transactional as a whole, it either fully succeeds or we try to reset to the best of our ability


except Exception as e:
reset_to_recognized_state(topic_arn)
exit(f'Failed to set success/failure role of topic '+topic_arn+': '+str(e))
exit(f'Failed to set success/failure role of topic {topic_arn}: {str(e)}')

def add_sample_rate_to_topic(topic_arn, sample_rate):
"""
Configures the Success sample rate, the percentage of successful messages for which you want to receive CloudWatch Logs.
"""
sns = connect_to_sns()
try:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=successRateRoleValue, AttributeValue=sample_rate)
for endpoint in endpointTypes:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}SuccessFeedbackSampleRate', AttributeValue=sample_rate)

except Exception as e:
reset_to_recognized_state(topic_arn)
exit(f'Failed to set success sample rate of SNS topic '+topic_arn+': '+str(e))
exit(f'Failed to set success sample rate of SNS topic {topic_arn}: {str(e)}')

def get_topic_attributes(topic_arn):
"""
Expand All @@ -79,13 +91,16 @@ def get_topic_attributes(topic_arn):
return topic_attributes

except Exception as e:
exit(f'Failed to get attributes of SNS topic '+topic_arn+': '+str(e))
exit(f'Failed to get attributes of SNS topic {topic_arn}: {str(e)}')

def reset_to_recognized_state(topic_arn):
"""
Used in case of error, will unset all delivery status logging parameters.
"""
sns = connect_to_sns()

sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=successFeedbackRoleValue, AttributeValue='')
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=failureFeedbackRoleValue, AttributeValue='')
for endpoint in endpointTypes:
try:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}SuccessFeedbackRoleArn', AttributeValue='')
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}FailureFeedbackRoleArn', AttributeValue='')
except Exception:
print(f'There was an error while resetting SNS Topic {topic_arn}, please manually turn off delivery status logging for protocol {endpoint}')
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from enable_delivery_status_logging import lambda_handler

def test_enables_delivery_status_logging(mocker):
endpointTypes = ['HTTP', 'Firehose', 'Lambda', 'Application', 'SQS']

my_session = boto3.session.Session()
my_region = my_session.region_name
Expand All @@ -26,34 +27,47 @@ def test_enables_delivery_status_logging(mocker):
logging_arn = 'logging_arn'
topic_arn = f'arn:aws:sns:{my_region}:111111111111:sharr-test'

response = { 'Attributes' : {
stub_response = { 'Attributes' : {
"LambdaFailureFeedbackRoleArn": logging_arn,
"LambdaSuccessFeedbackRoleArn": logging_arn,
"LambdaSuccessFeedbackSampleRate": logging_arn
"LambdaSuccessFeedbackSampleRate": '0',
"HTTPFailureFeedbackRoleArn": logging_arn,
"HTTPSuccessFeedbackRoleArn": logging_arn,
"HTTPSuccessFeedbackSampleRate": '0',
"FirehoseFailureFeedbackRoleArn": logging_arn,
"FirehoseSuccessFeedbackRoleArn": logging_arn,
"FirehoseSuccessFeedbackSampleRate": '0',
"ApplicationFailureFeedbackRoleArn": logging_arn,
"ApplicationSuccessFeedbackRoleArn": logging_arn,
"ApplicationSuccessFeedbackSampleRate": '0',
"SQSFailureFeedbackRoleArn": logging_arn,
"SQSSuccessFeedbackRoleArn": logging_arn,
"SQSSuccessFeedbackSampleRate": '0'
}}
for endpoint in endpointTypes:
stub_sns.add_response(
'set_topic_attributes',
{},
{
'TopicArn': topic_arn ,
'AttributeName': f"{endpoint}SuccessFeedbackRoleArn",
'AttributeValue': logging_arn})

stub_sns.add_response(
'set_topic_attributes',
stub_sns.add_response('set_topic_attributes',
{},
{
'TopicArn': topic_arn ,
'AttributeName': "LambdaSuccessFeedbackRoleArn",
{ 'TopicArn': topic_arn ,
'AttributeName': f"{endpoint}FailureFeedbackRoleArn" ,
'AttributeValue': logging_arn})

stub_sns.add_response('set_topic_attributes',
{},
{ 'TopicArn': topic_arn ,
'AttributeName': "LambdaFailureFeedbackRoleArn" ,
'AttributeValue': logging_arn})

stub_sns.add_response('set_topic_attributes',
{},
{ 'TopicArn': topic_arn ,
'AttributeName': "LambdaSuccessFeedbackSampleRate" ,
'AttributeValue': '0'})

for endpoint in endpointTypes:
stub_sns.add_response('set_topic_attributes',
{},
{ 'TopicArn': topic_arn ,
'AttributeName': f"{endpoint}SuccessFeedbackSampleRate" ,
'AttributeValue': '0'})

stub_sns.add_response('get_topic_attributes',
response,
stub_response,
{ 'TopicArn': topic_arn })

stub_sns.activate()
Expand All @@ -62,8 +76,20 @@ def test_enables_delivery_status_logging(mocker):
event = { 'topic_arn': topic_arn, 'logging_role': logging_arn, 'sample_rate': '0' }
response = lambda_handler(event, {})
assert response == {
"FailureFeedbackRole": logging_arn,
"SuccessFeedbackRole": logging_arn,
"SuccessSampleRate": logging_arn }
"LambdaFailureFeedbackRoleArn": logging_arn,
"LambdaSuccessFeedbackRoleArn": logging_arn,
"LambdaSuccessFeedbackSampleRate": '0',
"HTTPFailureFeedbackRoleArn": logging_arn,
"HTTPSuccessFeedbackRoleArn": logging_arn,
"HTTPSuccessFeedbackSampleRate": '0',
"FirehoseFailureFeedbackRoleArn": logging_arn,
"FirehoseSuccessFeedbackRoleArn": logging_arn,
"FirehoseSuccessFeedbackSampleRate": '0',
"ApplicationFailureFeedbackRoleArn": logging_arn,
"ApplicationSuccessFeedbackRoleArn": logging_arn,
"ApplicationSuccessFeedbackSampleRate": '0',
"SQSFailureFeedbackRoleArn": logging_arn,
"SQSSuccessFeedbackRoleArn": logging_arn,
"SQSSuccessFeedbackSampleRate": '0' }


49 changes: 32 additions & 17 deletions source/test/__snapshots__/runbook_stack.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3872,9 +3872,7 @@ boto_config = Config(
}
)

failureFeedbackRoleValue = "LambdaFailureFeedbackRoleArn"
successFeedbackRoleValue = "LambdaSuccessFeedbackRoleArn"
successRateRoleValue = "LambdaSuccessFeedbackSampleRate"
endpointTypes = ['HTTP', 'Firehose', 'Lambda', 'Application', 'SQS']

def connect_to_sns():
return boto3.client('sns', config=boto_config)
Expand All @@ -3900,9 +3898,21 @@ def lambda_handler(event, _):
topic_attributes = get_topic_attributes(topic_arn)

return {
"FailureFeedbackRole": topic_attributes["Attributes"][failureFeedbackRoleValue],
"SuccessFeedbackRole": topic_attributes["Attributes"][successFeedbackRoleValue],
"SuccessSampleRate": topic_attributes["Attributes"][successRateRoleValue]
"HTTPFailureFeedbackRoleArn": topic_attributes["Attributes"]["HTTPFailureFeedbackRoleArn"],
"HTTPSuccessFeedbackRoleArn": topic_attributes["Attributes"]["HTTPSuccessFeedbackRoleArn"],
"HTTPSuccessFeedbackSampleRate": topic_attributes["Attributes"]["HTTPSuccessFeedbackSampleRate"],
"FirehoseFailureFeedbackRoleArn": topic_attributes["Attributes"]["FirehoseFailureFeedbackRoleArn"],
"FirehoseSuccessFeedbackRoleArn": topic_attributes["Attributes"]["FirehoseSuccessFeedbackRoleArn"],
"FirehoseSuccessFeedbackSampleRate": topic_attributes["Attributes"]["FirehoseSuccessFeedbackSampleRate"],
"LambdaFailureFeedbackRoleArn": topic_attributes["Attributes"]["LambdaFailureFeedbackRoleArn"],
"LambdaSuccessFeedbackRoleArn": topic_attributes["Attributes"]["LambdaSuccessFeedbackRoleArn"],
"LambdaSuccessFeedbackSampleRate": topic_attributes["Attributes"]["LambdaSuccessFeedbackSampleRate"],
"ApplicationFailureFeedbackRoleArn": topic_attributes["Attributes"]["ApplicationFailureFeedbackRoleArn"],
"ApplicationSuccessFeedbackRoleArn": topic_attributes["Attributes"]["ApplicationSuccessFeedbackRoleArn"],
"ApplicationSuccessFeedbackSampleRate": topic_attributes["Attributes"]["ApplicationSuccessFeedbackSampleRate"],
"SQSFailureFeedbackRoleArn": topic_attributes["Attributes"]["SQSFailureFeedbackRoleArn"],
"SQSSuccessFeedbackRoleArn": topic_attributes["Attributes"]["SQSSuccessFeedbackRoleArn"],
"SQSSuccessFeedbackSampleRate": topic_attributes["Attributes"]["SQSSuccessFeedbackSampleRate"]
}

def add_roles_to_topic(logging_role, topic_arn):
Expand All @@ -3911,24 +3921,26 @@ def add_roles_to_topic(logging_role, topic_arn):
"""
sns = connect_to_sns()
try:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=successFeedbackRoleValue, AttributeValue=logging_role)
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=failureFeedbackRoleValue, AttributeValue=logging_role)
for endpoint in endpointTypes:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}SuccessFeedbackRoleArn', AttributeValue=logging_role)
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}FailureFeedbackRoleArn', AttributeValue=logging_role)

except Exception as e:
reset_to_recognized_state(topic_arn)
exit(f'Failed to set success/failure role of topic '+topic_arn+': '+str(e))
exit(f'Failed to set success/failure role of topic {topic_arn}: {str(e)}')

def add_sample_rate_to_topic(topic_arn, sample_rate):
"""
Configures the Success sample rate, the percentage of successful messages for which you want to receive CloudWatch Logs.
"""
sns = connect_to_sns()
try:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=successRateRoleValue, AttributeValue=sample_rate)
for endpoint in endpointTypes:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}SuccessFeedbackSampleRate', AttributeValue=sample_rate)

except Exception as e:
reset_to_recognized_state(topic_arn)
exit(f'Failed to set success sample rate of SNS topic '+topic_arn+': '+str(e))
exit(f'Failed to set success sample rate of SNS topic {topic_arn}: {str(e)}')

def get_topic_attributes(topic_arn):
"""
Expand All @@ -3940,16 +3952,19 @@ def get_topic_attributes(topic_arn):
return topic_attributes

except Exception as e:
exit(f'Failed to get attributes of SNS topic '+topic_arn+': '+str(e))
exit(f'Failed to get attributes of SNS topic {topic_arn}: {str(e)}')

def reset_to_recognized_state(topic_arn):
"""
Used in case of error, will unset all delivery status logging parameters.
"""
sns = connect_to_sns()

sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=successFeedbackRoleValue, AttributeValue='')
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=failureFeedbackRoleValue, AttributeValue='')",
for endpoint in endpointTypes:
try:
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}SuccessFeedbackRoleArn', AttributeValue='')
sns.set_topic_attributes(TopicArn=topic_arn, AttributeName=f'{endpoint}FailureFeedbackRoleArn', AttributeValue='')
except Exception:
print(f'There was an error while resetting SNS Topic {topic_arn}, please manually turn off delivery status logging for protocol {endpoint}')",
},
"isEnd": true,
"name": "EnableDeliveryStatusLogging",
Expand Down Expand Up @@ -7737,7 +7752,7 @@ def add_ssl_bucket_policy(event, _):
"Properties": {
"CreateIntervalSeconds": 1,
"DeleteIntervalSeconds": 0,
"DocumentPropertiesHash": "76a143310018a965418e9379eb90670ea780456ea33047bd55f0b597443d59ba",
"DocumentPropertiesHash": "dff26ffe5bc8a2eb7a84297f591aa46181b17efa8b7c977636db9cf3beeec61c",
"ServiceToken": {
"Ref": "WaitProviderServiceToken",
},
Expand Down Expand Up @@ -7931,7 +7946,7 @@ def add_ssl_bucket_policy(event, _):
"Properties": {
"CreateIntervalSeconds": 0,
"DeleteIntervalSeconds": 0.5,
"DocumentPropertiesHash": "76a143310018a965418e9379eb90670ea780456ea33047bd55f0b597443d59ba",
"DocumentPropertiesHash": "dff26ffe5bc8a2eb7a84297f591aa46181b17efa8b7c977636db9cf3beeec61c",
"ServiceToken": {
"Ref": "WaitProviderServiceToken",
},
Expand Down